@webpieces/rules-config 0.4.554 → 0.4.555

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.554",
3
+ "version": "0.4.555",
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",
@@ -57,14 +57,22 @@ exports.defaultRules = {
57
57
  'validate-packagejson': { mode: 'RUN_EVERY_TIME' },
58
58
  'validate-versions-locked': { mode: 'RUN_EVERY_TIME' },
59
59
  'validate-eslint-sync': { mode: 'RUN_EVERY_TIME' },
60
- // autoReapMergedBranches ships FALSE. It is schema-required so every consumer must state a value,
61
- // and the framework default must be the conservative one: an upgrade should never start deleting
62
- // a project's branches unattended before a human has opted in. Set it true to let the background
63
- // refresher reap dead branches on its own; `pnpm wp-cleanup` works either way.
60
+ // autoReapMergedBranches ships TRUE, and it is also what a fresh config is seeded with.
61
+ //
62
+ // It shipped FALSE on the reasoning that an upgrade must never delete branches unattended before a
63
+ // human opts in. In practice that produced the opposite of safety: nobody opts in, dead branches
64
+ // pile up, and the pile is what makes a real branch hard to find. The reap is also NOT destructive
65
+ // in the way the old comment implied — BranchReaper deletes only provably-dead branches (a merged
66
+ // PR, a squash-merge backup of one, or no commits of their own), spares everything else for a
67
+ // human, and logs each deletion to .webpieces/hooks/branch-mutations.log with the pre-delete SHA
68
+ // and a ready-made `recover=` command. So the worst case is one paste to undo, which a human can
69
+ // resolve; the previous default's worst case was unbounded accumulation nobody ever cleaned.
70
+ //
71
+ // Set it false to keep reaping manual; `pnpm wp-cleanup` works either way.
64
72
  'branch-creation-guard': {
65
73
  mode: 'ON',
66
74
  subBranchNaming: 'feature/<ticket>/<short-description>',
67
- autoReapMergedBranches: false,
75
+ autoReapMergedBranches: true,
68
76
  },
69
77
  'pr-creation-or-push-guard': { mode: 'ON' },
70
78
  'merge-in-progress-guard': { mode: 'ON' },
@@ -1 +1 @@
1
- {"version":3,"file":"default-rules.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/default-rules.ts"],"names":[],"mappings":"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","sourcesContent":["// Default holistic exclude list for the validate-ts-in-src\n// rules. Bare names match a directory segment at any depth; globs match the\n// workspace-relative path. `**/*.d.ts` (ambient declarations) and\n// `**/jest.config.ts` legitimately live outside src/ and are exempt here.\nconst DEFAULT_EXCLUDE_PATHS: readonly string[] = [\n 'node_modules', 'dist', '.nx', '.git',\n '**/*.d.ts', '**/jest.config.ts',\n];\n\n// On/off is driven by `mode` (\"OFF\" disables; an absent mode leaves a rule\n// on). Code-rules entries omit `mode` so each executor keeps its own default\n// scope; structural rules declare `mode: 'RUN_EVERY_TIME'`, bash guards `mode: 'ON'`.\n// webpieces-disable no-any-unknown -- rule options are opaque at framework level\nexport const defaultRules: Record<string, Record<string, unknown>> = {\n 'no-any-unknown': {},\n 'no-implicit-any': {},\n 'max-file-lines': { limit: 900 },\n 'max-method-lines': { limit: 80 },\n 'require-return-type': {},\n 'no-inline-type-literals': {},\n 'no-destructure': { allowTopLevel: true },\n 'catch-error-pattern': {},\n 'no-unmanaged-exceptions': {},\n 'no-file-import-cycles': { mode: 'RUN_EVERY_TIME' },\n 'runtime-architecture': { mode: 'RUN_EVERY_TIME', allowedCycles: [] },\n 'prisma-validate-dtos': {},\n 'prisma-converter': {},\n 'angular-no-direct-api-in-resolver': {},\n 'no-symbol-di-tokens': {},\n // Ships OFF: a repo opts in per webpieces.config.json once it is ready to migrate any\n // client-in-a-lib sites (severity defaults to \"warn\" so even when enabled it reports without\n // failing until a repo flips it to \"error\").\n 'no-client-creation-outside-server-or-client': { mode: 'OFF' },\n 'no-custom-css': { allowGlobs: [] },\n 'no-process-exit-outside-main': {},\n 'inject-annotation-not-needed-for-concrete-class': {},\n 'framework-tag': { mode: 'MODIFIED_PROJECTS', knownTypes: ['browser', 'react', 'angular', 'node', 'express'] },\n 'role-tag': { mode: 'MODIFIED_PROJECTS', knownTypes: ['server', 'app', 'designed-lib', 'lib', 'client', 'api-lib'] },\n 'nx-wiring': { mode: 'RUN_EVERY_TIME' },\n 'di-graph': { mode: 'RUN_EVERY_TIME' },\n 'missing-design-annotation': { mode: 'RUN_EVERY_TIME' },\n 'validate-ts-in-src': {\n mode: 'NEW_AND_MODIFIED_FILES',\n allowedRootFiles: ['jest.setup.ts'],\n excludePaths: [...DEFAULT_EXCLUDE_PATHS],\n },\n 'no-js-files': { mode: 'OFF' },\n // The five Nx infrastructure validators. They enforced unconditionally before they were wired to\n // config, so RUN_EVERY_TIME is the only default that keeps existing repos behaving identically on\n // upgrade. Set \"mode\": \"OFF\" to disable one; the two graph-baseline rules\n // (validate-architecture-unchanged / validate-no-architecture-cycles) additionally honor\n // turnOffRuleUntilEpoch — the other three are all-or-nothing (see rule-configs.ts).\n 'validate-architecture-unchanged': { mode: 'RUN_EVERY_TIME' },\n 'validate-no-architecture-cycles': { mode: 'RUN_EVERY_TIME' },\n 'validate-packagejson': { mode: 'RUN_EVERY_TIME' },\n 'validate-versions-locked': { mode: 'RUN_EVERY_TIME' },\n 'validate-eslint-sync': { mode: 'RUN_EVERY_TIME' },\n // autoReapMergedBranches ships FALSE. It is schema-required so every consumer must state a value,\n // and the framework default must be the conservative one: an upgrade should never start deleting\n // a project's branches unattended before a human has opted in. Set it true to let the background\n // refresher reap dead branches on its own; `pnpm wp-cleanup` works either way.\n 'branch-creation-guard': {\n mode: 'ON',\n subBranchNaming: 'feature/<ticket>/<short-description>',\n autoReapMergedBranches: false,\n },\n 'pr-creation-or-push-guard': { mode: 'ON' },\n 'merge-in-progress-guard': { mode: 'ON' },\n 'pr-merge-guard': { mode: 'ON' },\n 'redirect-how-to-merge-main': { mode: 'ON' },\n // Phase 1 ships OFF on purpose. This guard blocks Read, the highest-blast-radius tool there is,\n // so it is opted into per-repo (webpieces.config.json → hookGuards) only AFTER the release\n // carrying it is published and installed. Flipping it ON here would arm it for every consumer\n // on upgrade, before anyone has verified the fail-open paths against their own git layout.\n 'read-stale-guard': { mode: 'OFF' },\n};\n\nexport const defaultRulesDir: readonly string[] = [];\n"]}
1
+ {"version":3,"file":"default-rules.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/default-rules.ts"],"names":[],"mappings":";;;AAAA,2DAA2D;AAC3D,4EAA4E;AAC5E,kEAAkE;AAClE,0EAA0E;AAC1E,MAAM,qBAAqB,GAAsB;IAC7C,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IACrC,WAAW,EAAE,mBAAmB;CACnC,CAAC;AAEF,2EAA2E;AAC3E,6EAA6E;AAC7E,sFAAsF;AACtF,iFAAiF;AACpE,QAAA,YAAY,GAA4C;IACjE,gBAAgB,EAAE,EAAE;IACpB,iBAAiB,EAAE,EAAE;IACrB,gBAAgB,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE;IAChC,kBAAkB,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;IACjC,qBAAqB,EAAE,EAAE;IACzB,yBAAyB,EAAE,EAAE;IAC7B,gBAAgB,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE;IACzC,qBAAqB,EAAE,EAAE;IACzB,yBAAyB,EAAE,EAAE;IAC7B,uBAAuB,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;IACnD,sBAAsB,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,aAAa,EAAE,EAAE,EAAE;IACrE,sBAAsB,EAAE,EAAE;IAC1B,kBAAkB,EAAE,EAAE;IACtB,mCAAmC,EAAE,EAAE;IACvC,qBAAqB,EAAE,EAAE;IACzB,sFAAsF;IACtF,6FAA6F;IAC7F,6CAA6C;IAC7C,6CAA6C,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;IAC9D,eAAe,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;IACnC,8BAA8B,EAAE,EAAE;IAClC,iDAAiD,EAAE,EAAE;IACrD,eAAe,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,UAAU,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE;IAC9G,UAAU,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,UAAU,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,EAAE;IACpH,WAAW,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;IACvC,UAAU,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;IACtC,2BAA2B,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;IACvD,oBAAoB,EAAE;QAClB,IAAI,EAAE,wBAAwB;QAC9B,gBAAgB,EAAE,CAAC,eAAe,CAAC;QACnC,YAAY,EAAE,CAAC,GAAG,qBAAqB,CAAC;KAC3C;IACD,aAAa,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;IAC9B,iGAAiG;IACjG,kGAAkG;IAClG,0EAA0E;IAC1E,yFAAyF;IACzF,oFAAoF;IACpF,iCAAiC,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;IAC7D,iCAAiC,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;IAC7D,sBAAsB,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;IAClD,0BAA0B,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;IACtD,sBAAsB,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;IAClD,wFAAwF;IACxF,EAAE;IACF,mGAAmG;IACnG,iGAAiG;IACjG,mGAAmG;IACnG,kGAAkG;IAClG,8FAA8F;IAC9F,iGAAiG;IACjG,iGAAiG;IACjG,6FAA6F;IAC7F,EAAE;IACF,2EAA2E;IAC3E,uBAAuB,EAAE;QACrB,IAAI,EAAE,IAAI;QACV,eAAe,EAAE,sCAAsC;QACvD,sBAAsB,EAAE,IAAI;KAC/B;IACD,2BAA2B,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IAC3C,yBAAyB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IACzC,gBAAgB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IAChC,4BAA4B,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IAC5C,gGAAgG;IAChG,2FAA2F;IAC3F,8FAA8F;IAC9F,2FAA2F;IAC3F,kBAAkB,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;CACtC,CAAC;AAEW,QAAA,eAAe,GAAsB,EAAE,CAAC","sourcesContent":["// Default holistic exclude list for the validate-ts-in-src\n// rules. Bare names match a directory segment at any depth; globs match the\n// workspace-relative path. `**/*.d.ts` (ambient declarations) and\n// `**/jest.config.ts` legitimately live outside src/ and are exempt here.\nconst DEFAULT_EXCLUDE_PATHS: readonly string[] = [\n 'node_modules', 'dist', '.nx', '.git',\n '**/*.d.ts', '**/jest.config.ts',\n];\n\n// On/off is driven by `mode` (\"OFF\" disables; an absent mode leaves a rule\n// on). Code-rules entries omit `mode` so each executor keeps its own default\n// scope; structural rules declare `mode: 'RUN_EVERY_TIME'`, bash guards `mode: 'ON'`.\n// webpieces-disable no-any-unknown -- rule options are opaque at framework level\nexport const defaultRules: Record<string, Record<string, unknown>> = {\n 'no-any-unknown': {},\n 'no-implicit-any': {},\n 'max-file-lines': { limit: 900 },\n 'max-method-lines': { limit: 80 },\n 'require-return-type': {},\n 'no-inline-type-literals': {},\n 'no-destructure': { allowTopLevel: true },\n 'catch-error-pattern': {},\n 'no-unmanaged-exceptions': {},\n 'no-file-import-cycles': { mode: 'RUN_EVERY_TIME' },\n 'runtime-architecture': { mode: 'RUN_EVERY_TIME', allowedCycles: [] },\n 'prisma-validate-dtos': {},\n 'prisma-converter': {},\n 'angular-no-direct-api-in-resolver': {},\n 'no-symbol-di-tokens': {},\n // Ships OFF: a repo opts in per webpieces.config.json once it is ready to migrate any\n // client-in-a-lib sites (severity defaults to \"warn\" so even when enabled it reports without\n // failing until a repo flips it to \"error\").\n 'no-client-creation-outside-server-or-client': { mode: 'OFF' },\n 'no-custom-css': { allowGlobs: [] },\n 'no-process-exit-outside-main': {},\n 'inject-annotation-not-needed-for-concrete-class': {},\n 'framework-tag': { mode: 'MODIFIED_PROJECTS', knownTypes: ['browser', 'react', 'angular', 'node', 'express'] },\n 'role-tag': { mode: 'MODIFIED_PROJECTS', knownTypes: ['server', 'app', 'designed-lib', 'lib', 'client', 'api-lib'] },\n 'nx-wiring': { mode: 'RUN_EVERY_TIME' },\n 'di-graph': { mode: 'RUN_EVERY_TIME' },\n 'missing-design-annotation': { mode: 'RUN_EVERY_TIME' },\n 'validate-ts-in-src': {\n mode: 'NEW_AND_MODIFIED_FILES',\n allowedRootFiles: ['jest.setup.ts'],\n excludePaths: [...DEFAULT_EXCLUDE_PATHS],\n },\n 'no-js-files': { mode: 'OFF' },\n // The five Nx infrastructure validators. They enforced unconditionally before they were wired to\n // config, so RUN_EVERY_TIME is the only default that keeps existing repos behaving identically on\n // upgrade. Set \"mode\": \"OFF\" to disable one; the two graph-baseline rules\n // (validate-architecture-unchanged / validate-no-architecture-cycles) additionally honor\n // turnOffRuleUntilEpoch — the other three are all-or-nothing (see rule-configs.ts).\n 'validate-architecture-unchanged': { mode: 'RUN_EVERY_TIME' },\n 'validate-no-architecture-cycles': { mode: 'RUN_EVERY_TIME' },\n 'validate-packagejson': { mode: 'RUN_EVERY_TIME' },\n 'validate-versions-locked': { mode: 'RUN_EVERY_TIME' },\n 'validate-eslint-sync': { mode: 'RUN_EVERY_TIME' },\n // autoReapMergedBranches ships TRUE, and it is also what a fresh config is seeded with.\n //\n // It shipped FALSE on the reasoning that an upgrade must never delete branches unattended before a\n // human opts in. In practice that produced the opposite of safety: nobody opts in, dead branches\n // pile up, and the pile is what makes a real branch hard to find. The reap is also NOT destructive\n // in the way the old comment implied BranchReaper deletes only provably-dead branches (a merged\n // PR, a squash-merge backup of one, or no commits of their own), spares everything else for a\n // human, and logs each deletion to .webpieces/hooks/branch-mutations.log with the pre-delete SHA\n // and a ready-made `recover=` command. So the worst case is one paste to undo, which a human can\n // resolve; the previous default's worst case was unbounded accumulation nobody ever cleaned.\n //\n // Set it false to keep reaping manual; `pnpm wp-cleanup` works either way.\n 'branch-creation-guard': {\n mode: 'ON',\n subBranchNaming: 'feature/<ticket>/<short-description>',\n autoReapMergedBranches: true,\n },\n 'pr-creation-or-push-guard': { mode: 'ON' },\n 'merge-in-progress-guard': { mode: 'ON' },\n 'pr-merge-guard': { mode: 'ON' },\n 'redirect-how-to-merge-main': { mode: 'ON' },\n // Phase 1 ships OFF on purpose. This guard blocks Read, the highest-blast-radius tool there is,\n // so it is opted into per-repo (webpieces.config.json → hookGuards) only AFTER the release\n // carrying it is published and installed. Flipping it ON here would arm it for every consumer\n // on upgrade, before anyone has verified the fail-open paths against their own git layout.\n 'read-stale-guard': { mode: 'OFF' },\n};\n\nexport const defaultRulesDir: readonly string[] = [];\n"]}
package/src/seed-entry.js CHANGED
@@ -50,7 +50,7 @@ function recommendedSeedMode(ruleName) {
50
50
  // 2. `mode` — the shared recommendation (see recommendedSeedMode);
51
51
  // 3. the framework's documented default for that rule (defaultRules) — the value the rule's own
52
52
  // config class commits to, e.g. max-file-lines.limit: 900, branch-creation-guard
53
- // .autoReapMergedBranches: false (deliberately conservative: never reap branches unattended);
53
+ // .autoReapMergedBranches: true (reaping is on by default — see default-rules.ts for why);
54
54
  // 4. a conservative fallback by type — null if the field accepts null, false for boolean, [] for
55
55
  // string[], the first enum value for an enum, '' / 0 otherwise. Reaching step 4 for a NEW field
56
56
  // means the rule forgot to give defaultRules an entry, which the seed-validates-clean spec in
@@ -1 +1 @@
1
- {"version":3,"file":"seed-entry.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/seed-entry.ts"],"names":[],"mappings":"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","sourcesContent":["// Seeding: what a rule's webpieces.config.json entry should look like when nothing has configured it\n// yet. Split out of validate-config.ts (700-line cap). This is the SINGLE source of truth shared by the\n// validator's copy-paste snippet (rolloutTip), the installer (ai-hook-rules setup.seedRule) and fault Y's\n// deny — so a seeded config can never contradict the advice printed beside it.\nimport { FieldDef } from './field-def';\nimport { RULE_SCHEMAS } from './rule-schemas';\nimport { defaultRules } from './default-rules';\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// The ONE place that decides what mode a rule should arrive as. Every consumer of that decision —\n// the validator's copy-paste snippet (rolloutTip in validate-config.ts), the installer's seeding, and the fault-`Y` deny in\n// ai-hook-rules — calls this, so a seeded config can never contradict the advice printed beside it.\n// Precedence: narrowest gradual mode the rule supports → ON → RUN_EVERY_TIME → OFF (a rule offering\n// none of those has nothing else it can be).\n// webpieces-disable no-function-outside-class -- sibling of the module-scope schema helpers in this file\nexport function recommendedSeedModeFor(modes: readonly string[]): string {\n const gradual = GRADUAL_MODE_PREFERENCE.find((m: string) => modes.includes(m));\n if (gradual) return gradual;\n if (modes.includes('ON')) return 'ON';\n if (modes.includes('RUN_EVERY_TIME')) return 'RUN_EVERY_TIME';\n return 'OFF';\n}\n\n/**\n * The mode a fresh/migrated `webpieces.config.json` entry for `ruleName` should be seeded with.\n * Unknown rule names (custom rules from `rulesDir`) fall back to 'OFF' — we have no schema to know\n * which modes they accept.\n */\n// webpieces-disable no-function-outside-class -- sibling of the module-scope schema helpers in this file\nexport function recommendedSeedMode(ruleName: string): string {\n const schema = RULE_SCHEMAS[ruleName];\n if (!schema) return 'OFF';\n return recommendedSeedModeFor(schema['mode']?.enumValues ?? []);\n}\n\n// The value a seeded entry gets for ONE required field. Order matters and is deliberate:\n// 1. the two universal escape hatches — always their \"active\" state (0 / null), never a placeholder;\n// 2. `mode` — the shared recommendation (see recommendedSeedMode);\n// 3. the framework's documented default for that rule (defaultRules) — the value the rule's own\n// config class commits to, e.g. max-file-lines.limit: 900, branch-creation-guard\n// .autoReapMergedBranches: false (deliberately conservative: never reap branches unattended);\n// 4. a conservative fallback by type — null if the field accepts null, false for boolean, [] for\n// string[], the first enum value for an enum, '' / 0 otherwise. Reaching step 4 for a NEW field\n// means the rule forgot to give defaultRules an entry, which the seed-validates-clean spec in\n// ai-hook-rules/src/bin/setup.spec.ts turns into a build failure if the fallback is not valid.\n// webpieces-disable no-any-unknown -- a config field value is opaque JSON by construction\n// webpieces-disable no-function-outside-class -- sibling of the module-scope schema helpers in this file\nfunction seedFieldValue(ruleName: string, key: string, def: FieldDef): unknown {\n if (key === 'turnOffRuleUntilEpoch') return 0;\n if (key === 'turnOffRuleWhileOnBranch') return null;\n if (key === 'mode') return recommendedSeedModeFor(def.enumValues ?? []);\n\n const documented = defaultRules[ruleName]?.[key];\n if (documented !== undefined) return documented;\n\n if (def.nullable) return null;\n if (def.type === 'boolean') return false;\n if (def.type === 'string[]') return [];\n if (def.enumValues && def.enumValues.length > 0) return def.enumValues[0];\n return def.type === 'number' ? 0 : '';\n}\n\n/**\n * The COMPLETE `webpieces.config.json` entry for `ruleName` — recommended mode, both escape hatches,\n * and a value for every other schema-REQUIRED field.\n *\n * Emitting only mode+hatches is what let `wp-install-ai-hooks` write a config the loader then\n * rejected (`[branch-creation-guard] Missing required field \"autoReapMergedBranches\"`), so the\n * installer and the validator read the SAME schema here. Unknown rule names (custom rules from\n * `rulesDir`) get the minimal entry — we have no schema to enumerate their required fields.\n */\n// webpieces-disable no-any-unknown -- a config entry is opaque JSON by construction\n// webpieces-disable no-function-outside-class -- sibling of the module-scope schema helpers in this file\nexport function seedEntryForRule(ruleName: string): Record<string, unknown> {\n const schema = RULE_SCHEMAS[ruleName];\n const entry: Record<string, unknown> = {\n mode: recommendedSeedMode(ruleName), turnOffRuleUntilEpoch: 0, turnOffRuleWhileOnBranch: null,\n };\n if (!schema) return entry;\n for (const key of Object.keys(schema)) {\n if (schema[key].optional) continue;\n entry[key] = seedFieldValue(ruleName, key, schema[key]);\n }\n return entry;\n}\n\n\n/** True when `mode` is one of the gradual (change-scoped) modes — used to decide whether to print the rollout prose. */\n// webpieces-disable no-function-outside-class -- sibling of the seeding helpers in this file\nexport function isGradualMode(mode: string): boolean {\n return GRADUAL_MODE_PREFERENCE.includes(mode);\n}\n"]}
1
+ {"version":3,"file":"seed-entry.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/seed-entry.ts"],"names":[],"mappings":"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","sourcesContent":["// Seeding: what a rule's webpieces.config.json entry should look like when nothing has configured it\n// yet. Split out of validate-config.ts (700-line cap). This is the SINGLE source of truth shared by the\n// validator's copy-paste snippet (rolloutTip), the installer (ai-hook-rules setup.seedRule) and fault Y's\n// deny — so a seeded config can never contradict the advice printed beside it.\nimport { FieldDef } from './field-def';\nimport { RULE_SCHEMAS } from './rule-schemas';\nimport { defaultRules } from './default-rules';\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// The ONE place that decides what mode a rule should arrive as. Every consumer of that decision —\n// the validator's copy-paste snippet (rolloutTip in validate-config.ts), the installer's seeding, and the fault-`Y` deny in\n// ai-hook-rules — calls this, so a seeded config can never contradict the advice printed beside it.\n// Precedence: narrowest gradual mode the rule supports → ON → RUN_EVERY_TIME → OFF (a rule offering\n// none of those has nothing else it can be).\n// webpieces-disable no-function-outside-class -- sibling of the module-scope schema helpers in this file\nexport function recommendedSeedModeFor(modes: readonly string[]): string {\n const gradual = GRADUAL_MODE_PREFERENCE.find((m: string) => modes.includes(m));\n if (gradual) return gradual;\n if (modes.includes('ON')) return 'ON';\n if (modes.includes('RUN_EVERY_TIME')) return 'RUN_EVERY_TIME';\n return 'OFF';\n}\n\n/**\n * The mode a fresh/migrated `webpieces.config.json` entry for `ruleName` should be seeded with.\n * Unknown rule names (custom rules from `rulesDir`) fall back to 'OFF' — we have no schema to know\n * which modes they accept.\n */\n// webpieces-disable no-function-outside-class -- sibling of the module-scope schema helpers in this file\nexport function recommendedSeedMode(ruleName: string): string {\n const schema = RULE_SCHEMAS[ruleName];\n if (!schema) return 'OFF';\n return recommendedSeedModeFor(schema['mode']?.enumValues ?? []);\n}\n\n// The value a seeded entry gets for ONE required field. Order matters and is deliberate:\n// 1. the two universal escape hatches — always their \"active\" state (0 / null), never a placeholder;\n// 2. `mode` — the shared recommendation (see recommendedSeedMode);\n// 3. the framework's documented default for that rule (defaultRules) — the value the rule's own\n// config class commits to, e.g. max-file-lines.limit: 900, branch-creation-guard\n// .autoReapMergedBranches: true (reaping is on by default — see default-rules.ts for why);\n// 4. a conservative fallback by type — null if the field accepts null, false for boolean, [] for\n// string[], the first enum value for an enum, '' / 0 otherwise. Reaching step 4 for a NEW field\n// means the rule forgot to give defaultRules an entry, which the seed-validates-clean spec in\n// ai-hook-rules/src/bin/setup.spec.ts turns into a build failure if the fallback is not valid.\n// webpieces-disable no-any-unknown -- a config field value is opaque JSON by construction\n// webpieces-disable no-function-outside-class -- sibling of the module-scope schema helpers in this file\nfunction seedFieldValue(ruleName: string, key: string, def: FieldDef): unknown {\n if (key === 'turnOffRuleUntilEpoch') return 0;\n if (key === 'turnOffRuleWhileOnBranch') return null;\n if (key === 'mode') return recommendedSeedModeFor(def.enumValues ?? []);\n\n const documented = defaultRules[ruleName]?.[key];\n if (documented !== undefined) return documented;\n\n if (def.nullable) return null;\n if (def.type === 'boolean') return false;\n if (def.type === 'string[]') return [];\n if (def.enumValues && def.enumValues.length > 0) return def.enumValues[0];\n return def.type === 'number' ? 0 : '';\n}\n\n/**\n * The COMPLETE `webpieces.config.json` entry for `ruleName` — recommended mode, both escape hatches,\n * and a value for every other schema-REQUIRED field.\n *\n * Emitting only mode+hatches is what let `wp-install-ai-hooks` write a config the loader then\n * rejected (`[branch-creation-guard] Missing required field \"autoReapMergedBranches\"`), so the\n * installer and the validator read the SAME schema here. Unknown rule names (custom rules from\n * `rulesDir`) get the minimal entry — we have no schema to enumerate their required fields.\n */\n// webpieces-disable no-any-unknown -- a config entry is opaque JSON by construction\n// webpieces-disable no-function-outside-class -- sibling of the module-scope schema helpers in this file\nexport function seedEntryForRule(ruleName: string): Record<string, unknown> {\n const schema = RULE_SCHEMAS[ruleName];\n const entry: Record<string, unknown> = {\n mode: recommendedSeedMode(ruleName), turnOffRuleUntilEpoch: 0, turnOffRuleWhileOnBranch: null,\n };\n if (!schema) return entry;\n for (const key of Object.keys(schema)) {\n if (schema[key].optional) continue;\n entry[key] = seedFieldValue(ruleName, key, schema[key]);\n }\n return entry;\n}\n\n\n/** True when `mode` is one of the gradual (change-scoped) modes — used to decide whether to print the rollout prose. */\n// webpieces-disable no-function-outside-class -- sibling of the seeding helpers in this file\nexport function isGradualMode(mode: string): boolean {\n return GRADUAL_MODE_PREFERENCE.includes(mode);\n}\n"]}