@codedrifters/configulator 0.0.329 → 0.0.330

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.mjs CHANGED
@@ -586,7 +586,8 @@ var agendaAnalystSubAgent = {
586
586
  " or cut content \u2014 do not ship a math-broken agenda.",
587
587
  "",
588
588
  "7. **Create the folder `index.md` if missing.** Populate it",
589
- " following the `stub-index-convention` rule:",
589
+ " following the section-index-page contract in the",
590
+ " `shared-editing-safety` rule:",
590
591
  " - Frontmatter `title` (short sidebar label) and `description`",
591
592
  " (one line).",
592
593
  " - A 2\u20134 sentence summary of the meeting's objective and desired",
@@ -1159,11 +1160,7 @@ var awsCdkBundle = {
1159
1160
  // src/agent/bundles/issue-templates.ts
1160
1161
  var DEFAULT_ISSUE_TEMPLATES_ENABLED = true;
1161
1162
  var DEFAULT_ISSUE_TEMPLATES_PATH = "docs/src/content/docs/agents/issue-templates.md";
1162
- var DEFAULT_ISSUE_TEMPLATES_BUNDLE_PATH_PATTERNS = [
1163
- "packages/@codedrifters/configulator/src/agent/bundles/**/*.ts",
1164
- ".claude/agents/**/*.md",
1165
- ".claude/skills/**/*.md"
1166
- ];
1163
+ var DEFAULT_ISSUE_TEMPLATES_BUNDLE_PATH_PATTERNS = [".claude/agents/**/*.md", ".claude/skills/**/*.md"];
1167
1164
  var DEFAULT_ISSUE_TEMPLATES_EMIT_CHECKER = false;
1168
1165
  var DEFAULT_ISSUE_TEMPLATES_EMIT_STARTER = false;
1169
1166
  var DEFAULT_ISSUE_TEMPLATES_REQUIRE_REFERENCE = true;
@@ -2332,7 +2329,66 @@ function renderSharedEditingRuleContent(se) {
2332
2329
  "conflicts; rewriting or reordering existing rows almost always",
2333
2330
  "does. If a shared index needs a structural change (column",
2334
2331
  "added, sort key changed), file a dedicated issue for the change",
2335
- "rather than bundling it into a content-contributing PR."
2332
+ "rather than bundling it into a content-contributing PR.",
2333
+ "",
2334
+ "## Section Index Page Shape",
2335
+ "",
2336
+ "When any agent creates or updates an `index.md` (or `README.md`)",
2337
+ "in a docs subdirectory under a Starlight content root, the file's",
2338
+ "body must include:",
2339
+ "",
2340
+ "1. **A 1\u20132 paragraph summary** of the section's purpose and how",
2341
+ " it fits into the larger research, requirements, or capability",
2342
+ " area. Readers landing on the page should understand what's in",
2343
+ " the section without falling back to the sidebar.",
2344
+ "",
2345
+ "2. **A grouped, linked listing of the directory's children**",
2346
+ " (table or bullet list). When a natural taxonomy exists (e.g.",
2347
+ " organizations grouped by sub-segment, regulations grouped by",
2348
+ " jurisdiction, capabilities grouped by tier), use it. Otherwise",
2349
+ " sort alphabetically by title. Every listing entry must link",
2350
+ " to the child page.",
2351
+ "",
2352
+ "3. **No body `# Heading`.** Starlight renders the frontmatter",
2353
+ " `title:` as the page H1 automatically \u2014 a body H1 produces a",
2354
+ " duplicate. The same no-body-H1 contract that applies to skill",
2355
+ " templates and inline agent templates also applies to every",
2356
+ " index page emitted by an agent.",
2357
+ "",
2358
+ "### When this applies",
2359
+ "",
2360
+ "The convention applies to every `index.md` / `README.md` file",
2361
+ "covered by the shared-index path globs listed above:",
2362
+ "",
2363
+ "- `docs/src/content/docs/**/index.md`",
2364
+ "- `docs/src/content/docs/**/README.md`",
2365
+ "",
2366
+ "Any agent that scaffolds a new directory under a Starlight",
2367
+ "content root MUST populate the directory's index page following",
2368
+ "this contract \u2014 a one-sentence stub is not acceptable.",
2369
+ "",
2370
+ "### Reference shapes",
2371
+ "",
2372
+ "Existing rich indexes are the canonical reference shape. Examples:",
2373
+ "",
2374
+ "- A `<MEETINGS_ROOT>/<YYYY-MM-DD>-<slug>/index.md` populated by",
2375
+ " the `agenda-analyst` bundle: frontmatter `title` /",
2376
+ " `description`, a 2\u20134 sentence summary, and a `## Documents`",
2377
+ " section listing every page in the folder.",
2378
+ "- A regulations scope index that opens with two paragraphs of",
2379
+ " context and groups every linked regulation under a",
2380
+ " `## Regulations` table by jurisdiction.",
2381
+ "- A standards-organizations index that groups every linked",
2382
+ " organization under a `## Organizations` heading by role",
2383
+ " (governance, working group, implementer).",
2384
+ "",
2385
+ "### Out of scope",
2386
+ "",
2387
+ "- Auto-generated child listings via Astro/Starlight components.",
2388
+ " Agents emit hand-curated tables or bullet lists; the rule",
2389
+ " defines the shape, not the rendering technology.",
2390
+ "- Backfilling pre-existing stub indexes is a downstream-consumer",
2391
+ " cleanup task, not a configulator change."
2336
2392
  );
2337
2393
  return lines.join("\n");
2338
2394
  }
@@ -2887,71 +2943,6 @@ function assertValidProductContextPath(value) {
2887
2943
  }
2888
2944
  }
