@codedrifters/configulator 0.0.294 → 0.0.296

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
@@ -1143,8 +1143,8 @@ function resolveIssueTemplates(config) {
1143
1143
  function validateIssueTemplatesConfig(config) {
1144
1144
  return resolveIssueTemplates(config);
1145
1145
  }
1146
- function renderIssueTemplatesRuleContent(it) {
1147
- if (!it.enabled) {
1146
+ function renderIssueTemplatesRuleContent(it, hasDownstreamBundles = true) {
1147
+ if (!it.enabled || !hasDownstreamBundles) {
1148
1148
  return [
1149
1149
  "# Issue Templates",
1150
1150
  "",
@@ -11294,6 +11294,238 @@ function assertValidStateFilePath(stateFilePath) {
11294
11294
  }
11295
11295
  }
11296
11296
 
11297
+ // src/agent/bundles/bundle-ownership.ts
11298
+ var BUNDLE_OWNERSHIP = {
11299
+ agenda: {
11300
+ typeLabels: ["agenda"],
11301
+ phaseLabelPrefixes: ["agenda:"],
11302
+ scheduledTaskIds: ["worker-agenda"],
11303
+ emitsDocs: true,
11304
+ downstreamIssueKinds: true
11305
+ },
11306
+ "bcm-writer": {
11307
+ typeLabels: ["bcm-document"],
11308
+ phaseLabelPrefixes: ["bcm:"],
11309
+ scheduledTaskIds: ["worker-bcm-writer"],
11310
+ emitsDocs: true,
11311
+ downstreamIssueKinds: true
11312
+ },
11313
+ "business-models": {
11314
+ typeLabels: ["business-model"],
11315
+ phaseLabelPrefixes: ["business-models:"],
11316
+ scheduledTaskIds: ["worker-business-models"],
11317
+ emitsDocs: true,
11318
+ downstreamIssueKinds: true
11319
+ },
11320
+ "company-profile": {
11321
+ typeLabels: ["company-profile"],
11322
+ phaseLabelPrefixes: ["company:"],
11323
+ scheduledTaskIds: ["worker-company-profile"],
11324
+ emitsDocs: true,
11325
+ downstreamIssueKinds: true
11326
+ },
11327
+ "customer-profile": {
11328
+ typeLabels: ["customer-profile"],
11329
+ phaseLabelPrefixes: ["customer:"],
11330
+ scheduledTaskIds: ["worker-customer-profile"],
11331
+ emitsDocs: true,
11332
+ downstreamIssueKinds: true
11333
+ },
11334
+ "docs-sync": {
11335
+ typeLabels: ["docs-sync"],
11336
+ phaseLabelPrefixes: ["docs-sync:"],
11337
+ scheduledTaskIds: ["worker-docs-sync"],
11338
+ emitsDocs: true,
11339
+ downstreamIssueKinds: true
11340
+ },
11341
+ "industry-discovery": {
11342
+ typeLabels: ["industry-discovery"],
11343
+ phaseLabelPrefixes: ["industry:"],
11344
+ scheduledTaskIds: ["worker-industry-discovery"],
11345
+ emitsDocs: true,
11346
+ downstreamIssueKinds: true
11347
+ },
11348
+ "maintenance-audit": {
11349
+ typeLabels: ["maintenance"],
11350
+ phaseLabelPrefixes: ["maint:"],
11351
+ scheduledTaskIds: ["worker-maintenance"],
11352
+ emitsDocs: false,
11353
+ downstreamIssueKinds: true
11354
+ },
11355
+ "meeting-analysis": {
11356
+ typeLabels: ["meeting-processing"],
11357
+ phaseLabelPrefixes: ["meeting:"],
11358
+ scheduledTaskIds: ["worker-meeting-analysis"],
11359
+ emitsDocs: true,
11360
+ downstreamIssueKinds: true
11361
+ },
11362
+ orchestrator: {
11363
+ // The orchestrator pipeline manager itself ships with the
11364
+ // `worker-orchestrator` scheduled task. It owns no `type:*` label
11365
+ // (it dispatches every type) and no phase-label prefix.
11366
+ typeLabels: [],
11367
+ phaseLabelPrefixes: [],
11368
+ scheduledTaskIds: ["worker-orchestrator"],
11369
+ emitsDocs: false,
11370
+ downstreamIssueKinds: false
11371
+ },
11372
+ "people-profile": {
11373
+ typeLabels: ["people-profile"],
11374
+ phaseLabelPrefixes: ["people:"],
11375
+ scheduledTaskIds: ["worker-people-profile"],
11376
+ emitsDocs: true,
11377
+ downstreamIssueKinds: true
11378
+ },
11379
+ "pr-review": {
11380
+ typeLabels: ["pr-review"],
11381
+ phaseLabelPrefixes: [],
11382
+ scheduledTaskIds: ["worker-pr-review"],
11383
+ emitsDocs: false,
11384
+ downstreamIssueKinds: false
11385
+ },
11386
+ "regulatory-research": {
11387
+ typeLabels: ["regulatory-research"],
11388
+ phaseLabelPrefixes: ["regulatory:"],
11389
+ scheduledTaskIds: ["worker-regulatory-research"],
11390
+ emitsDocs: true,
11391
+ downstreamIssueKinds: true
11392
+ },
11393
+ "requirements-analyst": {
11394
+ typeLabels: ["requirement"],
11395
+ phaseLabelPrefixes: ["req:"],
11396
+ scheduledTaskIds: ["worker-requirements-analyst"],
11397
+ emitsDocs: true,
11398
+ downstreamIssueKinds: true
11399
+ },
11400
+ "requirements-reviewer": {
11401
+ // Co-owns `type:requirement` with the analyst and writer; owns
11402
+ // the `req:review` and `req:deprecate` phase labels exactly.
11403
+ typeLabels: ["requirement"],
11404
+ phaseLabelPrefixes: ["req:review", "req:deprecate"],
11405
+ scheduledTaskIds: ["worker-requirements-reviewer"],
11406
+ emitsDocs: true,
11407
+ downstreamIssueKinds: true
11408
+ },
11409
+ "requirements-writer": {
11410
+ // Co-owns `type:requirement` with the analyst and reviewer; owns
11411
+ // the `req:write` phase label exactly.
11412
+ typeLabels: ["requirement"],
11413
+ phaseLabelPrefixes: ["req:write"],
11414
+ scheduledTaskIds: ["worker-requirements-writer"],
11415
+ emitsDocs: true,
11416
+ downstreamIssueKinds: true
11417
+ },
11418
+ "research-pipeline": {
11419
+ typeLabels: ["research"],
11420
+ phaseLabelPrefixes: ["research:"],
11421
+ scheduledTaskIds: ["worker-research"],
11422
+ emitsDocs: true,
11423
+ downstreamIssueKinds: true
11424
+ },
11425
+ "software-profile": {
11426
+ typeLabels: ["software-profile"],
11427
+ phaseLabelPrefixes: ["software:"],
11428
+ scheduledTaskIds: ["worker-software-profile"],
11429
+ emitsDocs: true,
11430
+ downstreamIssueKinds: true
11431
+ },
11432
+ "standards-research": {
11433
+ typeLabels: ["standards-research"],
11434
+ phaseLabelPrefixes: ["standards:"],
11435
+ scheduledTaskIds: ["worker-standards-research"],
11436
+ emitsDocs: true,
11437
+ downstreamIssueKinds: true
11438
+ }
11439
+ };
11440
+ function isTypeLabelOwnedByExcluded(typeLabel, excludedBundles) {
11441
+ if (excludedBundles.length === 0) {
11442
+ return false;
11443
+ }
11444
+ for (const bundleName of excludedBundles) {
11445
+ const ownership = BUNDLE_OWNERSHIP[bundleName];
11446
+ if (!ownership) {
11447
+ continue;
11448
+ }
11449
+ if (ownership.typeLabels.includes(typeLabel)) {
11450
+ const owners = findOwnersOfTypeLabel(typeLabel);
11451
+ const allExcluded = owners.every(
11452
+ (owner) => excludedBundles.includes(owner)
11453
+ );
11454
+ if (allExcluded) {
11455
+ return true;
11456
+ }
11457
+ }
11458
+ }
11459
+ return false;
11460
+ }
11461
+ function isPhaseLabelOwnedByExcluded(phaseLabel, excludedBundles) {
11462
+ if (excludedBundles.length === 0) {
11463
+ return false;
11464
+ }
11465
+ for (const bundleName of excludedBundles) {
11466
+ const ownership = BUNDLE_OWNERSHIP[bundleName];
11467
+ if (!ownership) {
11468
+ continue;
11469
+ }
11470
+ for (const entry of ownership.phaseLabelPrefixes) {
11471
+ if (entry.endsWith(":")) {
11472
+ if (phaseLabel.startsWith(entry)) {
11473
+ return true;
11474
+ }
11475
+ } else if (phaseLabel === entry) {
11476
+ return true;
11477
+ }
11478
+ }
11479
+ }
11480
+ return false;
11481
+ }
11482
+ function isScheduledTaskOwnedByExcluded(taskId, excludedBundles) {
11483
+ if (excludedBundles.length === 0) {
11484
+ return false;
11485
+ }
11486
+ for (const bundleName of excludedBundles) {
11487
+ const ownership = BUNDLE_OWNERSHIP[bundleName];
11488
+ if (!ownership) {
11489
+ continue;
11490
+ }
11491
+ if (ownership.scheduledTaskIds.includes(taskId)) {
11492
+ return true;
11493
+ }
11494
+ }
11495
+ return false;
11496
+ }
11497
+ function hasAnyDocsEmittingBundle(excludedBundles) {
11498
+ for (const [bundleName, ownership] of Object.entries(BUNDLE_OWNERSHIP)) {
11499
+ if (!ownership.emitsDocs) {
11500
+ continue;
11501
+ }
11502
+ if (!excludedBundles.includes(bundleName)) {
11503
+ return true;
11504
+ }
11505
+ }
11506
+ return false;
11507
+ }
11508
+ function hasAnyDownstreamIssueKindBundle(excludedBundles) {
11509
+ for (const [bundleName, ownership] of Object.entries(BUNDLE_OWNERSHIP)) {
11510
+ if (!ownership.downstreamIssueKinds) {
11511
+ continue;
11512
+ }
11513
+ if (!excludedBundles.includes(bundleName)) {
11514
+ return true;
11515
+ }
11516
+ }
11517
+ return false;
11518
+ }
11519
+ function findOwnersOfTypeLabel(typeLabel) {
11520
+ const owners = [];
11521
+ for (const [bundleName, ownership] of Object.entries(BUNDLE_OWNERSHIP)) {
11522
+ if (ownership.typeLabels.includes(typeLabel)) {
11523
+ owners.push(bundleName);
11524
+ }
11525
+ }
11526
+ return owners;
11527
+ }
11528
+
11297
11529
  // src/agent/bundles/scheduled-tasks.ts
11298
11530
  var SCHEDULED_TASK_MODEL_VALUES = ["opus", "sonnet", "haiku"];
11299
11531
  var SCHEDULED_TASK_KIND_VALUES = ["issue-worker", "pipeline"];
@@ -11558,17 +11790,23 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11558
11790
  description: "Documentation-sync drift-detection and audit pipeline (scaffolding release \u2014 behavior carried by downstream child issues of the parent docs-sync epic)."
11559
11791
  }
11560
11792
  ];
11561
- function resolveScheduledTasks(config) {
11793
+ function resolveScheduledTasks(config, excludeBundles = []) {
11562
11794
  const root = config?.root ?? DEFAULT_SCHEDULED_TASKS_ROOT;
11563
11795
  assertValidRoot(root);
11564
11796
  const merged = /* @__PURE__ */ new Map();
11565
11797
  for (const entry of DEFAULT_SCHEDULED_TASK_ENTRIES) {
11798
+ if (isScheduledTaskOwnedByExcluded(entry.taskId, excludeBundles)) {
11799
+ continue;
11800
+ }
11566
11801
  merged.set(entry.taskId, entry);
11567
11802
  }
11568
11803
  if (config?.overrides) {
11569
11804
  for (const [taskId, override] of Object.entries(config.overrides)) {
11570
11805
  const existing = merged.get(taskId);
11571
11806
  if (!existing) {
11807
+ if (isScheduledTaskOwnedByExcluded(taskId, excludeBundles)) {
11808
+ continue;
11809
+ }
11572
11810
  throw new Error(
11573
11811
  `ScheduledTasksConfig.overrides references unknown taskId ${JSON.stringify(
11574
11812
  taskId
@@ -11599,8 +11837,8 @@ function resolveScheduledTasks(config) {
11599
11837
  tasks: [...merged.values()]
11600
11838
  };
11601
11839
  }
11602
- function validateScheduledTasksConfig(config) {
11603
- return resolveScheduledTasks(config);
11840
+ function validateScheduledTasksConfig(config, excludeBundles = []) {
11841
+ return resolveScheduledTasks(config, excludeBundles);
11604
11842
  }
11605
11843
  function renderScheduledTasksSection(resolved) {
11606
11844
  const lines = [
@@ -12083,7 +12321,7 @@ function classifyIssueScope(body, gate, labels = []) {
12083
12321
  matchedLabel: effective.matchedLabel
12084
12322
  };
12085
12323
  }
12086
- function renderScopeGateSection(gate) {
12324
+ function renderScopeGateSection(gate, excludeBundles = []) {
12087
12325
  const { acceptanceCriteria: ac, sources } = gate;
12088
12326
  const lines = [
12089
12327
  "## Scope gate",
@@ -12157,7 +12395,9 @@ function renderScopeGateSection(gate) {
12157
12395
  " is in place."
12158
12396
  );
12159
12397
  }
12160
- const overrideEntries = Object.entries(gate.bundleOverrides);
12398
+ const overrideEntries = Object.entries(gate.bundleOverrides).filter(
12399
+ ([label]) => !isPhaseLabelOwnedByExcluded(label, excludeBundles)
12400
+ );
12161
12401
  if (overrideEntries.length > 0) {
12162
12402
  lines.push(
12163
12403
  "",
@@ -12501,9 +12741,12 @@ function validateAgentTierConfig(config) {
12501
12741
  }
12502
12742
  return resolveAgentTiers(config);
12503
12743
  }
12504
- function renderAgentTierSection(tiers) {
12744
+ function renderAgentTierSection(tiers, excludeBundles = []) {
12745
+ const filtered = tiers.filter(
12746
+ (entry) => !isTypeLabelOwnedByExcluded(entry.type, excludeBundles)
12747
+ );
12505
12748
  const grouped = /* @__PURE__ */ new Map();
12506
- for (const entry of tiers) {
12749
+ for (const entry of filtered) {
12507
12750
  const bucket = grouped.get(entry.tier) ?? [];
12508
12751
  bucket.push(entry);
12509
12752
  grouped.set(entry.tier, bucket);
@@ -14234,13 +14477,13 @@ var ORCHESTRATOR_CONVENTIONS_PREAMBLE = [
14234
14477
  "",
14235
14478
  'Practical implication for scheduled-task wiring: the `worker-orchestrator` scheduled task\'s `SKILL.md` instructs the **scheduled-task session itself** to read `.claude/agents/orchestrator.md` and execute its phase pipeline in-session, then use the `Agent` tool to delegate the picked work item to `issue-worker` (depth-1). The scheduled task does **not** call `Agent(subagent_type: "orchestrator")` \u2014 that would put the orchestrator at depth-1 and break the chain.'
14236
14479
  ].join("\n");
14237
- function buildOrchestratorConventionsContent(tiers, scopeGate = resolveScopeGate(), runRatio = resolveRunRatio(), scheduledTasks = resolveScheduledTasks(), unblockDependents = resolveUnblockDependents()) {
14480
+ function buildOrchestratorConventionsContent(tiers, scopeGate = resolveScopeGate(), runRatio = resolveRunRatio(), scheduledTasks = resolveScheduledTasks(), unblockDependents = resolveUnblockDependents(), excludeBundles = []) {
14238
14481
  return [
14239
14482
  ORCHESTRATOR_CONVENTIONS_PREAMBLE,
14240
14483
  "",
14241
- renderAgentTierSection(tiers),
14484
+ renderAgentTierSection(tiers, excludeBundles),
14242
14485
  "",
14243
- renderScopeGateSection(scopeGate),
14486
+ renderScopeGateSection(scopeGate, excludeBundles),
14244
14487
  "",
14245
14488
  renderRunRatioSection(runRatio),
14246
14489
  "",
@@ -14249,11 +14492,14 @@ function buildOrchestratorConventionsContent(tiers, scopeGate = resolveScopeGate
14249
14492
  renderUnblockDependentsSection(unblockDependents)
14250
14493
  ].join("\n");
14251
14494
  }
14252
- function resolveOrchestratorAssets(tierConfig, scopeGateConfig, runRatioConfig, scheduledTasksConfig, unblockDependentsConfig) {
14495
+ function resolveOrchestratorAssets(tierConfig, scopeGateConfig, runRatioConfig, scheduledTasksConfig, unblockDependentsConfig, excludeBundles = []) {
14253
14496
  const tiers = resolveAgentTiers(tierConfig);
14254
14497
  const scopeGate = resolveScopeGate(scopeGateConfig);
14255
14498
  const runRatio = resolveRunRatio(runRatioConfig);
14256
- const scheduledTasks = resolveScheduledTasks(scheduledTasksConfig);
14499
+ const scheduledTasks = resolveScheduledTasks(
14500
+ scheduledTasksConfig,
14501
+ excludeBundles
14502
+ );
14257
14503
  const unblockDependentsResolved = resolveUnblockDependents(
14258
14504
  unblockDependentsConfig
14259
14505
  );
@@ -14268,7 +14514,8 @@ function resolveOrchestratorAssets(tierConfig, scopeGateConfig, runRatioConfig,
14268
14514
  scopeGate,
14269
14515
  runRatio,
14270
14516
  scheduledTasks,
14271
- unblockDependentsResolved
14517
+ unblockDependentsResolved,
14518
+ excludeBundles
14272
14519
  ),
14273
14520
  procedure: buildCheckBlockedProcedure(tiers, scopeGate, runRatio),
14274
14521
  unblockDependentsProcedure: buildUnblockDependentsProcedure(
@@ -26544,7 +26791,7 @@ var VERSION = {
26544
26791
  /**
26545
26792
  * Version of Astro to pin for AstroProject scaffolding.
26546
26793
  */
26547
- ASTRO_VERSION: "6.2.1",
26794
+ ASTRO_VERSION: "6.2.2",
26548
26795
  /**
26549
26796
  * CDK CLI for workflows and command line operations.
26550
26797
  *
@@ -26573,7 +26820,7 @@ var VERSION = {
26573
26820
  /**
26574
26821
  * Version of PNPM to use in workflows at github actions.
26575
26822
  */
26576
- PNPM_VERSION: "10.33.2",
26823
+ PNPM_VERSION: "10.33.3",
26577
26824
  /**
26578
26825
  * Version of Projen to use.
26579
26826
  */
@@ -26591,11 +26838,11 @@ var VERSION = {
26591
26838
  /**
26592
26839
  * Version of @astrojs/starlight to pin for StarlightProject scaffolding.
26593
26840
  */
26594
- STARLIGHT_VERSION: "0.38.4",
26841
+ STARLIGHT_VERSION: "0.38.5",
26595
26842
  /**
26596
26843
  * What version of the turborepo library should we use?
26597
26844
  */
26598
- TURBO_VERSION: "2.9.8",
26845
+ TURBO_VERSION: "2.9.9",
26599
26846
  /**
26600
26847
  * Version of @types/node to use across all packages (pnpm catalog).
26601
26848
  */
@@ -28043,7 +28290,8 @@ var AgentConfig = class _AgentConfig extends Component8 {
28043
28290
  this.project.gitignore.addPatterns(`/${resolvedProgressFiles.stateDir}/`);
28044
28291
  }
28045
28292
  const resolvedScheduledTasks = validateScheduledTasksConfig(
28046
- this.options.scheduledTasks
28293
+ this.options.scheduledTasks,
28294
+ this.options.excludeBundles ?? []
28047
28295
  );
28048
28296
  if (resolvedScheduledTasks.enabled) {
28049
28297
  for (const task of resolvedScheduledTasks.tasks) {
@@ -28251,7 +28499,8 @@ ${section}`
28251
28499
  }
28252
28500
  }
28253
28501
  }
28254
- if (this.options.tiers || this.options.scopeGate || this.options.runRatio || this.options.scheduledTasks || this.options.unblockDependents) {
28502
+ const excludedBundleNames = this.options.excludeBundles ?? [];
28503
+ if (this.options.tiers || this.options.scopeGate || this.options.runRatio || this.options.scheduledTasks || this.options.unblockDependents || excludedBundleNames.length > 0) {
28255
28504
  const orchestratorRule = ruleMap.get("orchestrator-conventions");
28256
28505
  if (orchestratorRule) {
28257
28506
  const { conventionsContent } = resolveOrchestratorAssets(
@@ -28259,7 +28508,8 @@ ${section}`
28259
28508
  this.options.scopeGate,
28260
28509
  this.options.runRatio,
28261
28510
  this.options.scheduledTasks,
28262
- this.options.unblockDependents
28511
+ this.options.unblockDependents,
28512
+ excludedBundleNames
28263
28513
  );
28264
28514
  if (conventionsContent !== orchestratorRule.content) {
28265
28515
  ruleMap.set("orchestrator-conventions", {
@@ -28392,11 +28642,13 @@ ${hook}`
28392
28642
  const resolvedIssueTemplatesForRules = resolveIssueTemplates(
28393
28643
  this.options.issueTemplates
28394
28644
  );
28395
- if (this.options.issueTemplates) {
28645
+ const hasDownstreamBundles = hasAnyDownstreamIssueKindBundle(excludedBundleNames);
28646
+ if (this.options.issueTemplates || !hasDownstreamBundles) {
28396
28647
  const issueTemplatesRule = ruleMap.get("issue-templates-convention");
28397
28648
  if (issueTemplatesRule) {
28398
28649
  const issueTemplatesContent = renderIssueTemplatesRuleContent(
28399
- resolvedIssueTemplatesForRules
28650
+ resolvedIssueTemplatesForRules,
28651
+ hasDownstreamBundles
28400
28652
  );
28401
28653
  if (issueTemplatesContent !== issueTemplatesRule.content) {
28402
28654
  ruleMap.set("issue-templates-convention", {
@@ -28406,7 +28658,10 @@ ${hook}`
28406
28658
  }
28407
28659
  }
28408
28660
  }
28409
- if (resolvedIssueTemplatesForRules.enabled) {
28661
+ if (!hasAnyDocsEmittingBundle(excludedBundleNames)) {
28662
+ ruleMap.delete("stub-index-convention");
28663
+ }
28664
+ if (resolvedIssueTemplatesForRules.enabled && hasDownstreamBundles) {
28410
28665
  for (const [ruleName, label] of ISSUE_TEMPLATES_BUNDLE_HOOKS) {
28411
28666
  const existing = ruleMap.get(ruleName);
28412
28667
  if (!existing) {
@@ -32908,6 +33163,7 @@ export {
32908
33163
  AwsDeploymentTarget,
32909
33164
  AwsTeardownWorkflow,
32910
33165
  BUILT_IN_BUNDLES,
33166
+ BUNDLE_OWNERSHIP,
32911
33167
  CLAUDE_RULE_TARGET,
32912
33168
  COMPLETE_JOB_ID,
32913
33169
  DEFAULT_AC_THRESHOLDS,
@@ -33051,7 +33307,12 @@ export {
33051
33307
  formatStarlightSingletonViolation,
33052
33308
  getLatestEligibleVersion,
33053
33309
  githubWorkflowBundle,
33310
+ hasAnyDocsEmittingBundle,
33311
+ hasAnyDownstreamIssueKindBundle,
33054
33312
  industryDiscoveryBundle,
33313
+ isPhaseLabelOwnedByExcluded,
33314
+ isScheduledTaskOwnedByExcluded,
33315
+ isTypeLabelOwnedByExcluded,
33055
33316
  jestBundle,
33056
33317
  labelsForPhase,
33057
33318
  maintenanceAuditBundle,