@webpieces/rules-config 0.4.481 → 0.4.483

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.
@@ -1 +1 @@
1
- {"version":3,"file":"checklist-manifest.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/checklist-manifest.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport { injectable, bindingScopeValues } from 'inversify';\nimport { ChecklistDefinition, RawChecklistItem, toChecklist } from './checklist-config';\nimport { toError } from './to-error';\n\n// The delimited JSON manifest embedded in the review doc. An HTML comment so it does NOT render in the\n// markdown a human reads, but is trivially + robustly parseable (JSON.parse — no YAML dependency, no\n// hand-rolled frontmatter parser). Example, at the top of `.claude/review/index.md`:\n//\n// <!-- webpieces:checklists\n// [ { \"subagent\": \"morpheus-envvars-reviewer\", \"doc\": \"morpheus-envvars.md\",\n// \"patterns\": [\"**/.env*\", \"**/Dockerfile*\"] } ]\n// -->\nconst MANIFEST_RE = /<!--\\s*webpieces:checklists\\s*([\\s\\S]*?)-->/;\n\n/**\n * Loads + validates the checklist manifest embedded in the single doc `pr-gate.checklists.doc` points at.\n * The set of checklists lives in the DOC (content), not webpieces.config.json (config) — the config only\n * carries the doc path. `@injectable(bindingScopeValues.Singleton)` so it is injected by type + drawn in\n * the DI design.\n */\n@injectable(bindingScopeValues.Singleton)\nexport class ChecklistManifestService {\n // Absolute path of the manifest doc under repoRoot.\n manifestDocPath(repoRoot: string, docRel: string): string {\n return path.join(repoRoot, docRel);\n }\n\n // The parsed checklists, or [] when the doc is missing / has no manifest block / is malformed. Callers\n // that need to REPORT those problems use validate(); this one is the tolerant runtime read.\n load(repoRoot: string, docRel: string): ChecklistDefinition[] {\n if (docRel.trim() === '') return [];\n const items = this.readItems(this.manifestDocPath(repoRoot, docRel));\n return items === null ? [] : items.map(toChecklist).filter((d: ChecklistDefinition): boolean => d.subagent !== '');\n }\n\n // Human-readable errors for the manifest doc, or [] when it is valid. Never throws.\n validate(repoRoot: string, docRel: string): string[] {\n if (docRel.trim() === '') return [];\n const docPath = this.manifestDocPath(repoRoot, docRel);\n if (!fs.existsSync(docPath)) {\n return [`[pr-gate] checklists.doc \"${docRel}\" does not exist — it must be a markdown doc carrying a <!-- webpieces:checklists [...] --> manifest.`];\n }\n const raw = this.extractManifest(fs.readFileSync(docPath, 'utf8'));\n if (raw === '') {\n return [`[pr-gate] \"${docRel}\" has no <!-- webpieces:checklists [...] --> block. Add a JSON array of { subagent, doc?, patterns? } inside that HTML comment.`];\n }\n const parsed = this.parse(raw);\n if (parsed === null) {\n return [`[pr-gate] the <!-- webpieces:checklists --> block in \"${docRel}\" is not a valid JSON array.`];\n }\n return this.validateItems(parsed, repoRoot, docRel);\n }\n\n private validateItems(items: readonly RawChecklistItem[], repoRoot: string, docRel: string): string[] {\n const errors: string[] = [];\n const seen = new Set<string>();\n const docDir = path.dirname(this.manifestDocPath(repoRoot, docRel));\n items.forEach((item: RawChecklistItem, i: number): void => {\n const label = typeof item.subagent === 'string' && item.subagent !== '' ? `\"${item.subagent}\"` : `checklists[${i}]`;\n if (typeof item.subagent !== 'string' || item.subagent.trim() === '') {\n errors.push(`[pr-gate] ${docRel} checklists[${i}].subagent must be a non-empty string (the reviewer agent name, matching .claude/agents/<subagent>.md).`);\n } else if (seen.has(item.subagent)) {\n errors.push(`[pr-gate] ${docRel} duplicate subagent \"${item.subagent}\" — each checklist must use a DISTINCT reviewer subagent (that is how independent review is enforced).`);\n } else {\n seen.add(item.subagent);\n }\n if (item.doc !== undefined && item.doc !== '' && !fs.existsSync(path.join(docDir, item.doc))) {\n errors.push(`[pr-gate] ${docRel} ${label}.doc \"${item.doc}\" does not exist (resolved relative to the manifest doc).`);\n }\n if (item.patterns !== undefined && !this.isStringArray(item.patterns)) {\n errors.push(`[pr-gate] ${docRel} ${label}.patterns must be a string[] of path globs (omit or [] to run on every PR).`);\n }\n });\n return errors;\n }\n\n // Read the manifest doc and return its parsed items, or null on any problem (missing/no block/bad JSON).\n private readItems(docPath: string): RawChecklistItem[] | null {\n if (!fs.existsSync(docPath)) return null;\n const raw = this.extractManifest(fs.readFileSync(docPath, 'utf8'));\n if (raw === '') return null;\n return this.parse(raw);\n }\n\n private extractManifest(content: string): string {\n const m = MANIFEST_RE.exec(content);\n return m ? m[1].trim() : '';\n }\n\n // webpieces-disable no-any-unknown -- opaque parsed JSON, narrowed to an item array by the caller\n private parse(json: string): RawChecklistItem[] | null {\n // webpieces-disable no-unmanaged-exceptions -- chokepoint: a malformed manifest is reported as one error / ignored\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n // webpieces-disable no-any-unknown -- parsed JSON is opaque until narrowed below\n const value = JSON.parse(json) as unknown;\n if (!Array.isArray(value)) return null;\n // webpieces-disable no-any-unknown -- each opaque entry is narrowed field-by-field downstream\n return value as RawChecklistItem[];\n } catch (err: unknown) {\n const error = toError(err);\n void error;\n return null;\n }\n }\n\n // webpieces-disable no-any-unknown -- opaque parsed JSON value, narrowed to string[] here\n private isStringArray(value: unknown): boolean {\n return Array.isArray(value) && value.every((v: unknown): boolean => typeof v === 'string');\n }\n}\n"]}
1
+ {"version":3,"file":"checklist-manifest.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/checklist-manifest.ts"],"names":[],"mappings":";;;;AAAA,+CAAyB;AACzB,mDAA6B;AAC7B,yCAA2D;AAC3D,yDAAyG;AACzG,yCAAqC;AAErC,wGAAwG;AACxG,mGAAmG;AACnG,2GAA2G;AAC3G,oCAAoC;AACpC,EAAE;AACF,8BAA8B;AAC9B,+EAA+E;AAC/E,uDAAuD;AACvD,QAAQ;AACR,EAAE;AACF,0GAA0G;AAC1G,2GAA2G;AAC3G,uDAAuD;AACvD,MAAM,WAAW,GAAG,6CAA6C,CAAC;AAElE,2FAA2F;AAC3F,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAElD;;;;;;GAMG;AAEI,IAAM,wBAAwB,GAA9B,MAAM,wBAAwB;IACjC,oDAAoD;IACpD,eAAe,CAAC,QAAgB,EAAE,MAAc;QAC5C,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;IAED;;;OAGG;IACH,IAAI,CAAC,QAAgB,EAAE,MAAuB;QAC1C,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAChE,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,OAAO,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACzE,IAAI,KAAK,KAAK,IAAI;YAAE,OAAO,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAqB,EAAuB,EAAE,CAAC,IAAA,8BAAW,EAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACpI,CAAC;IAED,yFAAyF;IACzF,QAAQ,CAAC,QAAgB,EAAE,MAAuB;QAC9C,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QACvG,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,OAAO,EAAE,CAAC;QACxC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC;QAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACvD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,6BAA6B,MAAM,uGAAuG,CAAC,CAAC;QACxJ,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;QACnE,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;YACb,OAAO,CAAC,cAAc,MAAM,iIAAiI,CAAC,CAAC;QACnK,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YAClB,OAAO,CAAC,yDAAyD,MAAM,8BAA8B,CAAC,CAAC;QAC3G,CAAC;QACD,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IACxD,CAAC;IAED,kGAAkG;IAClG,+FAA+F;IACvF,aAAa,CAAC,KAAkC,EAAE,QAAgB,EAAE,MAAc;QACtF,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC3C,KAAK,CAAC,OAAO,CAAC,CAAC,IAAsB,EAAE,CAAS,EAAQ,EAAE;YACtD,MAAM,KAAK,GAAG,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,IAAI,IAAI,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC;YACpH,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACpE,MAAM,CAAC,IAAI,CAAC,aAAa,MAAM,IAAI,KAAK,6EAA6E,CAAC,CAAC;YAC3H,CAAC;QACL,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAsB,EAAuB,EAAE,CAAC,IAAA,8BAAW,EAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QACpG,OAAO,CAAC,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;IACzE,CAAC;IAED;;;OAGG;IACK,gBAAgB,CAAC,IAAoC,EAAE,QAAgB,EAAE,WAAmB;QAChG,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,qGAAqG;QACrG,kGAAkG;QAClG,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAClD,MAAM,WAAW,GAAG,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO,CAAC,CAAC,GAAwB,EAAE,CAAS,EAAQ,EAAE;YACvD,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC;YAC7E,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBAC7B,MAAM,CAAC,IAAI,CAAC,aAAa,WAAW,eAAe,CAAC,yGAAyG,CAAC,CAAC;YACnK,CAAC;iBAAM,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAChC,MAAM,CAAC,IAAI,CAAC,aAAa,WAAW,wBAAwB,GAAG,CAAC,QAAQ,wGAAwG,CAAC,CAAC;YACtL,CAAC;iBAAM,CAAC;gBACJ,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;gBACvB,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;YAC1G,CAAC;YACD,IAAI,GAAG,CAAC,GAAG,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;gBACjE,MAAM,CAAC,IAAI,CAAC,aAAa,WAAW,IAAI,KAAK,SAAS,GAAG,CAAC,GAAG,4CAA4C,CAAC,CAAC;YAC/G,CAAC;QACL,CAAC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAClB,CAAC;IAED;;;;;;OAMG;IACH,yDAAyD;IACjD,sBAAsB,CAAC,QAAgB,EAAE,KAAa,EAAE,WAAoB,EAAE,SAAiB,EAAE,WAAmB;QACxH,IAAI,CAAC,WAAW;YAAE,OAAO,EAAE,CAAC;QAC5B,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,QAAQ,KAAK,CAAC,CAAC;YAAE,OAAO,EAAE,CAAC;QACrE,OAAO;YACH,aAAa,WAAW,IAAI,KAAK,iCAAiC,UAAU,IAAI,QAAQ,sBAAsB;gBAC9G,mFAAmF,QAAQ,oCAAoC;gBAC/H,yCAAyC;SAC5C,CAAC;IACN,CAAC;IAED,kGAAkG;IAClG,+EAA+E;IACvE,MAAM,CAAC,IAAoC;QAC/C,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAsB,EAAW,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED,yGAAyG;IACjG,SAAS,CAAC,OAAe;QAC7B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;QACzC,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;QACnE,IAAI,GAAG,KAAK,EAAE;YAAE,OAAO,IAAI,CAAC;QAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAEO,eAAe,CAAC,OAAe;QACnC,MAAM,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAChC,CAAC;IAED,kGAAkG;IAC1F,KAAK,CAAC,IAAY;QACtB,mHAAmH;QACnH,8DAA8D;QAC9D,IAAI,CAAC;YACD,iFAAiF;YACjF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;YAC1C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAC;YACvC,8FAA8F;YAC9F,OAAO,KAA2B,CAAC;QACvC,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACpB,MAAM,KAAK,GAAG,IAAA,kBAAO,EAAC,GAAG,CAAC,CAAC;YAC3B,KAAK,KAAK,CAAC;YACX,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IAED,0FAA0F;IAClF,aAAa,CAAC,KAAc;QAChC,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAU,EAAW,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC;IAC/F,CAAC;CACJ,CAAA;AA3IY,4DAAwB;mCAAxB,wBAAwB;IADpC,IAAA,sBAAU,EAAC,8BAAkB,CAAC,SAAS,CAAC;GAC5B,wBAAwB,CA2IpC","sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport { injectable, bindingScopeValues } from 'inversify';\nimport { ChecklistDefinition, ChecklistSource, RawChecklistItem, toChecklist } from './checklist-config';\nimport { toError } from './to-error';\n\n// The delimited JSON manifest embedded in the review doc — the LEGACY shape, kept working because it is\n// shipped. An HTML comment so it does NOT render in the markdown a human reads, but is trivially +\n// robustly parseable (JSON.parse — no YAML dependency, no hand-rolled frontmatter parser). Example, at the\n// top of `.claude/review/index.md`:\n//\n// <!-- webpieces:checklists\n// [ { \"subagent\": \"morpheus-envvars-reviewer\", \"doc\": \"morpheus-envvars.md\",\n// \"patterns\": [\"**/.env*\", \"**/Dockerfile*\"] } ]\n// -->\n//\n// New repos should put the SAME array directly in `pr-gate.checklists` in webpieces.config.json instead —\n// see ChecklistSource. A JSON array inside an HTML comment is reachable only by this regex: no JSON Schema\n// covers it, no editor completes it, no `jq` reads it.\nconst MANIFEST_RE = /<!--\\s*webpieces:checklists\\s*([\\s\\S]*?)-->/;\n\n// Where a reviewer subagent's definition must live for Claude Code to be able to spawn it.\nconst AGENTS_DIR = path.join('.claude', 'agents');\n\n/**\n * Loads + validates a repo's review checklists from EITHER shape (see {@link ChecklistSource}): the\n * `pr-gate.checklists` array in webpieces.config.json (primary) or the `<!-- webpieces:checklists -->`\n * manifest embedded in the doc that `pr-gate.checklists.doc` points at (legacy).\n *\n * `@injectable(bindingScopeValues.Singleton)` so it is injected by type + drawn in the DI design.\n */\n@injectable(bindingScopeValues.Singleton)\nexport class ChecklistManifestService {\n // Absolute path of the manifest doc under repoRoot.\n manifestDocPath(repoRoot: string, docRel: string): string {\n return path.join(repoRoot, docRel);\n }\n\n /**\n * The repo's checklists, or [] when there are none / the manifest doc is missing / malformed. Callers\n * that need to REPORT those problems use validate(); this one is the tolerant runtime read.\n */\n load(repoRoot: string, source: ChecklistSource): ChecklistDefinition[] {\n if (source.inline.length > 0) return this.usable(source.inline);\n if (source.doc.trim() === '') return [];\n const items = this.readItems(this.manifestDocPath(repoRoot, source.doc));\n if (items === null) return [];\n return this.usable(items.map((raw: RawChecklistItem): ChecklistDefinition => toChecklist(raw, path.posix.dirname(source.doc))));\n }\n\n // Human-readable errors for the repo's checklist config, or [] when valid. Never throws.\n validate(repoRoot: string, source: ChecklistSource): string[] {\n if (source.inline.length > 0) return this.validateResolved(source.inline, repoRoot, source.describe());\n if (source.doc.trim() === '') return [];\n const docRel = source.doc;\n const docPath = this.manifestDocPath(repoRoot, docRel);\n if (!fs.existsSync(docPath)) {\n return [`[pr-gate] checklists.doc \"${docRel}\" does not exist — it must be a markdown doc carrying a <!-- webpieces:checklists [...] --> manifest.`];\n }\n const raw = this.extractManifest(fs.readFileSync(docPath, 'utf8'));\n if (raw === '') {\n return [`[pr-gate] \"${docRel}\" has no <!-- webpieces:checklists [...] --> block. Add a JSON array of { subagent, doc?, patterns? } inside that HTML comment.`];\n }\n const parsed = this.parse(raw);\n if (parsed === null) {\n return [`[pr-gate] the <!-- webpieces:checklists --> block in \"${docRel}\" is not a valid JSON array.`];\n }\n return this.validateItems(parsed, repoRoot, docRel);\n }\n\n // Validate raw manifest entries (legacy shape): narrow each to a ChecklistDefinition with its doc\n // resolved against the manifest doc's directory, then run the SAME checks the array form gets.\n private validateItems(items: readonly RawChecklistItem[], repoRoot: string, docRel: string): string[] {\n const errors: string[] = [];\n const docBase = path.posix.dirname(docRel);\n items.forEach((item: RawChecklistItem, i: number): void => {\n const label = typeof item.subagent === 'string' && item.subagent !== '' ? `\"${item.subagent}\"` : `checklists[${i}]`;\n if (item.patterns !== undefined && !this.isStringArray(item.patterns)) {\n errors.push(`[pr-gate] ${docRel} ${label}.patterns must be a string[] of path globs (omit or [] to run on every PR).`);\n }\n });\n const defs = items.map((item: RawChecklistItem): ChecklistDefinition => toChecklist(item, docBase));\n return [...errors, ...this.validateResolved(defs, repoRoot, docRel)];\n }\n\n /**\n * The checks that are the SAME for both config shapes, run against already-narrowed definitions:\n * subagent present + distinct + actually resolves to a spawnable agent, and the guidance doc exists.\n */\n private validateResolved(defs: readonly ChecklistDefinition[], repoRoot: string, sourceLabel: string): string[] {\n const errors: string[] = [];\n const seen = new Set<string>();\n // Only enforce the reviewer-agent file when this repo HAS an agents dir — a non-Claude-Code consumer\n // that drives the gate some other way must not be broken by a check for a directory it never has.\n const agentsDir = path.join(repoRoot, AGENTS_DIR);\n const checkAgents = fs.existsSync(agentsDir);\n defs.forEach((def: ChecklistDefinition, i: number): void => {\n const label = def.subagent !== '' ? `\"${def.subagent}\"` : `checklists[${i}]`;\n if (def.subagent.trim() === '') {\n errors.push(`[pr-gate] ${sourceLabel} checklists[${i}].subagent must be a non-empty string (the reviewer agent name, matching .claude/agents/<subagent>.md).`);\n } else if (seen.has(def.subagent)) {\n errors.push(`[pr-gate] ${sourceLabel} duplicate subagent \"${def.subagent}\" — each checklist must use a DISTINCT reviewer subagent (that is how independent review is enforced).`);\n } else {\n seen.add(def.subagent);\n errors.push(...this.validateSubagentExists(def.subagent, label, checkAgents, agentsDir, sourceLabel));\n }\n if (def.doc !== '' && !fs.existsSync(path.join(repoRoot, def.doc))) {\n errors.push(`[pr-gate] ${sourceLabel} ${label}.doc \"${def.doc}\" does not exist (resolved repo-relative).`);\n }\n });\n return errors;\n }\n\n /**\n * The check this validator was missing: `subagent` is the ONE required field and the whole\n * distinct-reviewer guarantee rests on it, yet nothing confirmed it names a real agent. A typo used to\n * validate clean, then get printed to the coding agent as \"spawn this\" — and since wp-finish blocks on\n * `review-<that-typo>.json`, the path of least resistance became writing the reviewer's verdict itself,\n * which is the exact self-certification the distinct-subagent rule exists to prevent. Reject at load.\n */\n // eslint-disable-next-line @typescript-eslint/max-params\n private validateSubagentExists(subagent: string, label: string, checkAgents: boolean, agentsDir: string, sourceLabel: string): string[] {\n if (!checkAgents) return [];\n if (fs.existsSync(path.join(agentsDir, `${subagent}.md`))) return [];\n return [\n `[pr-gate] ${sourceLabel} ${label}.subagent names no reviewer — ${AGENTS_DIR}/${subagent}.md does not exist, ` +\n `so nothing can spawn it and wp-finish-upsert-pr would block forever on a review-${subagent}.json that no reviewer can write. ` +\n `Create that agent file or fix the name.`,\n ];\n }\n\n // Drop entries with no subagent — they have no id, so they can key neither review-<id>.json nor a\n // dashboard row. validate() reports them; the tolerant load() just skips them.\n private usable(defs: readonly ChecklistDefinition[]): ChecklistDefinition[] {\n return defs.filter((d: ChecklistDefinition): boolean => d.subagent !== '');\n }\n\n // Read the manifest doc and return its parsed items, or null on any problem (missing/no block/bad JSON).\n private readItems(docPath: string): RawChecklistItem[] | null {\n if (!fs.existsSync(docPath)) return null;\n const raw = this.extractManifest(fs.readFileSync(docPath, 'utf8'));\n if (raw === '') return null;\n return this.parse(raw);\n }\n\n private extractManifest(content: string): string {\n const m = MANIFEST_RE.exec(content);\n return m ? m[1].trim() : '';\n }\n\n // webpieces-disable no-any-unknown -- opaque parsed JSON, narrowed to an item array by the caller\n private parse(json: string): RawChecklistItem[] | null {\n // webpieces-disable no-unmanaged-exceptions -- chokepoint: a malformed manifest is reported as one error / ignored\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n // webpieces-disable no-any-unknown -- parsed JSON is opaque until narrowed below\n const value = JSON.parse(json) as unknown;\n if (!Array.isArray(value)) return null;\n // webpieces-disable no-any-unknown -- each opaque entry is narrowed field-by-field downstream\n return value as RawChecklistItem[];\n } catch (err: unknown) {\n const error = toError(err);\n void error;\n return null;\n }\n }\n\n // webpieces-disable no-any-unknown -- opaque parsed JSON value, narrowed to string[] here\n private isStringArray(value: unknown): boolean {\n return Array.isArray(value) && value.every((v: unknown): boolean => typeof v === 'string');\n }\n}\n"]}
@@ -12,5 +12,8 @@ export declare class CommandsConfig {
12
12
  * field the consumer omits. `legacyPrGate` is the top-level `pr-gate` block (pre-migration layout);
13
13
  * it is used only as a fallback so an un-migrated file still loads its gate config. Pure transform —
14
14
  * the structural validation happens in loadAndValidate.
15
+ *
16
+ * Command-string precedence per field: commands.guardHints.<name> (canonical) → the legacy flat
17
+ * commands.<upsertPr|mergeComplete> → the built-in default. So a half-migrated file still resolves.
15
18
  */
16
19
  export declare function buildCommandsConfig(section: unknown, legacyPrGate?: unknown): CommandsConfig;
@@ -16,8 +16,10 @@ exports.DEFAULT_MERGE_COMPLETE_COMMAND = 'pnpm wp-finish-upsert-pr';
16
16
  class CommandsConfig {
17
17
  prGate;
18
18
  // Command the pr-creation-or-push-guard tells agents to run instead of `gh pr create` or a manual push.
19
+ // Sourced from commands.guardHints.prCreationOrPush (canonical) or the legacy flat commands.upsertPr.
19
20
  upsertPr;
20
21
  // Command the merge-in-progress-guard tells agents to run to finish a 3-point merge.
22
+ // Sourced from commands.guardHints.mergeInProgress (canonical) or the legacy flat commands.mergeComplete.
21
23
  mergeComplete;
22
24
  constructor(prGate, upsertPr, mergeComplete) {
23
25
  this.prGate = prGate;
@@ -31,6 +33,9 @@ exports.CommandsConfig = CommandsConfig;
31
33
  * field the consumer omits. `legacyPrGate` is the top-level `pr-gate` block (pre-migration layout);
32
34
  * it is used only as a fallback so an un-migrated file still loads its gate config. Pure transform —
33
35
  * the structural validation happens in loadAndValidate.
36
+ *
37
+ * Command-string precedence per field: commands.guardHints.<name> (canonical) → the legacy flat
38
+ * commands.<upsertPr|mergeComplete> → the built-in default. So a half-migrated file still resolves.
34
39
  */
35
40
  // webpieces-disable no-any-unknown -- `section` is opaque consumer JSON until narrowed here
36
41
  function buildCommandsConfig(section, legacyPrGate) {
@@ -38,6 +43,15 @@ function buildCommandsConfig(section, legacyPrGate) {
38
43
  ? section
39
44
  : {};
40
45
  const prGateRaw = raw['pr-gate'] ?? legacyPrGate;
41
- return new CommandsConfig((0, pr_gate_config_1.buildPrGateConfig)(prGateRaw), typeof raw.upsertPr === 'string' && raw.upsertPr.trim() !== '' ? raw.upsertPr : exports.DEFAULT_UPSERT_PR_COMMAND, typeof raw.mergeComplete === 'string' && raw.mergeComplete.trim() !== '' ? raw.mergeComplete : exports.DEFAULT_MERGE_COMPLETE_COMMAND);
46
+ const hints = (typeof raw.guardHints === 'object' && raw.guardHints !== null)
47
+ ? raw.guardHints
48
+ : {};
49
+ const upsertPr = typeof hints.prCreationOrPush === 'string' && hints.prCreationOrPush.trim() !== '' ? hints.prCreationOrPush
50
+ : typeof raw.upsertPr === 'string' && raw.upsertPr.trim() !== '' ? raw.upsertPr
51
+ : exports.DEFAULT_UPSERT_PR_COMMAND;
52
+ const mergeComplete = typeof hints.mergeInProgress === 'string' && hints.mergeInProgress.trim() !== '' ? hints.mergeInProgress
53
+ : typeof raw.mergeComplete === 'string' && raw.mergeComplete.trim() !== '' ? raw.mergeComplete
54
+ : exports.DEFAULT_MERGE_COMPLETE_COMMAND;
55
+ return new CommandsConfig((0, pr_gate_config_1.buildPrGateConfig)(prGateRaw), upsertPr, mergeComplete);
42
56
  }
43
57
  //# sourceMappingURL=commands-config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"commands-config.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/commands-config.ts"],"names":[],"mappings":";AAAA,kGAAkG;AAClG,oGAAoG;AACpG,gGAAgG;AAChG,oGAAoG;AACpG,EAAE;AACF,sGAAsG;;;AAqCtG,kDAUC;AA7CD,qDAAmE;AAEnE,oGAAoG;AACpG,wFAAwF;AAC3E,QAAA,yBAAyB,GAAG,yBAAyB,CAAC;AACtD,QAAA,8BAA8B,GAAG,0BAA0B,CAAC;AAEzE,MAAa,cAAc;IACvB,MAAM,CAAe;IACrB,wGAAwG;IACxG,QAAQ,CAAS;IACjB,qFAAqF;IACrF,aAAa,CAAS;IAEtB,YAAY,MAAoB,EAAE,QAAgB,EAAE,aAAqB;QACrE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;IACvC,CAAC;CACJ;AAZD,wCAYC;AASD;;;;;GAKG;AACH,4FAA4F;AAC5F,SAAgB,mBAAmB,CAAC,OAAgB,EAAE,YAAsB;IACxE,MAAM,GAAG,GAAuB,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,CAAC;QAC7E,CAAC,CAAE,OAA8B;QACjC,CAAC,CAAC,EAAE,CAAC;IACT,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC,IAAI,YAAY,CAAC;IACjD,OAAO,IAAI,cAAc,CACrB,IAAA,kCAAiB,EAAC,SAAS,CAAC,EAC5B,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,iCAAyB,EACzG,OAAO,GAAG,CAAC,aAAa,KAAK,QAAQ,IAAI,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,sCAA8B,CAChI,CAAC;AACN,CAAC","sourcesContent":["// The \"commands\" section of webpieces.config.json. It configures the gated command endpoints that\n// the bash guards point agents toward (instead of running raw `gh pr create` / finishing a merge by\n// hand), plus the pr-gate build dashboard. pr-gate lives here (not at the top level) because it\n// configures the wp-start-upsert-pr / wp-finish-upsert-pr commands — the guards only POINT at them.\n//\n// Data-only (per CLAUDE.md, classes for data). Built + validated by loadAndValidate (load-config.ts).\n\nimport { PrGateConfig, buildPrGateConfig } from './pr-gate-config';\n\n// Canonical gated commands. Guards default their command hints to these so a project that renames a\n// command edits it in ONE place (the commands section) and every guard message follows.\nexport const DEFAULT_UPSERT_PR_COMMAND = 'pnpm wp-start-upsert-pr';\nexport const DEFAULT_MERGE_COMPLETE_COMMAND = 'pnpm wp-finish-upsert-pr';\n\nexport class CommandsConfig {\n prGate: PrGateConfig;\n // Command the pr-creation-or-push-guard tells agents to run instead of `gh pr create` or a manual push.\n upsertPr: string;\n // Command the merge-in-progress-guard tells agents to run to finish a 3-point merge.\n mergeComplete: string;\n\n constructor(prGate: PrGateConfig, upsertPr: string, mergeComplete: string) {\n this.prGate = prGate;\n this.upsertPr = upsertPr;\n this.mergeComplete = mergeComplete;\n }\n}\n\ninterface RawCommandsSection {\n // webpieces-disable no-any-unknown -- opaque pr-gate JSON, validated by validatePrGateSection\n 'pr-gate'?: unknown;\n upsertPr?: string;\n mergeComplete?: string;\n}\n\n/**\n * Build a CommandsConfig from the already-parsed `commands` section, falling back to defaults for any\n * field the consumer omits. `legacyPrGate` is the top-level `pr-gate` block (pre-migration layout);\n * it is used only as a fallback so an un-migrated file still loads its gate config. Pure transform —\n * the structural validation happens in loadAndValidate.\n */\n// webpieces-disable no-any-unknown -- `section` is opaque consumer JSON until narrowed here\nexport function buildCommandsConfig(section: unknown, legacyPrGate?: unknown): CommandsConfig {\n const raw: RawCommandsSection = (typeof section === 'object' && section !== null)\n ? (section as RawCommandsSection)\n : {};\n const prGateRaw = raw['pr-gate'] ?? legacyPrGate;\n return new CommandsConfig(\n buildPrGateConfig(prGateRaw),\n typeof raw.upsertPr === 'string' && raw.upsertPr.trim() !== '' ? raw.upsertPr : DEFAULT_UPSERT_PR_COMMAND,\n typeof raw.mergeComplete === 'string' && raw.mergeComplete.trim() !== '' ? raw.mergeComplete : DEFAULT_MERGE_COMPLETE_COMMAND,\n );\n}\n"]}
1
+ {"version":3,"file":"commands-config.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/commands-config.ts"],"names":[],"mappings":";AAAA,kGAAkG;AAClG,oGAAoG;AACpG,gGAAgG;AAChG,oGAAoG;AACpG,EAAE;AACF,sGAAsG;;;AAqDtG,kDAiBC;AApED,qDAAmE;AAEnE,oGAAoG;AACpG,wFAAwF;AAC3E,QAAA,yBAAyB,GAAG,yBAAyB,CAAC;AACtD,QAAA,8BAA8B,GAAG,0BAA0B,CAAC;AAEzE,MAAa,cAAc;IACvB,MAAM,CAAe;IACrB,wGAAwG;IACxG,sGAAsG;IACtG,QAAQ,CAAS;IACjB,qFAAqF;IACrF,0GAA0G;IAC1G,aAAa,CAAS;IAEtB,YAAY,MAAoB,EAAE,QAAgB,EAAE,aAAqB;QACrE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;IACvC,CAAC;CACJ;AAdD,wCAcC;AAoBD;;;;;;;;GAQG;AACH,4FAA4F;AAC5F,SAAgB,mBAAmB,CAAC,OAAgB,EAAE,YAAsB;IACxE,MAAM,GAAG,GAAuB,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,CAAC;QAC7E,CAAC,CAAE,OAA8B;QACjC,CAAC,CAAC,EAAE,CAAC;IACT,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC,IAAI,YAAY,CAAC;IACjD,MAAM,KAAK,GAAkB,CAAC,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,IAAI,GAAG,CAAC,UAAU,KAAK,IAAI,CAAC;QACxF,CAAC,CAAC,GAAG,CAAC,UAAU;QAChB,CAAC,CAAC,EAAE,CAAC;IACT,MAAM,QAAQ,GACV,OAAO,KAAK,CAAC,gBAAgB,KAAK,QAAQ,IAAI,KAAK,CAAC,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,gBAAgB;QACvG,CAAC,CAAC,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ;YAC3E,CAAC,CAAC,iCAAyB,CAAC;IACxC,MAAM,aAAa,GACf,OAAO,KAAK,CAAC,eAAe,KAAK,QAAQ,IAAI,KAAK,CAAC,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,eAAe;QACpG,CAAC,CAAC,OAAO,GAAG,CAAC,aAAa,KAAK,QAAQ,IAAI,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa;YAC1F,CAAC,CAAC,sCAA8B,CAAC;IAC7C,OAAO,IAAI,cAAc,CAAC,IAAA,kCAAiB,EAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;AACrF,CAAC","sourcesContent":["// The \"commands\" section of webpieces.config.json. It configures the gated command endpoints that\n// the bash guards point agents toward (instead of running raw `gh pr create` / finishing a merge by\n// hand), plus the pr-gate build dashboard. pr-gate lives here (not at the top level) because it\n// configures the wp-start-upsert-pr / wp-finish-upsert-pr commands — the guards only POINT at them.\n//\n// Data-only (per CLAUDE.md, classes for data). Built + validated by loadAndValidate (load-config.ts).\n\nimport { PrGateConfig, buildPrGateConfig } from './pr-gate-config';\n\n// Canonical gated commands. Guards default their command hints to these so a project that renames a\n// command edits it in ONE place (the commands section) and every guard message follows.\nexport const DEFAULT_UPSERT_PR_COMMAND = 'pnpm wp-start-upsert-pr';\nexport const DEFAULT_MERGE_COMPLETE_COMMAND = 'pnpm wp-finish-upsert-pr';\n\nexport class CommandsConfig {\n prGate: PrGateConfig;\n // Command the pr-creation-or-push-guard tells agents to run instead of `gh pr create` or a manual push.\n // Sourced from commands.guardHints.prCreationOrPush (canonical) or the legacy flat commands.upsertPr.\n upsertPr: string;\n // Command the merge-in-progress-guard tells agents to run to finish a 3-point merge.\n // Sourced from commands.guardHints.mergeInProgress (canonical) or the legacy flat commands.mergeComplete.\n mergeComplete: string;\n\n constructor(prGate: PrGateConfig, upsertPr: string, mergeComplete: string) {\n this.prGate = prGate;\n this.upsertPr = upsertPr;\n this.mergeComplete = mergeComplete;\n }\n}\n\n// The `commands.guardHints` sub-object: the ONLY command strings the guards read (each maps to exactly\n// one guard). Grouped under `guardHints` so the file makes plain these are guard hints — not pr-gate\n// config, and not command behaviour. `prCreationOrPush` → pr-creation-or-push-guard;\n// `mergeInProgress` → merge-in-progress-guard.\ninterface RawGuardHints {\n prCreationOrPush?: string;\n mergeInProgress?: string;\n}\n\ninterface RawCommandsSection {\n // webpieces-disable no-any-unknown -- opaque pr-gate JSON, validated by validatePrGateSection\n 'pr-gate'?: unknown;\n guardHints?: RawGuardHints;\n // Legacy FLAT command strings, kept for back-compat until every consumer migrates to guardHints.\n upsertPr?: string;\n mergeComplete?: string;\n}\n\n/**\n * Build a CommandsConfig from the already-parsed `commands` section, falling back to defaults for any\n * field the consumer omits. `legacyPrGate` is the top-level `pr-gate` block (pre-migration layout);\n * it is used only as a fallback so an un-migrated file still loads its gate config. Pure transform —\n * the structural validation happens in loadAndValidate.\n *\n * Command-string precedence per field: commands.guardHints.<name> (canonical) → the legacy flat\n * commands.<upsertPr|mergeComplete> → the built-in default. So a half-migrated file still resolves.\n */\n// webpieces-disable no-any-unknown -- `section` is opaque consumer JSON until narrowed here\nexport function buildCommandsConfig(section: unknown, legacyPrGate?: unknown): CommandsConfig {\n const raw: RawCommandsSection = (typeof section === 'object' && section !== null)\n ? (section as RawCommandsSection)\n : {};\n const prGateRaw = raw['pr-gate'] ?? legacyPrGate;\n const hints: RawGuardHints = (typeof raw.guardHints === 'object' && raw.guardHints !== null)\n ? raw.guardHints\n : {};\n const upsertPr =\n typeof hints.prCreationOrPush === 'string' && hints.prCreationOrPush.trim() !== '' ? hints.prCreationOrPush\n : typeof raw.upsertPr === 'string' && raw.upsertPr.trim() !== '' ? raw.upsertPr\n : DEFAULT_UPSERT_PR_COMMAND;\n const mergeComplete =\n typeof hints.mergeInProgress === 'string' && hints.mergeInProgress.trim() !== '' ? hints.mergeInProgress\n : typeof raw.mergeComplete === 'string' && raw.mergeComplete.trim() !== '' ? raw.mergeComplete\n : DEFAULT_MERGE_COMPLETE_COMMAND;\n return new CommandsConfig(buildPrGateConfig(prGateRaw), upsertPr, mergeComplete);\n}\n"]}
package/src/index.d.ts CHANGED
@@ -35,12 +35,13 @@ export type { ClientCreationSeverity } from './no-client-creation-config';
35
35
  export type { MethodLimitMode, FileLimitMode, ReturnTypeMode, InlineTypeMode, ModifiedCodeMode, ProjectMode, PrismaValidateDtosMode, PrismaConverterMode, DirectApiResolverMode, ThrowCauseMode, OnOffMode, StructuralMode, ValidateTsMode, } from './rule-configs';
36
36
  export { FeatureBranchGuardConfig, ReadStaleGuardConfig, MergedBranchBashGuardConfig, StaleMainBashGuardConfig, } from './main-sync-guard-configs';
37
37
  export { GateDefinition, PrGateConfig, defaultGates, defaultPrGateConfig, buildPrGateConfig, MERGE_MODE_AUTO, MERGE_MODE_NONE, MERGE_MODES, } from './pr-gate-config';
38
- export { ChecklistDefinition, toChecklist, } from './checklist-config';
38
+ export { ChecklistDefinition, ChecklistSource, toChecklist, resolveChecklistDoc, formatFileList, } from './checklist-config';
39
39
  export type { RawChecklistItem } from './checklist-config';
40
40
  export { ChecklistManifestService } from './checklist-manifest';
41
+ export { ChecklistInstructionsService } from './checklist-instructions';
41
42
  export { GateTokenService, computeGateToken, gateTokenMarker, extractGateToken, verifyGateToken, } from './gate-token';
42
43
  export { SubagentProvenanceService, ProvenanceResult, PROVENANCE_OK, PROVENANCE_MISSING, PROVENANCE_SKIPPED, } from './subagent-provenance';
43
- export { ReviewJson, PrContext, ChecklistResult, ChecklistVerdict, CK_PASS, CK_OVERRIDDEN, CK_FAIL, CK_MISSING, RequiredChecklist, ReviewJsonService, loadReviewJson, prDirFor, reviewJsonPath, reviewJsonSchemaHint, } from './review-json';
44
+ export { ReviewJson, PrContext, ChecklistResult, ChecklistVerdict, CK_PASS, CK_OVERRIDDEN, CK_FAIL, CK_MISSING, RequiredChecklist, ChecklistReviewContext, ReviewJsonService, loadReviewJson, prDirFor, reviewJsonPath, reviewJsonSchemaHint, } from './review-json';
44
45
  export { MainSyncStatus, MainSyncLock, MainSyncStatusService, DEFAULT_HANG_TIMEOUT_MINUTES, mainSyncStatusPath, mainSyncLockPath, readMainSyncStatus, writeMainSyncStatus, readMainSyncLock, writeMainSyncLock, isLockStale, isRefreshInProgress, tryAcquireMainSyncLock, inProcessLock, finishedLock, computeMainSyncStatus, stampCleanMainSyncStatus, squashRecoverySteps, } from './main-sync-status';
45
46
  export { MergedBranch, DeletableBranch, DeletableWorktree, MergedBranchesCache, MergedBranchesService, } from './merged-branches';
46
47
  export { Worktree, WorktreeService, } from './worktrees';
package/src/index.js CHANGED
@@ -2,9 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  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.validateChecklistDocs = exports.allRuleNames = exports.validateMatchRulesSection = exports.validateExcludePaths = exports.validateCommandsSection = exports.validateSectionPlacement = exports.validateChecklistsSection = 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.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 = exports.getCurrentBranch = exports.shouldSkipRule = void 0;
5
- exports.verifyGateToken = exports.extractGateToken = exports.gateTokenMarker = exports.computeGateToken = exports.GateTokenService = exports.ChecklistManifestService = exports.toChecklist = exports.ChecklistDefinition = exports.MERGE_MODES = exports.MERGE_MODE_NONE = exports.MERGE_MODE_AUTO = exports.buildPrGateConfig = exports.defaultPrGateConfig = exports.defaultGates = exports.PrGateConfig = exports.GateDefinition = exports.StaleMainBashGuardConfig = exports.MergedBranchBashGuardConfig = exports.ReadStaleGuardConfig = exports.FeatureBranchGuardConfig = exports.CLIENT_CREATION_SEVERITIES = exports.NoClientCreationOutsideServerOrClientConfig = 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.ValidateEslintSyncConfig = exports.ValidateVersionsLockedConfig = exports.ValidatePackageJsonConfig = exports.ValidateNoArchitectureCyclesConfig = exports.ValidateArchitectureUnchangedConfig = exports.ValidateTsInSrcConfig = exports.NoJsFilesConfig = exports.DiGraphConfig = exports.NxWiringConfig = exports.RuntimeArchitectureConfig = exports.NoFileImportCyclesConfig = exports.RedirectHowToMergeMainConfig = exports.PrMergeGuardConfig = exports.MergeInProgressGuardConfig = void 0;
6
- 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 = exports.tryAcquireMainSyncLock = 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.RequiredChecklist = exports.CK_MISSING = exports.CK_FAIL = exports.CK_OVERRIDDEN = exports.CK_PASS = exports.ChecklistVerdict = exports.ChecklistResult = exports.PrContext = exports.ReviewJson = exports.PROVENANCE_SKIPPED = exports.PROVENANCE_MISSING = exports.PROVENANCE_OK = exports.ProvenanceResult = exports.SubagentProvenanceService = void 0;
7
- exports.DEFAULT_MERGE_COMPLETE_COMMAND = exports.DEFAULT_UPSERT_PR_COMMAND = exports.buildCommandsConfig = exports.CommandsConfig = exports.logBranchMutation = void 0;
5
+ exports.GateTokenService = exports.ChecklistInstructionsService = exports.ChecklistManifestService = exports.formatFileList = exports.resolveChecklistDoc = exports.toChecklist = exports.ChecklistSource = exports.ChecklistDefinition = exports.MERGE_MODES = exports.MERGE_MODE_NONE = exports.MERGE_MODE_AUTO = exports.buildPrGateConfig = exports.defaultPrGateConfig = exports.defaultGates = exports.PrGateConfig = exports.GateDefinition = exports.StaleMainBashGuardConfig = exports.MergedBranchBashGuardConfig = exports.ReadStaleGuardConfig = exports.FeatureBranchGuardConfig = exports.CLIENT_CREATION_SEVERITIES = exports.NoClientCreationOutsideServerOrClientConfig = 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.ValidateEslintSyncConfig = exports.ValidateVersionsLockedConfig = exports.ValidatePackageJsonConfig = exports.ValidateNoArchitectureCyclesConfig = exports.ValidateArchitectureUnchangedConfig = exports.ValidateTsInSrcConfig = exports.NoJsFilesConfig = exports.DiGraphConfig = exports.NxWiringConfig = exports.RuntimeArchitectureConfig = exports.NoFileImportCyclesConfig = exports.RedirectHowToMergeMainConfig = exports.PrMergeGuardConfig = exports.MergeInProgressGuardConfig = void 0;
6
+ 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 = exports.tryAcquireMainSyncLock = 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.ChecklistReviewContext = exports.RequiredChecklist = exports.CK_MISSING = exports.CK_FAIL = exports.CK_OVERRIDDEN = exports.CK_PASS = exports.ChecklistVerdict = exports.ChecklistResult = exports.PrContext = exports.ReviewJson = exports.PROVENANCE_SKIPPED = exports.PROVENANCE_MISSING = exports.PROVENANCE_OK = exports.ProvenanceResult = exports.SubagentProvenanceService = exports.verifyGateToken = exports.extractGateToken = exports.gateTokenMarker = exports.computeGateToken = void 0;
7
+ 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 = void 0;
8
8
  var types_1 = require("./types");
9
9
  Object.defineProperty(exports, "ResolvedConfig", { enumerable: true, get: function () { return types_1.ResolvedConfig; } });
10
10
  Object.defineProperty(exports, "ResolvedRuleConfig", { enumerable: true, get: function () { return types_1.ResolvedRuleConfig; } });
@@ -182,9 +182,14 @@ Object.defineProperty(exports, "MERGE_MODE_NONE", { enumerable: true, get: funct
182
182
  Object.defineProperty(exports, "MERGE_MODES", { enumerable: true, get: function () { return pr_gate_config_1.MERGE_MODES; } });
183
183
  var checklist_config_1 = require("./checklist-config");
184
184
  Object.defineProperty(exports, "ChecklistDefinition", { enumerable: true, get: function () { return checklist_config_1.ChecklistDefinition; } });
185
+ Object.defineProperty(exports, "ChecklistSource", { enumerable: true, get: function () { return checklist_config_1.ChecklistSource; } });
185
186
  Object.defineProperty(exports, "toChecklist", { enumerable: true, get: function () { return checklist_config_1.toChecklist; } });
187
+ Object.defineProperty(exports, "resolveChecklistDoc", { enumerable: true, get: function () { return checklist_config_1.resolveChecklistDoc; } });
188
+ Object.defineProperty(exports, "formatFileList", { enumerable: true, get: function () { return checklist_config_1.formatFileList; } });
186
189
  var checklist_manifest_1 = require("./checklist-manifest");
187
190
  Object.defineProperty(exports, "ChecklistManifestService", { enumerable: true, get: function () { return checklist_manifest_1.ChecklistManifestService; } });
191
+ var checklist_instructions_1 = require("./checklist-instructions");
192
+ Object.defineProperty(exports, "ChecklistInstructionsService", { enumerable: true, get: function () { return checklist_instructions_1.ChecklistInstructionsService; } });
188
193
  var gate_token_1 = require("./gate-token");
189
194
  Object.defineProperty(exports, "GateTokenService", { enumerable: true, get: function () { return gate_token_1.GateTokenService; } });
190
195
  Object.defineProperty(exports, "computeGateToken", { enumerable: true, get: function () { return gate_token_1.computeGateToken; } });
@@ -207,6 +212,7 @@ Object.defineProperty(exports, "CK_OVERRIDDEN", { enumerable: true, get: functio
207
212
  Object.defineProperty(exports, "CK_FAIL", { enumerable: true, get: function () { return review_json_1.CK_FAIL; } });
208
213
  Object.defineProperty(exports, "CK_MISSING", { enumerable: true, get: function () { return review_json_1.CK_MISSING; } });
209
214
  Object.defineProperty(exports, "RequiredChecklist", { enumerable: true, get: function () { return review_json_1.RequiredChecklist; } });
215
+ Object.defineProperty(exports, "ChecklistReviewContext", { enumerable: true, get: function () { return review_json_1.ChecklistReviewContext; } });
210
216
  Object.defineProperty(exports, "ReviewJsonService", { enumerable: true, get: function () { return review_json_1.ReviewJsonService; } });
211
217
  Object.defineProperty(exports, "loadReviewJson", { enumerable: true, get: function () { return review_json_1.loadReviewJson; } });
212
218
  Object.defineProperty(exports, "prDirFor", { enumerable: true, get: function () { return review_json_1.prDirFor; } });
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, validateChecklistsSection, validateSectionPlacement, validateCommandsSection, validateExcludePaths, validateMatchRulesSection, allRuleNames } from './validate-config';\nexport { validateChecklistDocs } from './checklist-docs-validator';\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 NoFileImportCyclesConfig,\n RuntimeArchitectureConfig,\n NxWiringConfig,\n DiGraphConfig,\n NoJsFilesConfig,\n ValidateTsInSrcConfig,\n ValidateArchitectureUnchangedConfig,\n ValidateNoArchitectureCyclesConfig,\n ValidatePackageJsonConfig,\n ValidateVersionsLockedConfig,\n ValidateEslintSyncConfig,\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 {\n NoClientCreationOutsideServerOrClientConfig,\n CLIENT_CREATION_SEVERITIES,\n} from './no-client-creation-config';\nexport type { ClientCreationSeverity } from './no-client-creation-config';\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 FeatureBranchGuardConfig,\n ReadStaleGuardConfig,\n MergedBranchBashGuardConfig,\n StaleMainBashGuardConfig,\n} from './main-sync-guard-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 ChecklistDefinition,\n toChecklist,\n} from './checklist-config';\nexport type { RawChecklistItem } from './checklist-config';\nexport { ChecklistManifestService } from './checklist-manifest';\nexport {\n GateTokenService,\n computeGateToken,\n gateTokenMarker,\n extractGateToken,\n verifyGateToken,\n} from './gate-token';\nexport {\n SubagentProvenanceService,\n ProvenanceResult,\n PROVENANCE_OK,\n PROVENANCE_MISSING,\n PROVENANCE_SKIPPED,\n} from './subagent-provenance';\nexport {\n ReviewJson,\n PrContext,\n ChecklistResult,\n ChecklistVerdict,\n CK_PASS,\n CK_OVERRIDDEN,\n CK_FAIL,\n CK_MISSING,\n RequiredChecklist,\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 tryAcquireMainSyncLock,\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, validateChecklistsSection, validateSectionPlacement, validateCommandsSection, validateExcludePaths, validateMatchRulesSection, allRuleNames } from './validate-config';\nexport { validateChecklistDocs } from './checklist-docs-validator';\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 NoFileImportCyclesConfig,\n RuntimeArchitectureConfig,\n NxWiringConfig,\n DiGraphConfig,\n NoJsFilesConfig,\n ValidateTsInSrcConfig,\n ValidateArchitectureUnchangedConfig,\n ValidateNoArchitectureCyclesConfig,\n ValidatePackageJsonConfig,\n ValidateVersionsLockedConfig,\n ValidateEslintSyncConfig,\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 {\n NoClientCreationOutsideServerOrClientConfig,\n CLIENT_CREATION_SEVERITIES,\n} from './no-client-creation-config';\nexport type { ClientCreationSeverity } from './no-client-creation-config';\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 FeatureBranchGuardConfig,\n ReadStaleGuardConfig,\n MergedBranchBashGuardConfig,\n StaleMainBashGuardConfig,\n} from './main-sync-guard-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 ChecklistDefinition,\n ChecklistSource,\n toChecklist,\n resolveChecklistDoc,\n formatFileList,\n} from './checklist-config';\nexport type { RawChecklistItem } from './checklist-config';\nexport { ChecklistManifestService } from './checklist-manifest';\nexport { ChecklistInstructionsService } from './checklist-instructions';\nexport {\n GateTokenService,\n computeGateToken,\n gateTokenMarker,\n extractGateToken,\n verifyGateToken,\n} from './gate-token';\nexport {\n SubagentProvenanceService,\n ProvenanceResult,\n PROVENANCE_OK,\n PROVENANCE_MISSING,\n PROVENANCE_SKIPPED,\n} from './subagent-provenance';\nexport {\n ReviewJson,\n PrContext,\n ChecklistResult,\n ChecklistVerdict,\n CK_PASS,\n CK_OVERRIDDEN,\n CK_FAIL,\n CK_MISSING,\n RequiredChecklist,\n ChecklistReviewContext,\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 tryAcquireMainSyncLock,\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,3 +1,4 @@
1
+ import { ChecklistSource } from './checklist-config';
1
2
  export declare class GateDefinition {
2
3
  name: string;
3
4
  patterns: string[];
@@ -27,7 +28,7 @@ export declare class PrGateConfig {
27
28
  * commits land as the internal "Squash merge of <branch>" subject.
28
29
  */
29
30
  mergeMode: string;
30
- checklistDoc: string;
31
+ checklists: ChecklistSource;
31
32
  checklistComments: boolean;
32
33
  /**
33
34
  * Shared secret used to mint the server-verifiable gate token. `wp-finish-upsert-pr` writes
@@ -42,7 +43,7 @@ export declare class PrGateConfig {
42
43
  * agent. See RESPONSE-pr-gate-ci-enforcement / the design memo for the full tradeoff.
43
44
  */
44
45
  gateSalt: string;
45
- constructor(mode: string, buildCommand: string, gates: GateDefinition[], mergeMode: string, checklistDoc?: string, gateSalt?: string, checklistComments?: boolean);
46
+ constructor(mode: string, buildCommand: string, gates: GateDefinition[], mergeMode: string, checklists?: ChecklistSource, gateSalt?: string, checklistComments?: boolean);
46
47
  }
47
48
  export declare function defaultGates(): GateDefinition[];
48
49
  export declare function defaultPrGateConfig(): PrGateConfig;
@@ -1,13 +1,14 @@
1
1
  "use strict";
2
- // PrGateConfig is the "special section" for the pr-gate dashboard. It does NOT live in the
3
- // validated `rules` map (the FieldDef schema can't express nested object arrays), but as a
4
- // top-level `pr-gate` key in webpieces.config.json. It is built and validated by
5
- // loadAndValidate (load-config.ts); this module holds only the data classes + defaults + toGate.
6
2
  Object.defineProperty(exports, "__esModule", { value: true });
7
3
  exports.PrGateConfig = exports.MERGE_MODES = exports.MERGE_MODE_NONE = exports.MERGE_MODE_AUTO = exports.GateDefinition = void 0;
8
4
  exports.defaultGates = defaultGates;
9
5
  exports.defaultPrGateConfig = defaultPrGateConfig;
10
6
  exports.buildPrGateConfig = buildPrGateConfig;
7
+ const checklist_config_1 = require("./checklist-config");
8
+ // PrGateConfig is the "special section" for the pr-gate dashboard. It does NOT live in the
9
+ // validated `rules` map (the FieldDef schema can't express nested object arrays), but as a
10
+ // top-level `pr-gate` key in webpieces.config.json. It is built and validated by
11
+ // loadAndValidate (load-config.ts); this module holds only the data classes + defaults + toGate.
11
12
  class GateDefinition {
12
13
  name;
13
14
  patterns;
@@ -54,9 +55,11 @@ class PrGateConfig {
54
55
  * commits land as the internal "Squash merge of <branch>" subject.
55
56
  */
56
57
  mergeMode;
57
- // Repo-relative path of the ONE doc carrying the checklist manifest (a <!-- webpieces:checklists [...] -->
58
- // JSON block). '' = no checklists. The checklist SET lives in that doc (content), never here (config).
59
- checklistDoc;
58
+ // WHERE this repo's review checklists come from: the `pr-gate.checklists` ARRAY in webpieces.config.json
59
+ // (primary `patterns` is a path-glob dispatch table and `subagent` a name binding, both config), or the
60
+ // legacy `{ doc }` form pointing at a doc carrying a <!-- webpieces:checklists [...] --> block. Empty
61
+ // source = no checklists.
62
+ checklists;
60
63
  // Whether wp-finish-upsert-pr publishes each reviewer's full `output` as ONE combined PR comment
61
64
  // (idempotently updated on every push). Defaults to true. Set false to keep the PR body-only.
62
65
  checklistComments;
@@ -74,12 +77,12 @@ class PrGateConfig {
74
77
  */
75
78
  gateSalt;
76
79
  // eslint-disable-next-line @typescript-eslint/max-params
77
- constructor(mode, buildCommand, gates, mergeMode, checklistDoc = '', gateSalt = '', checklistComments = true) {
80
+ constructor(mode, buildCommand, gates, mergeMode, checklists = new checklist_config_1.ChecklistSource(), gateSalt = '', checklistComments = true) {
78
81
  this.mode = mode;
79
82
  this.buildCommand = buildCommand;
80
83
  this.gates = gates;
81
84
  this.mergeMode = mergeMode;
82
- this.checklistDoc = checklistDoc;
85
+ this.checklists = checklists;
83
86
  this.gateSalt = gateSalt;
84
87
  this.checklistComments = checklistComments;
85
88
  }
@@ -96,8 +99,8 @@ function defaultGates() {
96
99
  ];
97
100
  }
98
101
  function defaultPrGateConfig() {
99
- // No default checklist doc — the extension point is opt-in; the default monorepo ships none.
100
- return new PrGateConfig('ON', '', defaultGates(), exports.MERGE_MODE_AUTO, '');
102
+ // No default checklists — the extension point is opt-in; the default monorepo ships none.
103
+ return new PrGateConfig('ON', '', defaultGates(), exports.MERGE_MODE_AUTO, new checklist_config_1.ChecklistSource());
101
104
  }
102
105
  function toGate(raw) {
103
106
  return new GateDefinition(raw.name ?? '', raw.patterns ?? [], raw.warningColor ?? 'yellow', raw.disabled ?? false);
@@ -120,12 +123,25 @@ function buildPrGateConfig(section) {
120
123
  // REQUIRED — validatePrGateSection rejects an omitted/unknown value, so this fallback only ever
121
124
  // applies to the no-config-file path that defaultPrGateConfig() serves.
122
125
  const mergeMode = raw.mergeMode ?? defaults.mergeMode;
123
- // Optional extension point — omitted ⇒ '' ⇒ no checklists computed anywhere downstream.
124
- const checklistDoc = raw.checklists?.doc ?? defaults.checklistDoc;
126
+ // Optional extension point — omitted ⇒ an empty source ⇒ no checklists computed anywhere downstream.
127
+ const checklists = toChecklistSource(raw.checklists, defaults.checklists);
125
128
  // Optional — omitted ⇒ '' ⇒ no gate token minted and CI enforcement is a no-op (back-compat).
126
129
  const gateSalt = raw.gateSalt ?? defaults.gateSalt;
127
130
  // Optional — omitted ⇒ true ⇒ reviewer output published as a PR comment.
128
131
  const checklistComments = raw.checklistComments ?? defaults.checklistComments;
129
- return new PrGateConfig(mode, buildCommand, gates, mergeMode, checklistDoc, gateSalt, checklistComments);
132
+ return new PrGateConfig(mode, buildCommand, gates, mergeMode, checklists, gateSalt, checklistComments);
133
+ }
134
+ /**
135
+ * Narrow the two accepted `pr-gate.checklists` shapes into ONE ChecklistSource so every downstream caller
136
+ * stops caring which one the consumer wrote. The array form resolves each entry's `doc` REPO-relative;
137
+ * the legacy `{ doc }` form defers to ChecklistManifestService, which resolves against the manifest doc.
138
+ */
139
+ // webpieces-disable no-function-outside-class -- pure config transform beside its data classes
140
+ function toChecklistSource(raw, defaults) {
141
+ if (raw === undefined)
142
+ return defaults;
143
+ if (Array.isArray(raw))
144
+ return new checklist_config_1.ChecklistSource(raw.map((item) => (0, checklist_config_1.toChecklist)(item, '')), '');
145
+ return new checklist_config_1.ChecklistSource([], raw.doc ?? '');
130
146
  }
131
147
  //# 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":"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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 // Repo-relative path of the ONE doc carrying the checklist manifest (a <!-- webpieces:checklists [...] -->\n // JSON block). '' = no checklists. The checklist SET lives in that doc (content), never here (config).\n checklistDoc: string;\n // Whether wp-finish-upsert-pr publishes each reviewer's full `output` as ONE combined PR comment\n // (idempotently updated on every push). Defaults to true. Set false to keep the PR body-only.\n checklistComments: boolean;\n /**\n * Shared secret used to mint the server-verifiable gate token. `wp-finish-upsert-pr` writes\n * `HMAC(gateSalt, HEAD_sha)` as a hidden marker into the PR body (and REFUSES to mint it unless\n * every BLOCK checklist passed), so a valid token IS proof the local gate ran and passed. A CI\n * check (`wp-check-pr` + the scaffolded workflow) recomputes it from the PR head sha and this salt.\n *\n * Optional, defaults to '' — empty means \"no token minted, no CI enforcement\" (byte-identical to\n * before this field existed). This is COMMITTED, obscurity-grade: it stops unhooked teammates who\n * push + open a PR in the web UI, but is readable in-repo and therefore forgeable by a determined\n * reader. It is deliberately NOT cryptographically sound; nothing local can stop a filesystem-reading\n * agent. See RESPONSE-pr-gate-ci-enforcement / the design memo for the full tradeoff.\n */\n gateSalt: string;\n\n // eslint-disable-next-line @typescript-eslint/max-params\n constructor(mode: string, buildCommand: string, gates: GateDefinition[], mergeMode: string, checklistDoc = '', gateSalt = '', checklistComments = true) {\n this.mode = mode;\n this.buildCommand = buildCommand;\n this.gates = gates;\n this.mergeMode = mergeMode;\n this.checklistDoc = checklistDoc;\n this.gateSalt = gateSalt;\n this.checklistComments = checklistComments;\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 // No default checklist doc — the extension point is opt-in; the default monorepo ships none.\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 checklists?: { doc?: string };\n gateSalt?: string;\n checklistComments?: boolean;\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 // Optional extension point — omitted ⇒ '' ⇒ no checklists computed anywhere downstream.\n const checklistDoc = raw.checklists?.doc ?? defaults.checklistDoc;\n // Optional — omitted ⇒ '' ⇒ no gate token minted and CI enforcement is a no-op (back-compat).\n const gateSalt = raw.gateSalt ?? defaults.gateSalt;\n // Optional — omitted ⇒ true ⇒ reviewer output published as a PR comment.\n const checklistComments = raw.checklistComments ?? defaults.checklistComments;\n return new PrGateConfig(mode, buildCommand, gates, mergeMode, checklistDoc, gateSalt, checklistComments);\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":["import { ChecklistDefinition, ChecklistSource, RawChecklistItem, toChecklist } from './checklist-config';\n\n// 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 // WHERE this repo's review checklists come from: the `pr-gate.checklists` ARRAY in webpieces.config.json\n // (primary — `patterns` is a path-glob dispatch table and `subagent` a name binding, both config), or the\n // legacy `{ doc }` form pointing at a doc carrying a <!-- webpieces:checklists [...] --> block. Empty\n // source = no checklists.\n checklists: ChecklistSource;\n // Whether wp-finish-upsert-pr publishes each reviewer's full `output` as ONE combined PR comment\n // (idempotently updated on every push). Defaults to true. Set false to keep the PR body-only.\n checklistComments: boolean;\n /**\n * Shared secret used to mint the server-verifiable gate token. `wp-finish-upsert-pr` writes\n * `HMAC(gateSalt, HEAD_sha)` as a hidden marker into the PR body (and REFUSES to mint it unless\n * every BLOCK checklist passed), so a valid token IS proof the local gate ran and passed. A CI\n * check (`wp-check-pr` + the scaffolded workflow) recomputes it from the PR head sha and this salt.\n *\n * Optional, defaults to '' — empty means \"no token minted, no CI enforcement\" (byte-identical to\n * before this field existed). This is COMMITTED, obscurity-grade: it stops unhooked teammates who\n * push + open a PR in the web UI, but is readable in-repo and therefore forgeable by a determined\n * reader. It is deliberately NOT cryptographically sound; nothing local can stop a filesystem-reading\n * agent. See RESPONSE-pr-gate-ci-enforcement / the design memo for the full tradeoff.\n */\n gateSalt: string;\n\n // eslint-disable-next-line @typescript-eslint/max-params\n constructor(mode: string, buildCommand: string, gates: GateDefinition[], mergeMode: string, checklists = new ChecklistSource(), gateSalt = '', checklistComments = true) {\n this.mode = mode;\n this.buildCommand = buildCommand;\n this.gates = gates;\n this.mergeMode = mergeMode;\n this.checklists = checklists;\n this.gateSalt = gateSalt;\n this.checklistComments = checklistComments;\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 // No default checklists — the extension point is opt-in; the default monorepo ships none.\n return new PrGateConfig('ON', '', defaultGates(), MERGE_MODE_AUTO, new ChecklistSource());\n}\n\ninterface RawGate {\n name?: string;\n patterns?: string[];\n warningColor?: string;\n disabled?: boolean;\n}\n\n// The legacy `checklists: { \"doc\": \"...\" }` pointer at a manifest doc. Named (not inline in the union) so\n// the two accepted shapes each have a name a reader can look up.\ninterface RawChecklistDocPointer {\n doc?: string;\n}\n\ninterface RawPrGateSection {\n mode?: string;\n buildCommand?: string;\n gates?: RawGate[];\n mergeMode?: string;\n // Either the array (primary) or the legacy { doc } pointer. validateChecklistsSection rejects anything else.\n checklists?: RawChecklistItem[] | RawChecklistDocPointer;\n gateSalt?: string;\n checklistComments?: boolean;\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 // Optional extension point — omitted ⇒ an empty source ⇒ no checklists computed anywhere downstream.\n const checklists = toChecklistSource(raw.checklists, defaults.checklists);\n // Optional — omitted ⇒ '' ⇒ no gate token minted and CI enforcement is a no-op (back-compat).\n const gateSalt = raw.gateSalt ?? defaults.gateSalt;\n // Optional — omitted ⇒ true ⇒ reviewer output published as a PR comment.\n const checklistComments = raw.checklistComments ?? defaults.checklistComments;\n return new PrGateConfig(mode, buildCommand, gates, mergeMode, checklists, gateSalt, checklistComments);\n}\n\n/**\n * Narrow the two accepted `pr-gate.checklists` shapes into ONE ChecklistSource so every downstream caller\n * stops caring which one the consumer wrote. The array form resolves each entry's `doc` REPO-relative;\n * the legacy `{ doc }` form defers to ChecklistManifestService, which resolves against the manifest doc.\n */\n// webpieces-disable no-function-outside-class -- pure config transform beside its data classes\nfunction toChecklistSource(raw: RawChecklistItem[] | RawChecklistDocPointer | undefined, defaults: ChecklistSource): ChecklistSource {\n if (raw === undefined) return defaults;\n if (Array.isArray(raw)) return new ChecklistSource(raw.map((item: RawChecklistItem): ChecklistDefinition => toChecklist(item, '')), '');\n return new ChecklistSource([], raw.doc ?? '');\n}\n"]}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Reject `gateSaltWhy` outright, and say why, so the next validate on upgrade FORCES its removal.
3
+ *
4
+ * webpieces.config.json is one of the first files a coding agent reads. A rationale note next to `gateSalt`
5
+ * necessarily explains what the token protects, that the salt is committed, and therefore how to forge it —
6
+ * i.e. it is a bypass how-to, sitting in the most-read file in the repo, defeating the only thing an
7
+ * obscurity-grade mechanism has going for it. The rationale belongs in the webpieces source (pr-gate-config.ts
8
+ * documents it in full for humans reading the tooling), never in consumer config. Every other `*Why` key
9
+ * stays allowed; this is not a general ban on documenting your config.
10
+ */
11
+ export declare function validateNoGateSaltRationale(s: Record<string, unknown>): string[];
12
+ /**
13
+ * The `checklists` section of a pr-gate config. TWO shapes are accepted:
14
+ * - an ARRAY of { subagent, doc?, patterns? } — the PRIMARY form, right here in webpieces.config.json
15
+ * where it is greppable, schemable and readable by any tool. Each `doc` resolves REPO-relative.
16
+ * - `{ "doc": "..." }` — the LEGACY form, where the same array lives in an HTML comment inside that doc
17
+ * and each entry's `doc` resolves relative to it. Still accepted; not recommended for new repos.
18
+ * Either way the entries themselves are validated by ChecklistManifestService, so both shapes get the
19
+ * identical subagent/doc/patterns checks. Exported so the isolated validate-checklist-docs target reuses
20
+ * it. `repoRoot` (when known) lets the doc + reviewer-agent existence checks run.
21
+ */
22
+ export declare function validateChecklistsSection(value: unknown, repoRoot?: string): string[];
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateNoGateSaltRationale = validateNoGateSaltRationale;
4
+ exports.validateChecklistsSection = validateChecklistsSection;
5
+ const checklist_manifest_1 = require("./checklist-manifest");
6
+ const checklist_config_1 = require("./checklist-config");
7
+ // The two `pr-gate` sub-sections whose validation is bulky enough to own a file: the review `checklists`
8
+ // (two accepted shapes) and the one rationale key that is rejected outright. Split out of validate-config.ts
9
+ // only for size; loadAndValidate still reaches both through validatePrGateSection.
10
+ // The `*Why` convention (buildCommandWhy, mergeModeWhy, gatesWhy…) is free-form rationale a consumer keeps
11
+ // beside a field, and pr-gate tolerates any of them — EXCEPT this one. See validateNoGateSaltRationale.
12
+ const GATE_SALT_WHY = 'gateSaltWhy';
13
+ /**
14
+ * Reject `gateSaltWhy` outright, and say why, so the next validate on upgrade FORCES its removal.
15
+ *
16
+ * webpieces.config.json is one of the first files a coding agent reads. A rationale note next to `gateSalt`
17
+ * necessarily explains what the token protects, that the salt is committed, and therefore how to forge it —
18
+ * i.e. it is a bypass how-to, sitting in the most-read file in the repo, defeating the only thing an
19
+ * obscurity-grade mechanism has going for it. The rationale belongs in the webpieces source (pr-gate-config.ts
20
+ * documents it in full for humans reading the tooling), never in consumer config. Every other `*Why` key
21
+ * stays allowed; this is not a general ban on documenting your config.
22
+ */
23
+ // webpieces-disable no-any-unknown -- the already-narrowed opaque pr-gate section; only key PRESENCE is read
24
+ // webpieces-disable no-function-outside-class -- module-level config validator, matches the rest of this file
25
+ function validateNoGateSaltRationale(s) {
26
+ if (!(GATE_SALT_WHY in s))
27
+ return [];
28
+ return [
29
+ `[pr-gate] DELETE the "${GATE_SALT_WHY}" key from webpieces.config.json. It is a rationale note next to ` +
30
+ `"gateSalt", which means it spells out what the gate token protects and that the salt is committed — a ` +
31
+ `bypass how-to in the file a coding agent reads first. The mechanism is obscurity-grade; documenting it ` +
32
+ `here removes the obscurity. Nothing else needs changing: the reasoning is already documented in the ` +
33
+ `webpieces source (PrGateConfig.gateSalt) for humans reading the tooling.`,
34
+ ];
35
+ }
36
+ /**
37
+ * The `checklists` section of a pr-gate config. TWO shapes are accepted:
38
+ * - an ARRAY of { subagent, doc?, patterns? } — the PRIMARY form, right here in webpieces.config.json
39
+ * where it is greppable, schemable and readable by any tool. Each `doc` resolves REPO-relative.
40
+ * - `{ "doc": "..." }` — the LEGACY form, where the same array lives in an HTML comment inside that doc
41
+ * and each entry's `doc` resolves relative to it. Still accepted; not recommended for new repos.
42
+ * Either way the entries themselves are validated by ChecklistManifestService, so both shapes get the
43
+ * identical subagent/doc/patterns checks. Exported so the isolated validate-checklist-docs target reuses
44
+ * it. `repoRoot` (when known) lets the doc + reviewer-agent existence checks run.
45
+ */
46
+ // webpieces-disable no-any-unknown -- `value` is opaque consumer JSON until narrowed below
47
+ // webpieces-disable no-function-outside-class -- module-level config validator, matches the rest of this file
48
+ function validateChecklistsSection(value, repoRoot) {
49
+ if (Array.isArray(value))
50
+ return validateChecklistArray(value, repoRoot);
51
+ if (typeof value !== 'object' || value === null) {
52
+ return [`[pr-gate] "checklists" must be an array of { "subagent", "doc"?, "patterns"? }, or the legacy object { "doc": "<path to the review manifest doc>" }.`];
53
+ }
54
+ // webpieces-disable no-any-unknown -- narrowing the opaque checklists section
55
+ const doc = value['doc'];
56
+ if (typeof doc !== 'string' || doc.trim() === '') {
57
+ return [`[pr-gate] "checklists.doc" must be a non-empty string — the repo-relative markdown doc carrying the <!-- webpieces:checklists [...] --> manifest. (Preferred alternative: drop the object and put the checklist ARRAY directly in "checklists".)`];
58
+ }
59
+ if (repoRoot === undefined)
60
+ return [];
61
+ return new checklist_manifest_1.ChecklistManifestService().validate(repoRoot, new checklist_config_1.ChecklistSource([], doc));
62
+ }
63
+ // The array (primary) shape: structurally check each entry HERE — a bad `patterns` or a non-object entry is
64
+ // a config-file typo and deserves a `checklists[i]` message — then hand the narrowed defs to the one
65
+ // validator both shapes share.
66
+ // webpieces-disable no-any-unknown -- opaque consumer JSON entries, narrowed per-field below
67
+ // webpieces-disable no-function-outside-class -- module-level config validator, matches the rest of this file
68
+ function validateChecklistArray(value, repoRoot) {
69
+ const errors = [];
70
+ const items = [];
71
+ // webpieces-disable no-any-unknown -- each array entry is opaque consumer JSON, narrowed field-by-field below
72
+ value.forEach((entry, i) => {
73
+ if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) {
74
+ errors.push(`[pr-gate] checklists[${i}] must be an object { "subagent", "doc"?, "patterns"? }.`);
75
+ return;
76
+ }
77
+ // webpieces-disable no-any-unknown -- narrowing one opaque checklist entry
78
+ const e = entry;
79
+ if (e['doc'] !== undefined && typeof e['doc'] !== 'string') {
80
+ errors.push(`[pr-gate] checklists[${i}].doc must be a string — a REPO-relative path to the reviewer's guidance doc (omit it and the reviewer just reads the diff).`);
81
+ }
82
+ // webpieces-disable no-any-unknown -- opaque array element, narrowed by the typeof guard
83
+ if (e['patterns'] !== undefined && !(Array.isArray(e['patterns']) && e['patterns'].every((p) => typeof p === 'string'))) {
84
+ errors.push(`[pr-gate] checklists[${i}].patterns must be a string[] of path globs (omit or [] to run on every PR).`);
85
+ }
86
+ items.push(e);
87
+ });
88
+ if (repoRoot === undefined)
89
+ return errors;
90
+ const defs = items.map((item) => (0, checklist_config_1.toChecklist)(item, ''));
91
+ return [...errors, ...new checklist_manifest_1.ChecklistManifestService().validate(repoRoot, new checklist_config_1.ChecklistSource(defs, ''))];
92
+ }
93
+ //# sourceMappingURL=pr-gate-section-validators.js.map