2889
2945
 
2890
- // src/agent/bundles/stub-index-convention.ts
2891
- function renderStubIndexConventionRuleContent() {
2892
- return [
2893
- "# Section Index Pages",
2894
- "",
2895
- "When any agent creates or updates an `index.md` (or `README.md`)",
2896
- "in a docs subdirectory under a Starlight content root, the file's",
2897
- "body must include:",
2898
- "",
2899
- "1. **A 1\u20132 paragraph summary** of the section's purpose and how",
2900
- " it fits into the larger research, requirements, or capability",
2901
- " area. Readers landing on the page should understand what's in",
2902
- " the section without falling back to the sidebar.",
2903
- "",
2904
- "2. **A grouped, linked listing of the directory's children**",
2905
- " (table or bullet list). When a natural taxonomy exists (e.g.",
2906
- " organizations grouped by sub-segment, regulations grouped by",
2907
- " jurisdiction, capabilities grouped by tier), use it. Otherwise",
2908
- " sort alphabetically by title. Every listing entry must link",
2909
- " to the child page.",
2910
- "",
2911
- "3. **No body `# Heading`.** Starlight renders the frontmatter",
2912
- " `title:` as the page H1 automatically \u2014 a body H1 produces a",
2913
- " duplicate. The same no-body-H1 contract that applies to skill",
2914
- " templates and inline agent templates also applies to every",
2915
- " index page emitted by an agent.",
2916
- "",
2917
- "## When this applies",
2918
- "",
2919
- "The convention applies to every `index.md` / `README.md` file",
2920
- "covered by the shared-index path globs documented in the",
2921
- "`shared-editing-safety` rule:",
2922
- "",
2923
- "- `docs/src/content/docs/**/index.md`",
2924
- "- `docs/src/content/docs/**/README.md`",
2925
- "",
2926
- "Any agent that scaffolds a new directory under a Starlight",
2927
- "content root MUST populate the directory's index page following",
2928
- "this contract \u2014 a one-sentence stub is not acceptable.",
2929
- "",
2930
- "## Reference shapes",
2931
- "",
2932
- "Existing rich indexes are the canonical reference shape. Examples:",
2933
- "",
2934
- "- A `<MEETINGS_ROOT>/<YYYY-MM-DD>-<slug>/index.md` populated by",
2935
- " the `agenda-analyst` bundle: frontmatter `title` /",
2936
- " `description`, a 2\u20134 sentence summary, and a `## Documents`",
2937
- " section listing every page in the folder.",
2938
- "- A regulations scope index that opens with two paragraphs of",
2939
- " context and groups every linked regulation under a",
2940
- " `## Regulations` table by jurisdiction.",
2941
- "- A standards-organizations index that groups every linked",
2942
- " organization under a `## Organizations` heading by role",
2943
- " (governance, working group, implementer).",
2944
- "",
2945
- "## Out of scope",
2946
- "",
2947
- "- Auto-generated child listings via Astro/Starlight components.",
2948
- " Agents emit hand-curated tables or bullet lists; the rule",
2949
- " defines the shape, not the rendering technology.",
2950
- "- Backfilling pre-existing stub indexes is a downstream-consumer",
2951
- " cleanup task, not a configulator change."
2952
- ].join("\n");
2953
- }
2954
-
2955
2946
  // src/agent/bundles/temporal-framing.ts
2956
2947
  var DEFAULT_TEMPORAL_FRAMING_ENABLED = true;
2957
2948
  var DEFAULT_TEMPORAL_FRAMING_PATHS = [
@@ -4120,6 +4111,12 @@ function buildBaseBundle(paths = DEFAULT_AGENT_PATHS) {
4120
4111
  {
4121
4112
  name: "issue-label-conventions",
4122
4113
  description: "Priority and status label taxonomy, defaults, inference rules, and blocking rules for agent-created or updated issues",
4114
+ // ALWAYS scope: every agent (and the user) needs the label
4115
+ // taxonomy whenever an issue gets created or updated, which
4116
+ // happens from any context — not only when editing agent /
4117
+ // skill / bundle source. Consumers that want to narrow the
4118
+ // load can override via `agentConfig.additionalRulePaths`
4119
+ // or `excludeRules`.
4123
4120
  scope: AGENT_RULE_SCOPE.ALWAYS,
4124
4121
  content: [
4125
4122
  "# Issue Label Conventions",
@@ -4485,7 +4482,13 @@ function buildBaseBundle(paths = DEFAULT_AGENT_PATHS) {
4485
4482
  {
4486
4483
  name: "progress-file-convention",
4487
4484
  description: "Progress-file schema and write rules, partial-resume protocol, stale-branch decision tree, and [BLOCKED] comment format that let phased agents survive crashes without losing work.",
4488
- scope: AGENT_RULE_SCOPE.ALWAYS,
4485
+ scope: AGENT_RULE_SCOPE.FILE_PATTERN,
4486
+ // Bundle defaults exclude paths into configulator's own source
4487
+ // (only meaningful when configulator is a workspace package,
4488
+ // i.e. in codedrifters/packages itself). That repo restores
4489
+ // them via `agentConfig.additionalRulePaths`; other consumers
4490
+ // get a clean default.
4491
+ filePatterns: [".claude/agents/*.md", ".claude/procedures/**"],
4489
4492
  content: renderProgressFilesRuleContent(resolveProgressFiles()),
4490
4493
  platforms: {
4491
4494
  cursor: { exclude: true }
@@ -4495,27 +4498,26 @@ function buildBaseBundle(paths = DEFAULT_AGENT_PATHS) {
4495
4498
  {
4496
4499
  name: "shared-editing-safety",
4497
4500
  description: "Shared-editing safety: single-entry deterministic-sort inserts on index files, commit-path verification, and the merge-conflict resolution recipe that keeps concurrent agent sessions from dropping each other's rows on shared registries and feature matrices.",
4498
- scope: AGENT_RULE_SCOPE.ALWAYS,
4501
+ scope: AGENT_RULE_SCOPE.FILE_PATTERN,
4502
+ filePatterns: DEFAULT_SHARED_INDEX_PATHS,
4499
4503
  content: renderSharedEditingRuleContent(resolveSharedEditing()),
4500
4504
  platforms: {
4501
4505
  cursor: { exclude: true }
4502
4506
  },
4503
4507
  tags: ["workflow"]
4504
4508
  },
4505
- {
4506
- name: "stub-index-convention",
4507
- description: "Section-index convention: every agent-emitted `index.md` / `README.md` under a Starlight docs root carries a contextual summary plus a grouped, linked listing of the directory's children \u2014 and no body `# Heading` (Starlight renders the frontmatter `title:` as the page H1).",
4508
- scope: AGENT_RULE_SCOPE.ALWAYS,
4509
- content: renderStubIndexConventionRuleContent(),
4510
- platforms: {
4511
- cursor: { exclude: true }
4512
- },
4513
- tags: ["workflow"]
4514
- },
4515
4509
  {
4516
4510
  name: "temporal-framing-convention",
4517
4511
  description: "Temporal-framing convention: every agent-authored time-sensitive factual claim (ownership, leadership tenure, regulatory status, litigation, dated metrics) carries an inline `as of [YYYY-MM-DD]` or `as of [Month YYYY]` qualifier on first occurrence so refresh agents have a mechanical signal for which claims to re-verify.",
4518
- scope: AGENT_RULE_SCOPE.ALWAYS,
4512
+ scope: AGENT_RULE_SCOPE.FILE_PATTERN,
4513
+ filePatterns: [
4514
+ "docs/src/content/docs/profiles/**/*.md",
4515
+ "docs/src/content/docs/industry-research/**/*.md",
4516
+ "docs/src/content/docs/software-research/**/*.md",
4517
+ "docs/src/content/docs/regulatory-research/**/*.md",
4518
+ "docs/src/content/docs/standards-research/**/*.md",
4519
+ "docs/src/content/docs/customer-research/**/*.md"
4520
+ ],
4519
4521
  content: renderTemporalFramingRuleContent(resolveTemporalFraming()),
4520
4522
  platforms: {
4521
4523
  cursor: { exclude: true }
@@ -4525,7 +4527,10 @@ function buildBaseBundle(paths = DEFAULT_AGENT_PATHS) {
4525
4527
  {
4526
4528
  name: "skill-evals",
4527
4529
  description: "Skill eval harness contract: declarative prompt/expected-output regression suites per skill at `<skillsRoot>/<skill-name>/evals/evals.json`, parameterised by a shared product-context fixture so the same eval shape works across every configulator-consuming project without forking fixtures.",
4528
- scope: AGENT_RULE_SCOPE.ALWAYS,
4530
+ scope: AGENT_RULE_SCOPE.FILE_PATTERN,
4531
+ // Bundle defaults exclude paths into configulator's own
4532
+ // source — see comment on progress-file-convention above.
4533
+ filePatterns: [".claude/skills/**"],
4529
4534
  content: renderSkillEvalsRuleContent(resolveSkillEvals()),
4530
4535
  platforms: {
4531
4536
  cursor: { exclude: true }
@@ -4535,7 +4540,14 @@ function buildBaseBundle(paths = DEFAULT_AGENT_PATHS) {
4535
4540
  {
4536
4541
  name: "issue-templates-convention",
4537
4542
  description: `Issue-templates convention: a single hand-authored reference page under \`${paths.docsRoot}/agents/issue-templates.md\` that carries one canonical \`gh issue create\` recipe per downstream phase label, and the reference-don't-inline rule that keeps bundle rules and agent prompts citing that page instead of duplicating full template invocations.`,
4538
- scope: AGENT_RULE_SCOPE.ALWAYS,
4543
+ scope: AGENT_RULE_SCOPE.FILE_PATTERN,
4544
+ // Bundle defaults exclude paths into configulator's own
4545
+ // source — see comment on progress-file-convention above.
4546
+ filePatterns: [
4547
+ ".claude/skills/**/SKILL.md",
4548
+ ".claude/agents/*.md",
4549
+ `${paths.docsRoot}/agents/issue-templates.md`
4550
+ ],
4539
4551
  content: renderIssueTemplatesRuleContent(resolveIssueTemplates()),
4540
4552
  platforms: {
4541
4553
  cursor: { exclude: true }
@@ -5858,8 +5870,8 @@ function buildBusinessModelsAnalystSubAgent(paths) {
5858
5870
  "",
5859
5871
  "7. **Create the segment index** at",
5860
5872
  " `<BUSINESS_MODELS_ROOT>/<industry>/segments/<SEGMENT_SLUG>/index.md`",
5861
- " if it does not already exist. Follow the",
5862
- " `stub-index-convention` rule: a 1\u20132 paragraph summary of the",
5873
+ " if it does not already exist. Follow the section-index-page",
5874
+ " contract in the `shared-editing-safety` rule: a 1\u20132 paragraph summary of the",
5863
5875
  " segment plus a linked listing of every page in the folder",
5864
5876
  " (`./business-model.md` and any value-stream / capability pages",
5865
5877
  " that land later). No body `# Heading` \u2014 the frontmatter",
@@ -10226,6 +10238,10 @@ var githubWorkflowBundle = {
10226
10238
  {
10227
10239
  name: "create-issue-workflow",
10228
10240
  description: "Automated workflow for creating a new GitHub issue",
10241
+ // ALWAYS scope: users invoke "create an issue" from any
10242
+ // context, not only when editing agent / skill / bundle source.
10243
+ // Consumers that want to narrow the load can override via
10244
+ // `agentConfig.additionalRulePaths` or `excludeRules`.
10229
10245
  scope: AGENT_RULE_SCOPE.ALWAYS,
10230
10246
  content: [
10231
10247
  "# Create Issue Workflow",
@@ -16256,7 +16272,15 @@ var orchestratorBundle = {
16256
16272
  {
16257
16273
  name: "orchestrator-conventions",
16258
16274
  description: "Guidelines for orchestrator agent behavior and pipeline management, including the funnel-tier dispatch sort, scope gate, and per-agent scheduled-task layout",
16259
- scope: AGENT_RULE_SCOPE.ALWAYS,
16275
+ scope: AGENT_RULE_SCOPE.FILE_PATTERN,
16276
+ // Bundle defaults exclude paths into configulator's own source
16277
+ // (only meaningful when configulator is a workspace package).
16278
+ // codedrifters/packages restores them via
16279
+ // `agentConfig.additionalRulePaths`.
16280
+ filePatterns: [
16281
+ ".claude/agents/orchestrator.md",
16282
+ ".claude/scheduled-tasks/**"
16283
+ ],
16260
16284
  content: buildOrchestratorConventionsContent(
16261
16285
  DEFAULT_AGENT_TIERS,
16262
16286
  resolveScopeGate(),
@@ -16265,7 +16289,6 @@ var orchestratorBundle = {
16265
16289
  resolveUnblockDependents()
16266
16290
  ),
16267
16291
  platforms: {
16268
- claude: { target: "claude-md" },
16269
16292
  cursor: { exclude: true }
16270
16293
  },
16271
16294
  tags: ["workflow"]
@@ -18836,7 +18859,15 @@ function buildPrReviewBundle(policy = resolvePrReviewPolicy()) {
18836
18859
  {
18837
18860
  name: "pr-review-policy",
18838
18861
  description: "Declarative policy that tells the pr-reviewer which PRs may auto-merge and which must wait for a human reviewer",
18839
- scope: AGENT_RULE_SCOPE.ALWAYS,
18862
+ scope: AGENT_RULE_SCOPE.FILE_PATTERN,
18863
+ // Bundle defaults exclude paths into configulator's own source
18864
+ // (only meaningful when configulator is a workspace package).
18865
+ // codedrifters/packages restores them via
18866
+ // `agentConfig.additionalRulePaths`.
18867
+ filePatterns: [
18868
+ ".claude/agents/pr-reviewer.md",
18869
+ ".claude/skills/review-pr/**"
18870
+ ],
18840
18871
  content: [
18841
18872
  "# PR Review Policy",
18842
18873
  "",
@@ -19018,7 +19049,15 @@ function buildPrReviewBundle(policy = resolvePrReviewPolicy()) {
19018
19049
  {
19019
19050
  name: "pr-review-feedback-protocol",
19020
19051
  description: "Documents the human-in-the-loop feedback loop on PR review: reaction state machine, pushback resolution, fix-list comment format, sticky reviewer-notes comment, label glossary, and human-author opt-in flag.",
19021
- scope: AGENT_RULE_SCOPE.ALWAYS,
19052
+ scope: AGENT_RULE_SCOPE.FILE_PATTERN,
19053
+ // Bundle defaults exclude paths into configulator's own source
19054
+ // (only meaningful when configulator is a workspace package).
19055
+ // codedrifters/packages restores them via
19056
+ // `agentConfig.additionalRulePaths`.
19057
+ filePatterns: [
19058
+ ".claude/agents/pr-reviewer.md",
19059
+ ".claude/agents/issue-worker.md"
19060
+ ],
19022
19061
  content: [
19023
19062
  "# PR Review Feedback Protocol",
19024
19063
  "",
@@ -19253,6 +19292,10 @@ var projenBundle = {
19253
19292
  {
19254
19293
  name: "development-commands",
19255
19294
  description: "Projen development commands for building, testing, linting, and validating changes",
19295
+ // ALWAYS scope: developers ask "how do I build/test/lint?" from
19296
+ // anywhere in the repo, not only when editing projen config.
19297
+ // Consumers that want to narrow the load can override via
19298
+ // `agentConfig.additionalRulePaths` or `excludeRules`.
19256
19299
  scope: AGENT_RULE_SCOPE.ALWAYS,
19257
19300
  content: [
19258
19301
  "# Development Commands",
@@ -19961,7 +20004,8 @@ function buildRegulatoryResearchAnalystSubAgent(paths, issueDefaults) {
19961
20004
  "7. **Create or update the scope index page** at",
19962
20005
  " `<SCOPE_INDEX_PAGE>` so downstream regulations link back to a",
19963
20006
  " coherent landing page for the scope. Follow the",
19964
- " `stub-index-convention` rule: the body must carry a 1\u20132",
20007
+ " section-index-page contract in the `shared-editing-safety` rule:",
20008
+ " the body must carry a 1\u20132",
19965
20009
  " paragraph contextual summary plus a grouped, linked listing of",
19966
20010
  " every regulation in the scope (e.g. by jurisdiction). No body",
19967
20011
  " `# Heading` \u2014 the frontmatter `title:` already renders as the",
@@ -27446,7 +27490,8 @@ function buildStandardsResearchAnalystSubAgent(paths, issueDefaults) {
27446
27490
  " pages.",
27447
27491
  "",
27448
27492
  "4. **Write the overview page** at `<OVERVIEW_PAGE>`. Follow",
27449
- " the `stub-index-convention` rule: the body opens with a",
27493
+ " the section-index-page contract in the",
27494
+ " `shared-editing-safety` rule: the body opens with a",
27450
27495
  " 1\u20132 paragraph contextual summary of the standard and its",
27451
27496
  " versions, and the version pages, modules, and extensions",
27452
27497
  " sections below double as the grouped, linked listing of",
@@ -29279,6 +29324,62 @@ function bundleNameForWorkflowRule(ruleName) {
29279
29324
  );
29280
29325
  return entry?.bundle;
29281
29326
  }
29327
+ function buildConventionsRegistryRule(rules) {
29328
+ const entries = [];
29329
+ for (const rule of rules) {
29330
+ if (rule.scope !== AGENT_RULE_SCOPE.FILE_PATTERN) {
29331
+ continue;
29332
+ }
29333
+ if (rule.platforms?.claude?.exclude === true) {
29334
+ continue;
29335
+ }
29336
+ if (!rule.filePatterns || rule.filePatterns.length === 0) {
29337
+ continue;
29338
+ }
29339
+ entries.push(rule);
29340
+ }
29341
+ if (entries.length === 0) {
29342
+ return void 0;
29343
+ }
29344
+ entries.sort((a, b) => a.name.localeCompare(b.name));
29345
+ const lines = [
29346
+ "# Conventions Registry",
29347
+ "",
29348
+ "Each row below is a `FILE_PATTERN`-scoped convention rule that",
29349
+ "auto-loads on demand when the agent's current file matches one",
29350
+ "of the listed paths. Full rule bodies live under",
29351
+ "`.claude/rules/<slug>.md` so they only consume context when",
29352
+ "they apply. Consult the matching rule before doing work in any",
29353
+ "of the listed surfaces.",
29354
+ "",
29355
+ "| Rule | Auto-loads when editing | Purpose |",
29356
+ "| --- | --- | --- |"
29357
+ ];
29358
+ const MAX_PATTERNS_SHOWN = 3;
29359
+ for (const rule of entries) {
29360
+ const ruleLink = `[\`${rule.name}\`](.claude/rules/${rule.name}.md)`;
29361
+ const patterns = rule.filePatterns ?? [];
29362
+ let patternCell;
29363
+ if (patterns.length <= MAX_PATTERNS_SHOWN) {
29364
+ patternCell = patterns.map((p) => `\`${p}\``).join(", ");
29365
+ } else {
29366
+ const shown = patterns.slice(0, MAX_PATTERNS_SHOWN).map((p) => `\`${p}\``).join(", ");
29367
+ patternCell = `${shown}, \u2026 ([full list](.claude/rules/${rule.name}.md))`;
29368
+ }
29369
+ const purposeCell = rule.description.replace(/\s+/g, " ").replace(/\|/g, "\\|").trim();
29370
+ lines.push(`| ${ruleLink} | ${patternCell} | ${purposeCell} |`);
29371
+ }
29372
+ return {
29373
+ name: "conventions-registry",
29374
+ description: "Routing table for every FILE_PATTERN-scoped convention rule. Lists each rule's slug, the file patterns that auto-trigger it, and a one-line purpose so agents whose current file does not match any rule's paths: can still discover the full convention set.",
29375
+ scope: AGENT_RULE_SCOPE.ALWAYS,
29376
+ content: lines.join("\n"),
29377
+ platforms: {
29378
+ cursor: { exclude: true }
29379
+ },
29380
+ tags: ["workflow"]
29381
+ };
29382
+ }
29282
29383
  function buildAgentRegistryRule(bundles, paths) {
29283
29384
  const activeNames = new Set(bundles.map((b) => b.name));
29284
29385
  const rows = AGENT_REGISTRY_ENTRIES.filter(
@@ -31001,6 +31102,20 @@ ${extra}`
31001
31102
  }
31002
31103
  }
31003
31104
  }
31105
+ if (this.options.additionalRulePaths) {
31106
+ for (const [name, extraPaths] of Object.entries(
31107
+ this.options.additionalRulePaths
31108
+ )) {
31109
+ if (extraPaths.length === 0) continue;
31110
+ const existing = ruleMap.get(name);
31111
+ if (!existing) continue;
31112
+ if (existing.scope !== AGENT_RULE_SCOPE.FILE_PATTERN) continue;
31113
+ ruleMap.set(name, {
31114
+ ...existing,
31115
+ filePatterns: [...existing.filePatterns ?? [], ...extraPaths]
31116
+ });
31117
+ }
31118
+ }
31004
31119
  if (this.options.priorityRules && this.options.priorityRules.length > 0) {
31005
31120
  const issueLabelRule = ruleMap.get("issue-label-conventions");
31006
31121
  if (issueLabelRule) {
@@ -31207,9 +31322,6 @@ ${hook}`
31207
31322
  }
31208
31323
  }
31209
31324
  }
31210
- if (!hasAnyDocsEmittingBundle(excludedBundleNames)) {
31211
- ruleMap.delete("stub-index-convention");
31212
- }
31213
31325
  if (injectBundleHooks && resolvedIssueTemplatesForRules.enabled && hasDownstreamBundles) {
31214
31326
  for (const [ruleName, label] of ISSUE_TEMPLATES_BUNDLE_HOOKS) {
31215
31327
  const existing = ruleMap.get(ruleName);
@@ -31326,6 +31438,12 @@ ${meetingsSection}`;
31326
31438
  });
31327
31439
  }
31328
31440
  }
31441
+ const conventionsRegistryRule = buildConventionsRegistryRule(
31442
+ ruleMap.values()
31443
+ );
31444
+ if (conventionsRegistryRule) {
31445
+ ruleMap.set(conventionsRegistryRule.name, conventionsRegistryRule);
31446
+ }
31329
31447
  return [...ruleMap.values()].sort((a, b) => {
31330
31448
  if (a.name === "project-overview") return -1;
31331
31449
  if (b.name === "project-overview") return 1;
@@ -37560,7 +37678,6 @@ export {
37560
37678
  renderSkillEvalsRuleContent,
37561
37679
  renderSkillEvalsRunnerScript,
37562
37680
  renderSourceTierExamples,
37563
- renderStubIndexConventionRuleContent,
37564
37681
  renderTemporalFramingCheckerScript,
37565
37682
  renderTemporalFramingRuleContent,
37566
37683
  renderUnblockDependentsScript,