@codedrifters/configulator 0.0.406 → 0.0.408
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.d.mts +2141 -1891
- package/lib/index.d.ts +2142 -1892
- package/lib/index.js +609 -223
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +599 -223
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -223,6 +223,7 @@ __export(index_exports, {
|
|
|
223
223
|
DEFAULT_API_EXTRACTOR_REPORT_FILENAME: () => DEFAULT_API_EXTRACTOR_REPORT_FILENAME,
|
|
224
224
|
DEFAULT_API_EXTRACTOR_REPORT_FOLDER: () => DEFAULT_API_EXTRACTOR_REPORT_FOLDER,
|
|
225
225
|
DEFAULT_AUDIT_REPORT_DIR: () => DEFAULT_AUDIT_REPORT_DIR,
|
|
226
|
+
DEFAULT_BASE_CONVENTIONS: () => DEFAULT_BASE_CONVENTIONS,
|
|
226
227
|
DEFAULT_BUILD_POLICY: () => DEFAULT_BUILD_POLICY,
|
|
227
228
|
DEFAULT_BUNDLE_OVERRIDES: () => DEFAULT_BUNDLE_OVERRIDES,
|
|
228
229
|
DEFAULT_DECOMPOSITION_TEMPLATE: () => DEFAULT_DECOMPOSITION_TEMPLATE,
|
|
@@ -239,6 +240,7 @@ __export(index_exports, {
|
|
|
239
240
|
DEFAULT_ISSUE_TEMPLATES_PATH: () => DEFAULT_ISSUE_TEMPLATES_PATH,
|
|
240
241
|
DEFAULT_ISSUE_TEMPLATES_REQUIRE_REFERENCE: () => DEFAULT_ISSUE_TEMPLATES_REQUIRE_REFERENCE,
|
|
241
242
|
DEFAULT_OFF_PEAK_CRON_EXAMPLE: () => DEFAULT_OFF_PEAK_CRON_EXAMPLE,
|
|
243
|
+
DEFAULT_ORCHESTRATOR_CONVENTIONS: () => DEFAULT_ORCHESTRATOR_CONVENTIONS,
|
|
242
244
|
DEFAULT_PARTIAL_UNBLOCK_COMMENT_TEMPLATE: () => DEFAULT_PARTIAL_UNBLOCK_COMMENT_TEMPLATE,
|
|
243
245
|
DEFAULT_PATHS_EXEMPT_FROM_SIZE: () => DEFAULT_PATHS_EXEMPT_FROM_SIZE,
|
|
244
246
|
DEFAULT_PRIORITY_LABELS: () => DEFAULT_PRIORITY_LABELS,
|
|
@@ -251,6 +253,7 @@ __export(index_exports, {
|
|
|
251
253
|
DEFAULT_REQUIREMENT_CATEGORY_DIRS: () => DEFAULT_REQUIREMENT_CATEGORY_DIRS,
|
|
252
254
|
DEFAULT_REQUIRE_PRODUCT_CONTEXT: () => DEFAULT_REQUIRE_PRODUCT_CONTEXT,
|
|
253
255
|
DEFAULT_RESOLVED_ISSUE_DEFAULTS: () => DEFAULT_RESOLVED_ISSUE_DEFAULTS,
|
|
256
|
+
DEFAULT_RULE_CONVENTIONS: () => DEFAULT_RULE_CONVENTIONS,
|
|
254
257
|
DEFAULT_SAMPLE_COMPILER_OPTIONS: () => DEFAULT_SAMPLE_COMPILER_OPTIONS,
|
|
255
258
|
DEFAULT_SCHEDULED_TASKS_ROOT: () => DEFAULT_SCHEDULED_TASKS_ROOT,
|
|
256
259
|
DEFAULT_SCHEDULED_TASK_ENTRIES: () => DEFAULT_SCHEDULED_TASK_ENTRIES,
|
|
@@ -277,6 +280,7 @@ __export(index_exports, {
|
|
|
277
280
|
DOCS_SYNC_AUDIT_SCHEMA_VERSION: () => DOCS_SYNC_AUDIT_SCHEMA_VERSION,
|
|
278
281
|
GITHUB_ISSUE_TYPES: () => GITHUB_ISSUE_TYPES,
|
|
279
282
|
GITHUB_ISSUE_TYPE_BY_TITLE_PREFIX: () => GITHUB_ISSUE_TYPE_BY_TITLE_PREFIX,
|
|
283
|
+
ISSUE_TEMPLATES_GENERATED_SUFFIX: () => ISSUE_TEMPLATES_GENERATED_SUFFIX,
|
|
280
284
|
JsiiFaker: () => JsiiFaker,
|
|
281
285
|
LAYOUT_ENFORCEMENT: () => LAYOUT_ENFORCEMENT,
|
|
282
286
|
LAYOUT_ROOT_BY_PROJECT_TYPE: () => LAYOUT_ROOT_BY_PROJECT_TYPE,
|
|
@@ -353,6 +357,7 @@ __export(index_exports, {
|
|
|
353
357
|
buildIndustryDiscoveryBundle: () => buildIndustryDiscoveryBundle,
|
|
354
358
|
buildMaintenanceAuditBundle: () => buildMaintenanceAuditBundle,
|
|
355
359
|
buildMeetingAnalysisBundle: () => buildMeetingAnalysisBundle,
|
|
360
|
+
buildOrchestratorBundle: () => buildOrchestratorBundle,
|
|
356
361
|
buildOrchestratorConventionsContent: () => buildOrchestratorConventionsContent,
|
|
357
362
|
buildPeopleProfileBundle: () => buildPeopleProfileBundle,
|
|
358
363
|
buildPrReviewBundle: () => buildPrReviewBundle,
|
|
@@ -372,6 +377,7 @@ __export(index_exports, {
|
|
|
372
377
|
checkLinksProcedure: () => checkLinksProcedure,
|
|
373
378
|
classifyIssueScope: () => classifyIssueScope,
|
|
374
379
|
classifyRun: () => classifyRun,
|
|
380
|
+
collectIssueTemplateRecipeStubs: () => collectIssueTemplateRecipeStubs,
|
|
375
381
|
companyProfileBundle: () => companyProfileBundle,
|
|
376
382
|
compileFencedSamples: () => compileFencedSamples,
|
|
377
383
|
createApiDiffCheck: () => createApiDiffCheck,
|
|
@@ -397,6 +403,8 @@ __export(index_exports, {
|
|
|
397
403
|
isScheduledTaskOwnedByExcluded: () => isScheduledTaskOwnedByExcluded,
|
|
398
404
|
isSuppressedWorkflowRule: () => isSuppressedWorkflowRule,
|
|
399
405
|
isTypeLabelOwnedByExcluded: () => isTypeLabelOwnedByExcluded,
|
|
406
|
+
issueTemplatesChildGlob: () => issueTemplatesChildGlob,
|
|
407
|
+
issueTemplatesGeneratedPath: () => issueTemplatesGeneratedPath,
|
|
400
408
|
jestBundle: () => jestBundle,
|
|
401
409
|
labelsForPhase: () => labelsForPhase,
|
|
402
410
|
maintenanceAuditBundle: () => maintenanceAuditBundle,
|
|
@@ -447,8 +455,10 @@ __export(index_exports, {
|
|
|
447
455
|
renderFocusSection: () => renderFocusSection,
|
|
448
456
|
renderGithubIssueTypeSection: () => renderGithubIssueTypeSection,
|
|
449
457
|
renderGithubIssueTypeSectionLines: () => renderGithubIssueTypeSectionLines,
|
|
458
|
+
renderIssueTemplateLabelsCheckerScript: () => renderIssueTemplateLabelsCheckerScript,
|
|
450
459
|
renderIssueTemplatesBundleHook: () => renderIssueTemplatesBundleHook,
|
|
451
460
|
renderIssueTemplatesCheckerScript: () => renderIssueTemplatesCheckerScript,
|
|
461
|
+
renderIssueTemplatesGeneratedPage: () => renderIssueTemplatesGeneratedPage,
|
|
452
462
|
renderIssueTemplatesRuleContent: () => renderIssueTemplatesRuleContent,
|
|
453
463
|
renderIssueTemplatesStarterPage: () => renderIssueTemplatesStarterPage,
|
|
454
464
|
renderIssueTypeAssignmentBlanket: () => renderIssueTypeAssignmentBlanket,
|
|
@@ -2199,12 +2209,111 @@ var awsCdkBundle = {
|
|
|
2199
2209
|
]
|
|
2200
2210
|
};
|
|
2201
2211
|
|
|
2212
|
+
// src/agent/bundles/issue-defaults.ts
|
|
2213
|
+
var VALID_STATUS_VALUES = [
|
|
2214
|
+
"ready",
|
|
2215
|
+
"blocked",
|
|
2216
|
+
"in-progress",
|
|
2217
|
+
"ready-for-review",
|
|
2218
|
+
"needs-attention",
|
|
2219
|
+
"done",
|
|
2220
|
+
"deferred"
|
|
2221
|
+
];
|
|
2222
|
+
var VALID_PRIORITY_VALUES = [
|
|
2223
|
+
"critical",
|
|
2224
|
+
"high",
|
|
2225
|
+
"medium",
|
|
2226
|
+
"low",
|
|
2227
|
+
"trivial"
|
|
2228
|
+
];
|
|
2229
|
+
var DEFAULT_ISSUE_STATUS = "ready";
|
|
2230
|
+
var DEFAULT_ISSUE_PRIORITY = "medium";
|
|
2231
|
+
var DEFAULT_RESOLVED_ISSUE_DEFAULTS = {
|
|
2232
|
+
defaults: {
|
|
2233
|
+
status: DEFAULT_ISSUE_STATUS,
|
|
2234
|
+
priority: DEFAULT_ISSUE_PRIORITY
|
|
2235
|
+
},
|
|
2236
|
+
overrides: {}
|
|
2237
|
+
};
|
|
2238
|
+
function resolveIssueDefaults(config) {
|
|
2239
|
+
if (config === void 0) {
|
|
2240
|
+
return DEFAULT_RESOLVED_ISSUE_DEFAULTS;
|
|
2241
|
+
}
|
|
2242
|
+
const overrides = {};
|
|
2243
|
+
for (const [phaseLabel, override] of Object.entries(config)) {
|
|
2244
|
+
assertValidPhaseLabel(phaseLabel);
|
|
2245
|
+
assertValidOverride(phaseLabel, override);
|
|
2246
|
+
overrides[phaseLabel] = {
|
|
2247
|
+
status: override.status ?? DEFAULT_ISSUE_STATUS,
|
|
2248
|
+
priority: override.priority ?? DEFAULT_ISSUE_PRIORITY
|
|
2249
|
+
};
|
|
2250
|
+
}
|
|
2251
|
+
return {
|
|
2252
|
+
defaults: {
|
|
2253
|
+
status: DEFAULT_ISSUE_STATUS,
|
|
2254
|
+
priority: DEFAULT_ISSUE_PRIORITY
|
|
2255
|
+
},
|
|
2256
|
+
overrides
|
|
2257
|
+
};
|
|
2258
|
+
}
|
|
2259
|
+
function validateIssueDefaultsConfig(config) {
|
|
2260
|
+
return resolveIssueDefaults(config);
|
|
2261
|
+
}
|
|
2262
|
+
function labelsForPhase(resolved, phaseLabel) {
|
|
2263
|
+
return resolved.overrides[phaseLabel] ?? resolved.defaults;
|
|
2264
|
+
}
|
|
2265
|
+
function assertValidPhaseLabel(phaseLabel) {
|
|
2266
|
+
if (typeof phaseLabel !== "string" || phaseLabel.trim() === "") {
|
|
2267
|
+
throw new Error(
|
|
2268
|
+
"AgentConfigOptions.issueDefaults: phase-label keys must be non-empty strings (e.g. `people:research`)."
|
|
2269
|
+
);
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
2272
|
+
function assertValidOverride(phaseLabel, override) {
|
|
2273
|
+
if (override === null || typeof override !== "object" || Array.isArray(override)) {
|
|
2274
|
+
throw new Error(
|
|
2275
|
+
`AgentConfigOptions.issueDefaults["${phaseLabel}"] must be an object with optional \`status\` and \`priority\` fields.`
|
|
2276
|
+
);
|
|
2277
|
+
}
|
|
2278
|
+
const { status, priority } = override;
|
|
2279
|
+
if (status === void 0 && priority === void 0) {
|
|
2280
|
+
throw new Error(
|
|
2281
|
+
`AgentConfigOptions.issueDefaults["${phaseLabel}"] must declare at least one of \`status\` or \`priority\`. Empty entries are rejected because they are almost always a typo on the field name.`
|
|
2282
|
+
);
|
|
2283
|
+
}
|
|
2284
|
+
if (status !== void 0 && !VALID_STATUS_VALUES.includes(status)) {
|
|
2285
|
+
throw new Error(
|
|
2286
|
+
`AgentConfigOptions.issueDefaults["${phaseLabel}"].status="${status}" is not a recognised status value. Allowed values: ${VALID_STATUS_VALUES.join(", ")}.`
|
|
2287
|
+
);
|
|
2288
|
+
}
|
|
2289
|
+
if (priority !== void 0 && !VALID_PRIORITY_VALUES.includes(priority)) {
|
|
2290
|
+
throw new Error(
|
|
2291
|
+
`AgentConfigOptions.issueDefaults["${phaseLabel}"].priority="${priority}" is not a recognised priority value. Allowed values: ${VALID_PRIORITY_VALUES.join(", ")}.`
|
|
2292
|
+
);
|
|
2293
|
+
}
|
|
2294
|
+
}
|
|
2295
|
+
|
|
2202
2296
|
// src/agent/bundles/issue-templates.ts
|
|
2203
2297
|
var DEFAULT_ISSUE_TEMPLATES_ENABLED = true;
|
|
2204
2298
|
var DEFAULT_ISSUE_TEMPLATES_PATH = "docs/src/content/docs/agents/issue-templates.md";
|
|
2205
2299
|
var DEFAULT_ISSUE_TEMPLATES_BUNDLE_PATH_PATTERNS = [".claude/agents/**/*.md", ".claude/skills/**/*.md"];
|
|
2206
2300
|
var DEFAULT_ISSUE_TEMPLATES_EMIT_CHECKER = false;
|
|
2207
2301
|
var DEFAULT_ISSUE_TEMPLATES_EMIT_STARTER = false;
|
|
2302
|
+
var ISSUE_TEMPLATES_GENERATED_SUFFIX = "-generated";
|
|
2303
|
+
function issueTemplatesGeneratedPath(templatesPath) {
|
|
2304
|
+
const slash = templatesPath.lastIndexOf("/");
|
|
2305
|
+
const dot = templatesPath.lastIndexOf(".");
|
|
2306
|
+
if (dot > slash) {
|
|
2307
|
+
return `${templatesPath.slice(0, dot)}${ISSUE_TEMPLATES_GENERATED_SUFFIX}${templatesPath.slice(dot)}`;
|
|
2308
|
+
}
|
|
2309
|
+
return `${templatesPath}${ISSUE_TEMPLATES_GENERATED_SUFFIX}`;
|
|
2310
|
+
}
|
|
2311
|
+
function issueTemplatesChildGlob(templatesPath) {
|
|
2312
|
+
const slash = templatesPath.lastIndexOf("/");
|
|
2313
|
+
const dot = templatesPath.lastIndexOf(".");
|
|
2314
|
+
const stem = dot > slash ? templatesPath.slice(0, dot) : templatesPath;
|
|
2315
|
+
return `${stem}/*.md`;
|
|
2316
|
+
}
|
|
2208
2317
|
var DEFAULT_ISSUE_TEMPLATES_REQUIRE_REFERENCE = true;
|
|
2209
2318
|
function resolveIssueTemplates(config) {
|
|
2210
2319
|
const templatesPath = config?.templatesPath ?? DEFAULT_ISSUE_TEMPLATES_PATH;
|
|
@@ -2288,7 +2397,40 @@ function renderIssueTemplatesRuleContent(it, hasDownstreamBundles = true) {
|
|
|
2288
2397
|
"issue kind appends one section; retiring a kind removes one. The",
|
|
2289
2398
|
"label taxonomy, body template shape, and placeholder conventions",
|
|
2290
2399
|
"are shared across every section.",
|
|
2291
|
-
""
|
|
2400
|
+
""
|
|
2401
|
+
];
|
|
2402
|
+
if (it.emitStarterDoc) {
|
|
2403
|
+
lines.push(
|
|
2404
|
+
"## Scaffolded Starting Point",
|
|
2405
|
+
"",
|
|
2406
|
+
"The page is hand-authored, but it does not start empty. Two files",
|
|
2407
|
+
"ship together:",
|
|
2408
|
+
"",
|
|
2409
|
+
`1. \`${it.templatesPath}\` \u2014 **written once**, then yours. Titles,`,
|
|
2410
|
+
" bodies, and the callers list are hand-authored here and never",
|
|
2411
|
+
" overwritten.",
|
|
2412
|
+
`2. \`${issueTemplatesGeneratedPath(it.templatesPath)}\` \u2014`,
|
|
2413
|
+
" **regenerated on every synth**. One",
|
|
2414
|
+
" `## Template: <phase-label>` stub per phase label the active",
|
|
2415
|
+
" bundles contribute to the label registry, with the phase label,",
|
|
2416
|
+
" the `type:<bundle>` label its owning bundle declares, and the",
|
|
2417
|
+
" configured `status:*` / `priority:*` defaults pre-filled.",
|
|
2418
|
+
"",
|
|
2419
|
+
"Only the **label set** is generated. Title and body stay",
|
|
2420
|
+
"angle-bracket placeholders, so the scaffold answers *which labels*",
|
|
2421
|
+
"without dictating *what the issue says*. Copy a stub into the",
|
|
2422
|
+
"hand-authored page, flesh out its body, and leave the label block",
|
|
2423
|
+
"as generated.",
|
|
2424
|
+
"",
|
|
2425
|
+
"The split is load-bearing. A write-once scaffold alone freezes",
|
|
2426
|
+
"every consumer on whatever skeleton shipped the day they adopted",
|
|
2427
|
+
"the convention \u2014 a new phase label minted upstream never reaches",
|
|
2428
|
+
"them. Regenerating the label half fixes that without ever",
|
|
2429
|
+
"clobbering an authored body.",
|
|
2430
|
+
""
|
|
2431
|
+
);
|
|
2432
|
+
}
|
|
2433
|
+
lines.push(
|
|
2292
2434
|
"## Reference-Don't-Inline Rule",
|
|
2293
2435
|
"",
|
|
2294
2436
|
`Every bundle rule, agent prompt, or skill instruction that files a`,
|
|
@@ -2359,8 +2501,12 @@ function renderIssueTemplatesRuleContent(it, hasDownstreamBundles = true) {
|
|
|
2359
2501
|
" placeholders (`<Organization Name>`, `<slug>`) that match",
|
|
2360
2502
|
" existing templates. Consistency across sections lets callers",
|
|
2361
2503
|
" substitute without re-reading the body every time.",
|
|
2504
|
+
"5. **Does the recipe assign a GitHub issue type?** `gh issue",
|
|
2505
|
+
" create` cannot set it and the `type:*` label does not either, so",
|
|
2506
|
+
" every section ends with the follow-up call. An issue that skips",
|
|
2507
|
+
" it stays untyped forever.",
|
|
2362
2508
|
""
|
|
2363
|
-
|
|
2509
|
+
);
|
|
2364
2510
|
if (it.emitChecker) {
|
|
2365
2511
|
lines.push(
|
|
2366
2512
|
"## Automated Lint",
|
|
@@ -2391,6 +2537,33 @@ function renderIssueTemplatesRuleContent(it, hasDownstreamBundles = true) {
|
|
|
2391
2537
|
"(which documents the conventional `gh issue create` call shape",
|
|
2392
2538
|
"as taxonomy, not a downstream template). All other bundle",
|
|
2393
2539
|
"files in the pattern set are in scope.",
|
|
2540
|
+
"",
|
|
2541
|
+
"### Recipe label correctness",
|
|
2542
|
+
"",
|
|
2543
|
+
"A companion lint,",
|
|
2544
|
+
"`.claude/procedures/check-issue-template-labels.sh`, checks the",
|
|
2545
|
+
"recipes themselves rather than where they live. It walks the",
|
|
2546
|
+
"templates page, its router-style child pages, and the generated",
|
|
2547
|
+
"label-set companion, and fails non-zero when a",
|
|
2548
|
+
"`## Template: <phase-label>` section:",
|
|
2549
|
+
"",
|
|
2550
|
+
"- never passes `--label <phase-label>` \u2014 the heading and the",
|
|
2551
|
+
" command disagree;",
|
|
2552
|
+
"- carries no `type:*` label, more than one, or one that is not",
|
|
2553
|
+
" the `type:<bundle>` label the phase label's owning bundle",
|
|
2554
|
+
" declares;",
|
|
2555
|
+
"- has no GitHub issue-type assignment step.",
|
|
2556
|
+
"",
|
|
2557
|
+
"```bash",
|
|
2558
|
+
".claude/procedures/check-issue-template-labels.sh",
|
|
2559
|
+
"```",
|
|
2560
|
+
"",
|
|
2561
|
+
"The phase-label \u2192 type-label pairing is generated from the same",
|
|
2562
|
+
"bundle-ownership map that drives `.github/labels.yml` and the",
|
|
2563
|
+
"orchestrator's invariant sweep, so a hand-edit can never",
|
|
2564
|
+
"reintroduce a mismatch the registry has already ruled out.",
|
|
2565
|
+
"Sections whose heading matches no bundle-owned phase label are",
|
|
2566
|
+
"skipped \u2014 consumer-specific labels are deliberately not policed.",
|
|
2394
2567
|
""
|
|
2395
2568
|
);
|
|
2396
2569
|
}
|
|
@@ -2399,8 +2572,10 @@ function renderIssueTemplatesRuleContent(it, hasDownstreamBundles = true) {
|
|
|
2399
2572
|
"",
|
|
2400
2573
|
"The convention intentionally does not:",
|
|
2401
2574
|
"",
|
|
2402
|
-
"- Auto-generate
|
|
2403
|
-
"
|
|
2575
|
+
"- Auto-generate recipe **bodies**. Only the label set is",
|
|
2576
|
+
" scaffolded, because labels are derivable from the bundle",
|
|
2577
|
+
" registry and bodies are not \u2014 repo-specific objectives,",
|
|
2578
|
+
" acceptance criteria, and callers lists stay hand-authored.",
|
|
2404
2579
|
"- Prescribe a fixed body shape across templates. Each section",
|
|
2405
2580
|
" may carry its own `## Acceptance Criteria`, `## Scope Size`,",
|
|
2406
2581
|
" or `## Output Path` fields as the downstream agent requires;",
|
|
@@ -2431,7 +2606,8 @@ function renderIssueTemplatesBundleHook(it, bundleLabel) {
|
|
|
2431
2606
|
"as an inline template vs. a prose mention."
|
|
2432
2607
|
].join("\n");
|
|
2433
2608
|
}
|
|
2434
|
-
function renderIssueTemplatesStarterPage(
|
|
2609
|
+
function renderIssueTemplatesStarterPage(it) {
|
|
2610
|
+
const generatedLink = `./${basename(issueTemplatesGeneratedPath(it.templatesPath))}`;
|
|
2435
2611
|
return [
|
|
2436
2612
|
"---",
|
|
2437
2613
|
"title: Issue Templates",
|
|
@@ -2466,6 +2642,20 @@ function renderIssueTemplatesStarterPage(_it) {
|
|
|
2466
2642
|
"bundle's rule \u2014 the issue-templates page is a recipe catalogue,",
|
|
2467
2643
|
"not a duplicate-check layer.",
|
|
2468
2644
|
"",
|
|
2645
|
+
"## Generated label sets",
|
|
2646
|
+
"",
|
|
2647
|
+
`[Generated Issue-Template Label Sets](${generatedLink}) carries one`,
|
|
2648
|
+
"correct-by-construction stub per phase label the active bundles",
|
|
2649
|
+
"emit \u2014 the phase label paired with the `type:<bundle>` label its",
|
|
2650
|
+
"owning bundle declares, plus the configured `status:*` /",
|
|
2651
|
+
"`priority:*` defaults. That page regenerates on every `projen` run,",
|
|
2652
|
+
"so it never goes stale as phase labels come and go.",
|
|
2653
|
+
"",
|
|
2654
|
+
"This page is the opposite: written once, then owned by you. Copy a",
|
|
2655
|
+
"stub across, flesh out its title and body here, and leave the label",
|
|
2656
|
+
"block exactly as generated \u2014 the label-consistency lint holds both",
|
|
2657
|
+
"copies to the same pairing.",
|
|
2658
|
+
"",
|
|
2469
2659
|
"## Template: example-phase",
|
|
2470
2660
|
"",
|
|
2471
2661
|
"Replace this example with the real templates for this repo. Each",
|
|
@@ -2505,6 +2695,115 @@ function renderIssueTemplatesStarterPage(_it) {
|
|
|
2505
2695
|
"```"
|
|
2506
2696
|
].join("\n");
|
|
2507
2697
|
}
|
|
2698
|
+
function collectIssueTemplateRecipeStubs(bundles, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS) {
|
|
2699
|
+
const stubs = /* @__PURE__ */ new Map();
|
|
2700
|
+
for (const bundle of bundles) {
|
|
2701
|
+
for (const label of bundle.labels ?? []) {
|
|
2702
|
+
const typeLabel = typeLabelForPhaseLabel(label.name);
|
|
2703
|
+
if (typeLabel === void 0) {
|
|
2704
|
+
continue;
|
|
2705
|
+
}
|
|
2706
|
+
if (stubs.has(label.name)) {
|
|
2707
|
+
continue;
|
|
2708
|
+
}
|
|
2709
|
+
const defaults = labelsForPhase(issueDefaults, label.name);
|
|
2710
|
+
stubs.set(label.name, {
|
|
2711
|
+
phaseLabel: label.name,
|
|
2712
|
+
typeLabel,
|
|
2713
|
+
bundleName: bundle.name,
|
|
2714
|
+
description: label.description ?? "",
|
|
2715
|
+
status: defaults.status,
|
|
2716
|
+
priority: defaults.priority,
|
|
2717
|
+
issueType: githubIssueTypeForTitle(`${label.name}: placeholder`)
|
|
2718
|
+
});
|
|
2719
|
+
}
|
|
2720
|
+
}
|
|
2721
|
+
return [...stubs.values()].sort(
|
|
2722
|
+
(a, b) => a.phaseLabel.localeCompare(b.phaseLabel)
|
|
2723
|
+
);
|
|
2724
|
+
}
|
|
2725
|
+
function renderIssueTemplatesGeneratedPage(it, stubs) {
|
|
2726
|
+
const lines = [
|
|
2727
|
+
"---",
|
|
2728
|
+
"title: Generated Issue-Template Label Sets",
|
|
2729
|
+
"description: Auto-generated label-correct gh issue create stubs \u2014 one per phase label.",
|
|
2730
|
+
"---",
|
|
2731
|
+
"",
|
|
2732
|
+
"**Generated file \u2014 do not edit.** Every section below is",
|
|
2733
|
+
"regenerated from the active bundle set on each `projen` run; hand",
|
|
2734
|
+
"edits are overwritten. The hand-authored recipes live in",
|
|
2735
|
+
`[the issue-templates page](./${basename(it.templatesPath)}) \u2014 this`,
|
|
2736
|
+
"page exists so the **label half** of every recipe stays",
|
|
2737
|
+
"correct-by-construction as phase labels come and go.",
|
|
2738
|
+
"",
|
|
2739
|
+
"## How to use",
|
|
2740
|
+
"",
|
|
2741
|
+
"Each section carries the exact label set the phase-label invariant",
|
|
2742
|
+
"requires: the phase label itself, the `type:<bundle>` label its",
|
|
2743
|
+
"owning bundle declares, and the configured `status:*` / `priority:*`",
|
|
2744
|
+
"defaults for that phase. Title and body are placeholders \u2014 copy the",
|
|
2745
|
+
"stub into the hand-authored templates page and flesh out the body",
|
|
2746
|
+
"there, or run it as-is when no repo-specific body exists yet.",
|
|
2747
|
+
"",
|
|
2748
|
+
"Every stub ends with the **GitHub issue type** assignment. `gh issue",
|
|
2749
|
+
"create` cannot set the issue type and the `type:*` label does not",
|
|
2750
|
+
"set it either, so an issue that skips the follow-up call stays",
|
|
2751
|
+
"untyped forever. See **Assigning the GitHub issue type** in the",
|
|
2752
|
+
"`issue-conventions` rule for the no-helper fallback.",
|
|
2753
|
+
""
|
|
2754
|
+
];
|
|
2755
|
+
if (stubs.length === 0) {
|
|
2756
|
+
lines.push(
|
|
2757
|
+
"## No phase labels",
|
|
2758
|
+
"",
|
|
2759
|
+
"No active bundle contributes a phase label, so there is nothing to",
|
|
2760
|
+
"scaffold. Enable a phased-pipeline bundle (or drop it from",
|
|
2761
|
+
"`excludeBundles`) and re-run `projen`."
|
|
2762
|
+
);
|
|
2763
|
+
return lines.join("\n");
|
|
2764
|
+
}
|
|
2765
|
+
for (const stub of stubs) {
|
|
2766
|
+
lines.push(
|
|
2767
|
+
`## Template: ${stub.phaseLabel}`,
|
|
2768
|
+
"",
|
|
2769
|
+
...stub.description === "" ? [] : [stub.description, ""],
|
|
2770
|
+
`**Owning bundle:** \`${stub.bundleName}\` \u2014 **required type label:**`,
|
|
2771
|
+
`\`${stub.typeLabel}\` (paired by the bundle-ownership map).`,
|
|
2772
|
+
"",
|
|
2773
|
+
"**Callers:** <name the bundles and agents that file this issue>",
|
|
2774
|
+
"",
|
|
2775
|
+
"```bash",
|
|
2776
|
+
"gh issue create \\",
|
|
2777
|
+
` --title "${stub.phaseLabel}: <short description>" \\`,
|
|
2778
|
+
` --label "${stub.typeLabel}" \\`,
|
|
2779
|
+
` --label "${stub.phaseLabel}" \\`,
|
|
2780
|
+
` --label "priority:${stub.priority}" \\`,
|
|
2781
|
+
` --label "status:${stub.status}" \\`,
|
|
2782
|
+
' --body "## Objective',
|
|
2783
|
+
"",
|
|
2784
|
+
"<1-3 sentences describing the work>.",
|
|
2785
|
+
"",
|
|
2786
|
+
"## Context",
|
|
2787
|
+
"",
|
|
2788
|
+
"- **Discovered in:** <source description> (#<parent-issue>)",
|
|
2789
|
+
"",
|
|
2790
|
+
"## Acceptance Criteria",
|
|
2791
|
+
"",
|
|
2792
|
+
"- [ ] <criterion 1>",
|
|
2793
|
+
'"',
|
|
2794
|
+
"```",
|
|
2795
|
+
"",
|
|
2796
|
+
`Then assign the GitHub issue type (\`${stub.issueType}\`):`,
|
|
2797
|
+
"",
|
|
2798
|
+
"```bash",
|
|
2799
|
+
`${SET_ISSUE_TYPE_HELPER_PATH} <issue-number> ${stub.issueType}`,
|
|
2800
|
+
"```",
|
|
2801
|
+
""
|
|
2802
|
+
);
|
|
2803
|
+
}
|
|
2804
|
+
lines.pop();
|
|
2805
|
+
return lines.join("\n");
|
|
2806
|
+
}
|
|
2508
2807
|
function renderIssueTemplatesCheckerScript(it) {
|
|
2509
2808
|
const patternsLiteral = it.bundlePathPatterns.map((p) => ` ${JSON.stringify(p)}`).join("\n");
|
|
2510
2809
|
return [
|
|
@@ -2693,6 +2992,157 @@ function renderIssueTemplatesCheckerScript(it) {
|
|
|
2693
2992
|
"exit 0"
|
|
2694
2993
|
].join("\n");
|
|
2695
2994
|
}
|
|
2995
|
+
function renderIssueTemplateLabelsCheckerScript(it) {
|
|
2996
|
+
const generatedPath = issueTemplatesGeneratedPath(it.templatesPath);
|
|
2997
|
+
const childGlob = issueTemplatesChildGlob(it.templatesPath);
|
|
2998
|
+
return [
|
|
2999
|
+
"#!/usr/bin/env bash",
|
|
3000
|
+
"# check-issue-template-labels.sh \u2014 Enforce recipe label correctness.",
|
|
3001
|
+
"#",
|
|
3002
|
+
"# Usage:",
|
|
3003
|
+
"# .claude/procedures/check-issue-template-labels.sh [<file>...]",
|
|
3004
|
+
"#",
|
|
3005
|
+
"# With no arguments the lint walks the templates page, its",
|
|
3006
|
+
"# router-style child pages, and the generated label-set companion.",
|
|
3007
|
+
"# Positional arguments override that default set.",
|
|
3008
|
+
"#",
|
|
3009
|
+
"# For every `## Template: <phase-label>` section it asserts the",
|
|
3010
|
+
"# recipe passes the heading's phase label, carries exactly one",
|
|
3011
|
+
"# `type:*` label matching the phase-label invariant, and assigns a",
|
|
3012
|
+
"# GitHub issue type. Sections whose heading matches no bundle-owned",
|
|
3013
|
+
"# phase label are skipped \u2014 unrecognised labels are consumer-",
|
|
3014
|
+
"# specific and deliberately not policed.",
|
|
3015
|
+
"#",
|
|
3016
|
+
"# The resolver below is generated from the canonical bundle-",
|
|
3017
|
+
"# ownership map \u2014 do not edit by hand; regenerate via",
|
|
3018
|
+
"# `pnpm exec projen`.",
|
|
3019
|
+
"",
|
|
3020
|
+
"set -uo pipefail",
|
|
3021
|
+
"",
|
|
3022
|
+
"err() {",
|
|
3023
|
+
' printf "check-issue-template-labels.sh: %s\\n" "$*" >&2',
|
|
3024
|
+
"}",
|
|
3025
|
+
"",
|
|
3026
|
+
renderPhaseTypeInvariantShellHelpers(),
|
|
3027
|
+
"",
|
|
3028
|
+
`templates_path=${JSON.stringify(it.templatesPath)}`,
|
|
3029
|
+
`generated_path=${JSON.stringify(generatedPath)}`,
|
|
3030
|
+
`child_glob=${JSON.stringify(childGlob)}`,
|
|
3031
|
+
"",
|
|
3032
|
+
"# Emit one TAB-separated record per `## Template:` section:",
|
|
3033
|
+
"# <file>\\t<line>\\t<phase-label>\\t<comma-joined labels>\\t<0|1 typed>",
|
|
3034
|
+
"# Quote characters are folded to spaces up front so a recipe written",
|
|
3035
|
+
"# with single quotes, double quotes, or none at all parses the same.",
|
|
3036
|
+
"# Fenced blocks are tracked so the `## Objective` heading inside a",
|
|
3037
|
+
"# recipe's --body string never reads as the end of the section.",
|
|
3038
|
+
"scan_file() {",
|
|
3039
|
+
' local file="$1"',
|
|
3040
|
+
` tr '\\042\\047' ' ' < "$file" | awk -v FNAME="$file" '`,
|
|
3041
|
+
" function flush() {",
|
|
3042
|
+
' if (phase != "") {',
|
|
3043
|
+
' printf "%s\\t%d\\t%s\\t%s\\t%d\\n", FNAME, start, phase, labels, hastype;',
|
|
3044
|
+
" }",
|
|
3045
|
+
' phase = ""; labels = ""; hastype = 0;',
|
|
3046
|
+
" }",
|
|
3047
|
+
" {",
|
|
3048
|
+
" if ($0 ~ /^[ \\t]*```/) {",
|
|
3049
|
+
" fence = 1 - fence;",
|
|
3050
|
+
' } else if (fence == 0 && index($0, "## ") == 1) {',
|
|
3051
|
+
" flush();",
|
|
3052
|
+
' if (index($0, "## Template: ") == 1) {',
|
|
3053
|
+
" phase = substr($0, 14);",
|
|
3054
|
+
' gsub(/[ \\t`]/, "", phase);',
|
|
3055
|
+
" start = NR;",
|
|
3056
|
+
" }",
|
|
3057
|
+
" next;",
|
|
3058
|
+
" }",
|
|
3059
|
+
' if (phase == "") next;',
|
|
3060
|
+
" if ($0 ~ /set-issue-type\\.sh/ || $0 ~ /updateIssueIssueType/) {",
|
|
3061
|
+
" hastype = 1;",
|
|
3062
|
+
" }",
|
|
3063
|
+
" line = $0;",
|
|
3064
|
+
" while (match(line, /--label[ \\t]+[^ \\t]+/)) {",
|
|
3065
|
+
" tok = substr(line, RSTART, RLENGTH);",
|
|
3066
|
+
" line = substr(line, RSTART + RLENGTH);",
|
|
3067
|
+
' sub(/^--label[ \\t]+/, "", tok);',
|
|
3068
|
+
' gsub(/[\\\\`]/, "", tok);',
|
|
3069
|
+
' labels = labels tok ",";',
|
|
3070
|
+
" }",
|
|
3071
|
+
" }",
|
|
3072
|
+
" END { flush(); }",
|
|
3073
|
+
" '",
|
|
3074
|
+
"}",
|
|
3075
|
+
"",
|
|
3076
|
+
"# Collect the file list: positional args override the default set.",
|
|
3077
|
+
"files=()",
|
|
3078
|
+
"if [[ $# -gt 0 ]]; then",
|
|
3079
|
+
' files=("$@")',
|
|
3080
|
+
"else",
|
|
3081
|
+
' [[ -f "$templates_path" ]] && files+=("$templates_path")',
|
|
3082
|
+
' [[ -f "$generated_path" ]] && files+=("$generated_path")',
|
|
3083
|
+
" for child in $child_glob; do",
|
|
3084
|
+
' [[ -f "$child" ]] && files+=("$child")',
|
|
3085
|
+
" done",
|
|
3086
|
+
"fi",
|
|
3087
|
+
"",
|
|
3088
|
+
"if [[ ${#files[@]} -eq 0 ]]; then",
|
|
3089
|
+
" exit 0",
|
|
3090
|
+
"fi",
|
|
3091
|
+
"",
|
|
3092
|
+
"violations=()",
|
|
3093
|
+
"checked=0",
|
|
3094
|
+
"",
|
|
3095
|
+
'for file in "${files[@]}"; do',
|
|
3096
|
+
' [[ -f "$file" ]] || continue',
|
|
3097
|
+
" while IFS=$'\\t' read -r rec_file rec_line phase labels hastype; do",
|
|
3098
|
+
' [[ -z "$phase" ]] && continue',
|
|
3099
|
+
' required=$(phase_label_type_of "$phase")',
|
|
3100
|
+
' [[ -z "$required" ]] && continue',
|
|
3101
|
+
" checked=$(( checked + 1 ))",
|
|
3102
|
+
' case ",${labels}" in',
|
|
3103
|
+
' *",${phase},"*) ;;',
|
|
3104
|
+
` *) violations+=("$rec_file:$rec_line: recipe for '$phase' never passes --label $phase") ;;`,
|
|
3105
|
+
" esac",
|
|
3106
|
+
' type_labels=""',
|
|
3107
|
+
" type_count=0",
|
|
3108
|
+
' for entry in $(printf "%s" "$labels" | tr , " "); do',
|
|
3109
|
+
' case "$entry" in',
|
|
3110
|
+
" type:*)",
|
|
3111
|
+
' type_labels="${type_labels}${entry} "',
|
|
3112
|
+
" type_count=$(( type_count + 1 ))",
|
|
3113
|
+
" ;;",
|
|
3114
|
+
" esac",
|
|
3115
|
+
" done",
|
|
3116
|
+
' if [[ "$type_count" -eq 0 ]]; then',
|
|
3117
|
+
` violations+=("$rec_file:$rec_line: recipe for '$phase' carries no type:* label (expected $required)")`,
|
|
3118
|
+
' elif [[ "$type_count" -gt 1 ]]; then',
|
|
3119
|
+
" violations+=(\"$rec_file:$rec_line: recipe for '$phase' carries ${type_count} type:* labels (${type_labels% }); exactly one is allowed\")",
|
|
3120
|
+
' elif [[ "${type_labels% }" != "$required" ]]; then',
|
|
3121
|
+
` violations+=("$rec_file:$rec_line: recipe for '$phase' carries \${type_labels% } but the phase label requires $required")`,
|
|
3122
|
+
" fi",
|
|
3123
|
+
' if [[ "$hastype" != "1" ]]; then',
|
|
3124
|
+
` violations+=("$rec_file:$rec_line: recipe for '$phase' has no GitHub issue-type assignment step")`,
|
|
3125
|
+
" fi",
|
|
3126
|
+
' done < <(scan_file "$file")',
|
|
3127
|
+
"done",
|
|
3128
|
+
"",
|
|
3129
|
+
"if [[ ${#violations[@]} -gt 0 ]]; then",
|
|
3130
|
+
' err "issue-template recipes disagree with the phase-label invariant:"',
|
|
3131
|
+
' for v in "${violations[@]}"; do',
|
|
3132
|
+
' err " - $v"',
|
|
3133
|
+
" done",
|
|
3134
|
+
` err "each '## Template: <phase-label>' recipe must pass its own phase label, exactly one matching type:<bundle> label, and a set-issue-type.sh (or updateIssueIssueType) step"`,
|
|
3135
|
+
" exit 1",
|
|
3136
|
+
"fi",
|
|
3137
|
+
"",
|
|
3138
|
+
'printf "check-issue-template-labels.sh: %d recipe(s) OK\\n" "$checked"',
|
|
3139
|
+
"exit 0"
|
|
3140
|
+
].join("\n");
|
|
3141
|
+
}
|
|
3142
|
+
function basename(path8) {
|
|
3143
|
+
const slash = path8.lastIndexOf("/");
|
|
3144
|
+
return slash === -1 ? path8 : path8.slice(slash + 1);
|
|
3145
|
+
}
|
|
2696
3146
|
function assertValidTemplatesPath(value) {
|
|
2697
3147
|
if (typeof value !== "string" || value.trim().length === 0) {
|
|
2698
3148
|
throw new Error(
|
|
@@ -4956,7 +5406,15 @@ var createRuleSkill = {
|
|
|
4956
5406
|
"- Use `ruleExtensions` to add project-specific content to existing bundle rules instead of replacing them"
|
|
4957
5407
|
].join("\n")
|
|
4958
5408
|
};
|
|
4959
|
-
|
|
5409
|
+
var DEFAULT_BASE_CONVENTIONS = {
|
|
5410
|
+
progressFiles: resolveProgressFiles(),
|
|
5411
|
+
sharedEditing: resolveSharedEditing(),
|
|
5412
|
+
temporalFraming: resolveTemporalFraming(),
|
|
5413
|
+
skillEvals: resolveSkillEvals(),
|
|
5414
|
+
issueTemplates: resolveIssueTemplates(),
|
|
5415
|
+
hasDownstreamIssueKindBundles: true
|
|
5416
|
+
};
|
|
5417
|
+
function buildBaseBundle(paths = DEFAULT_AGENT_PATHS, conventions = DEFAULT_BASE_CONVENTIONS) {
|
|
4960
5418
|
return {
|
|
4961
5419
|
name: "base",
|
|
4962
5420
|
description: "Core rules: project overview, interaction style, and general coding conventions",
|
|
@@ -5625,7 +6083,7 @@ function buildBaseBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
|
5625
6083
|
// them via `agentConfig.additionalRulePaths`; other consumers
|
|
5626
6084
|
// get a clean default.
|
|
5627
6085
|
filePatterns: [".claude/agents/*.md", ".claude/procedures/**"],
|
|
5628
|
-
content: renderProgressFilesRuleContent(
|
|
6086
|
+
content: renderProgressFilesRuleContent(conventions.progressFiles),
|
|
5629
6087
|
platforms: {
|
|
5630
6088
|
cursor: { exclude: true }
|
|
5631
6089
|
},
|
|
@@ -5636,7 +6094,7 @@ function buildBaseBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
|
5636
6094
|
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.",
|
|
5637
6095
|
scope: AGENT_RULE_SCOPE.FILE_PATTERN,
|
|
5638
6096
|
filePatterns: DEFAULT_SHARED_INDEX_PATHS,
|
|
5639
|
-
content: renderSharedEditingRuleContent(
|
|
6097
|
+
content: renderSharedEditingRuleContent(conventions.sharedEditing),
|
|
5640
6098
|
platforms: {
|
|
5641
6099
|
cursor: { exclude: true }
|
|
5642
6100
|
},
|
|
@@ -5654,7 +6112,7 @@ function buildBaseBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
|
5654
6112
|
"docs/src/content/docs/standards-research/**/*.md",
|
|
5655
6113
|
"docs/src/content/docs/customer-research/**/*.md"
|
|
5656
6114
|
],
|
|
5657
|
-
content: renderTemporalFramingRuleContent(
|
|
6115
|
+
content: renderTemporalFramingRuleContent(conventions.temporalFraming),
|
|
5658
6116
|
platforms: {
|
|
5659
6117
|
cursor: { exclude: true }
|
|
5660
6118
|
},
|
|
@@ -5667,7 +6125,7 @@ function buildBaseBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
|
5667
6125
|
// Bundle defaults exclude paths into configulator's own
|
|
5668
6126
|
// source — see comment on progress-file-convention above.
|
|
5669
6127
|
filePatterns: [".claude/skills/**"],
|
|
5670
|
-
content: renderSkillEvalsRuleContent(
|
|
6128
|
+
content: renderSkillEvalsRuleContent(conventions.skillEvals),
|
|
5671
6129
|
platforms: {
|
|
5672
6130
|
cursor: { exclude: true }
|
|
5673
6131
|
},
|
|
@@ -5684,7 +6142,10 @@ function buildBaseBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
|
5684
6142
|
".claude/agents/*.md",
|
|
5685
6143
|
`${paths.docsRoot}/agents/issue-templates.md`
|
|
5686
6144
|
],
|
|
5687
|
-
content: renderIssueTemplatesRuleContent(
|
|
6145
|
+
content: renderIssueTemplatesRuleContent(
|
|
6146
|
+
conventions.issueTemplates,
|
|
6147
|
+
conventions.hasDownstreamIssueKindBundles
|
|
6148
|
+
),
|
|
5688
6149
|
platforms: {
|
|
5689
6150
|
cursor: { exclude: true }
|
|
5690
6151
|
},
|
|
@@ -5695,90 +6156,6 @@ function buildBaseBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
|
5695
6156
|
}
|
|
5696
6157
|
var baseBundle = buildBaseBundle();
|
|
5697
6158
|
|
|
5698
|
-
// src/agent/bundles/issue-defaults.ts
|
|
5699
|
-
var VALID_STATUS_VALUES = [
|
|
5700
|
-
"ready",
|
|
5701
|
-
"blocked",
|
|
5702
|
-
"in-progress",
|
|
5703
|
-
"ready-for-review",
|
|
5704
|
-
"needs-attention",
|
|
5705
|
-
"done",
|
|
5706
|
-
"deferred"
|
|
5707
|
-
];
|
|
5708
|
-
var VALID_PRIORITY_VALUES = [
|
|
5709
|
-
"critical",
|
|
5710
|
-
"high",
|
|
5711
|
-
"medium",
|
|
5712
|
-
"low",
|
|
5713
|
-
"trivial"
|
|
5714
|
-
];
|
|
5715
|
-
var DEFAULT_ISSUE_STATUS = "ready";
|
|
5716
|
-
var DEFAULT_ISSUE_PRIORITY = "medium";
|
|
5717
|
-
var DEFAULT_RESOLVED_ISSUE_DEFAULTS = {
|
|
5718
|
-
defaults: {
|
|
5719
|
-
status: DEFAULT_ISSUE_STATUS,
|
|
5720
|
-
priority: DEFAULT_ISSUE_PRIORITY
|
|
5721
|
-
},
|
|
5722
|
-
overrides: {}
|
|
5723
|
-
};
|
|
5724
|
-
function resolveIssueDefaults(config) {
|
|
5725
|
-
if (config === void 0) {
|
|
5726
|
-
return DEFAULT_RESOLVED_ISSUE_DEFAULTS;
|
|
5727
|
-
}
|
|
5728
|
-
const overrides = {};
|
|
5729
|
-
for (const [phaseLabel, override] of Object.entries(config)) {
|
|
5730
|
-
assertValidPhaseLabel(phaseLabel);
|
|
5731
|
-
assertValidOverride(phaseLabel, override);
|
|
5732
|
-
overrides[phaseLabel] = {
|
|
5733
|
-
status: override.status ?? DEFAULT_ISSUE_STATUS,
|
|
5734
|
-
priority: override.priority ?? DEFAULT_ISSUE_PRIORITY
|
|
5735
|
-
};
|
|
5736
|
-
}
|
|
5737
|
-
return {
|
|
5738
|
-
defaults: {
|
|
5739
|
-
status: DEFAULT_ISSUE_STATUS,
|
|
5740
|
-
priority: DEFAULT_ISSUE_PRIORITY
|
|
5741
|
-
},
|
|
5742
|
-
overrides
|
|
5743
|
-
};
|
|
5744
|
-
}
|
|
5745
|
-
function validateIssueDefaultsConfig(config) {
|
|
5746
|
-
return resolveIssueDefaults(config);
|
|
5747
|
-
}
|
|
5748
|
-
function labelsForPhase(resolved, phaseLabel) {
|
|
5749
|
-
return resolved.overrides[phaseLabel] ?? resolved.defaults;
|
|
5750
|
-
}
|
|
5751
|
-
function assertValidPhaseLabel(phaseLabel) {
|
|
5752
|
-
if (typeof phaseLabel !== "string" || phaseLabel.trim() === "") {
|
|
5753
|
-
throw new Error(
|
|
5754
|
-
"AgentConfigOptions.issueDefaults: phase-label keys must be non-empty strings (e.g. `people:research`)."
|
|
5755
|
-
);
|
|
5756
|
-
}
|
|
5757
|
-
}
|
|
5758
|
-
function assertValidOverride(phaseLabel, override) {
|
|
5759
|
-
if (override === null || typeof override !== "object" || Array.isArray(override)) {
|
|
5760
|
-
throw new Error(
|
|
5761
|
-
`AgentConfigOptions.issueDefaults["${phaseLabel}"] must be an object with optional \`status\` and \`priority\` fields.`
|
|
5762
|
-
);
|
|
5763
|
-
}
|
|
5764
|
-
const { status, priority } = override;
|
|
5765
|
-
if (status === void 0 && priority === void 0) {
|
|
5766
|
-
throw new Error(
|
|
5767
|
-
`AgentConfigOptions.issueDefaults["${phaseLabel}"] must declare at least one of \`status\` or \`priority\`. Empty entries are rejected because they are almost always a typo on the field name.`
|
|
5768
|
-
);
|
|
5769
|
-
}
|
|
5770
|
-
if (status !== void 0 && !VALID_STATUS_VALUES.includes(status)) {
|
|
5771
|
-
throw new Error(
|
|
5772
|
-
`AgentConfigOptions.issueDefaults["${phaseLabel}"].status="${status}" is not a recognised status value. Allowed values: ${VALID_STATUS_VALUES.join(", ")}.`
|
|
5773
|
-
);
|
|
5774
|
-
}
|
|
5775
|
-
if (priority !== void 0 && !VALID_PRIORITY_VALUES.includes(priority)) {
|
|
5776
|
-
throw new Error(
|
|
5777
|
-
`AgentConfigOptions.issueDefaults["${phaseLabel}"].priority="${priority}" is not a recognised priority value. Allowed values: ${VALID_PRIORITY_VALUES.join(", ")}.`
|
|
5778
|
-
);
|
|
5779
|
-
}
|
|
5780
|
-
}
|
|
5781
|
-
|
|
5782
6159
|
// src/agent/bundles/bcm-writer.ts
|
|
5783
6160
|
function buildBcmWriterSubAgent(paths, issueDefaults) {
|
|
5784
6161
|
return {
|
|
@@ -19469,37 +19846,7 @@ var scanCommand = {
|
|
|
19469
19846
|
""
|
|
19470
19847
|
].join("\n")
|
|
19471
19848
|
};
|
|
19472
|
-
var
|
|
19473
|
-
name: "orchestrator",
|
|
19474
|
-
description: "Pipeline orchestrator agent for issue triage, PR review, and queue management",
|
|
19475
|
-
// Always included by default
|
|
19476
|
-
appliesWhen: () => true,
|
|
19477
|
-
rules: [
|
|
19478
|
-
{
|
|
19479
|
-
name: "orchestrator-conventions",
|
|
19480
|
-
description: "Guidelines for orchestrator agent behavior and pipeline management, including the funnel-tier dispatch sort, scope gate, and per-agent scheduled-task layout",
|
|
19481
|
-
scope: AGENT_RULE_SCOPE.FILE_PATTERN,
|
|
19482
|
-
// Bundle defaults exclude paths into configulator's own source
|
|
19483
|
-
// (only meaningful when configulator is a workspace package).
|
|
19484
|
-
// codedrifters/packages restores them via
|
|
19485
|
-
// `agentConfig.additionalRulePaths`.
|
|
19486
|
-
filePatterns: [
|
|
19487
|
-
".claude/agents/orchestrator.md",
|
|
19488
|
-
".claude/scheduled-tasks/**"
|
|
19489
|
-
],
|
|
19490
|
-
content: buildOrchestratorConventionsContent(
|
|
19491
|
-
DEFAULT_AGENT_TIERS,
|
|
19492
|
-
resolveScopeGate(),
|
|
19493
|
-
resolveRunRatio(),
|
|
19494
|
-
resolveScheduledTasks(),
|
|
19495
|
-
resolveUnblockDependents()
|
|
19496
|
-
),
|
|
19497
|
-
platforms: {
|
|
19498
|
-
cursor: { exclude: true }
|
|
19499
|
-
},
|
|
19500
|
-
tags: ["workflow"]
|
|
19501
|
-
}
|
|
19502
|
-
],
|
|
19849
|
+
var ORCHESTRATOR_BUNDLE_STATIC = {
|
|
19503
19850
|
subAgents: [orchestratorSubAgent, issueWorkerSubAgent],
|
|
19504
19851
|
procedures: [
|
|
19505
19852
|
checkBlockedProcedure,
|
|
@@ -19515,6 +19862,51 @@ var orchestratorBundle = {
|
|
|
19515
19862
|
]
|
|
19516
19863
|
}
|
|
19517
19864
|
};
|
|
19865
|
+
var DEFAULT_ORCHESTRATOR_CONVENTIONS = {
|
|
19866
|
+
tiers: DEFAULT_AGENT_TIERS,
|
|
19867
|
+
scopeGate: resolveScopeGate(),
|
|
19868
|
+
runRatio: resolveRunRatio(),
|
|
19869
|
+
scheduledTasks: resolveScheduledTasks(),
|
|
19870
|
+
unblockDependents: resolveUnblockDependents(),
|
|
19871
|
+
excludeBundles: []
|
|
19872
|
+
};
|
|
19873
|
+
function buildOrchestratorBundle(conventions = DEFAULT_ORCHESTRATOR_CONVENTIONS) {
|
|
19874
|
+
return {
|
|
19875
|
+
name: "orchestrator",
|
|
19876
|
+
description: "Pipeline orchestrator agent for issue triage, PR review, and queue management",
|
|
19877
|
+
// Always included by default
|
|
19878
|
+
appliesWhen: () => true,
|
|
19879
|
+
rules: [
|
|
19880
|
+
{
|
|
19881
|
+
name: "orchestrator-conventions",
|
|
19882
|
+
description: "Guidelines for orchestrator agent behavior and pipeline management, including the funnel-tier dispatch sort, scope gate, and per-agent scheduled-task layout",
|
|
19883
|
+
scope: AGENT_RULE_SCOPE.FILE_PATTERN,
|
|
19884
|
+
// Bundle defaults exclude paths into configulator's own source
|
|
19885
|
+
// (only meaningful when configulator is a workspace package).
|
|
19886
|
+
// codedrifters/packages restores them via
|
|
19887
|
+
// `agentConfig.additionalRulePaths`.
|
|
19888
|
+
filePatterns: [
|
|
19889
|
+
".claude/agents/orchestrator.md",
|
|
19890
|
+
".claude/scheduled-tasks/**"
|
|
19891
|
+
],
|
|
19892
|
+
content: buildOrchestratorConventionsContent(
|
|
19893
|
+
conventions.tiers,
|
|
19894
|
+
conventions.scopeGate,
|
|
19895
|
+
conventions.runRatio,
|
|
19896
|
+
conventions.scheduledTasks,
|
|
19897
|
+
conventions.unblockDependents,
|
|
19898
|
+
conventions.excludeBundles
|
|
19899
|
+
),
|
|
19900
|
+
platforms: {
|
|
19901
|
+
cursor: { exclude: true }
|
|
19902
|
+
},
|
|
19903
|
+
tags: ["workflow"]
|
|
19904
|
+
}
|
|
19905
|
+
],
|
|
19906
|
+
...ORCHESTRATOR_BUNDLE_STATIC
|
|
19907
|
+
};
|
|
19908
|
+
}
|
|
19909
|
+
var orchestratorBundle = buildOrchestratorBundle();
|
|
19518
19910
|
|
|
19519
19911
|
// src/agent/bundles/people-profile.ts
|
|
19520
19912
|
function buildPeopleProfileAnalystSubAgent(paths, issueDefaults, tier) {
|
|
@@ -33025,6 +33417,8 @@ var UPSTREAM_CONFIGULATOR_DOCS_DETAIL = [
|
|
|
33025
33417
|
" --body $'## Summary\\n\\nThe `software-profile-analyst` Phase 2 prompt does not capture the vendor pricing tier (free / paid / enterprise), which downstream consumers need for segment matching.\\n\\n## Details\\n\\n- Add a `Pricing tier` field to the profile template at `docs/src/content/docs/agents/software-profile-analyst.md`\\n- Update the Phase 2 instructions to require the field before commit\\n- Add a regression test in `bundles.test.ts`'",
|
|
33026
33418
|
"```",
|
|
33027
33419
|
"",
|
|
33420
|
+
"The call above does **not** set the GitHub issue type \u2014 `gh issue create` cannot. Assign it immediately, in the same session, with the cross-repo GraphQL flow above (`feat:` title \u2192 **Feature**; every other prefix except `epic:` / `fix:` \u2192 **Task**). Skipping it leaves the upstream issue untyped, and nobody comes back for it later.",
|
|
33421
|
+
"",
|
|
33028
33422
|
"After filing, reference the upstream issue from any local workaround so it can be reverted once the upstream fix lands:",
|
|
33029
33423
|
"",
|
|
33030
33424
|
"```typescript",
|
|
@@ -33986,10 +34380,14 @@ function renderPriorityRulesSection(rules) {
|
|
|
33986
34380
|
}
|
|
33987
34381
|
|
|
33988
34382
|
// src/agent/bundles/index.ts
|
|
33989
|
-
|
|
34383
|
+
var DEFAULT_RULE_CONVENTIONS = {
|
|
34384
|
+
base: DEFAULT_BASE_CONVENTIONS,
|
|
34385
|
+
orchestrator: DEFAULT_ORCHESTRATOR_CONVENTIONS
|
|
34386
|
+
};
|
|
34387
|
+
function buildBuiltInBundles(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS, defaultAgentTier = AGENT_MODEL.BALANCED, bundleAgentTiers = /* @__PURE__ */ new Map(), prReviewPolicy = resolvePrReviewPolicy(), buildPolicy = DEFAULT_BUILD_POLICY, conventions = DEFAULT_RULE_CONVENTIONS) {
|
|
33990
34388
|
const tierFor = (bundle) => bundleAgentTiers.get(bundle) ?? defaultAgentTier;
|
|
33991
34389
|
return [
|
|
33992
|
-
buildBaseBundle(paths),
|
|
34390
|
+
buildBaseBundle(paths, conventions.base),
|
|
33993
34391
|
upstreamConfigulatorDocsBundle,
|
|
33994
34392
|
typescriptBundle,
|
|
33995
34393
|
vitestBundle,
|
|
@@ -34002,7 +34400,7 @@ function buildBuiltInBundles(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAUL
|
|
|
34002
34400
|
slackBundle,
|
|
34003
34401
|
buildMeetingAnalysisBundle(tierFor("meeting-analysis")),
|
|
34004
34402
|
agendaBundle,
|
|
34005
|
-
|
|
34403
|
+
buildOrchestratorBundle(conventions.orchestrator),
|
|
34006
34404
|
buildPrReviewBundle(prReviewPolicy),
|
|
34007
34405
|
buildRequirementsAnalystBundle(paths, issueDefaults),
|
|
34008
34406
|
buildRequirementsWriterBundle(paths, issueDefaults),
|
|
@@ -35090,6 +35488,13 @@ var AgentConfig = class _AgentConfig extends import_projen8.Component {
|
|
|
35090
35488
|
* credential requirement when a remote cache actually exists. The
|
|
35091
35489
|
* getter is lazy by design — `TurboRepo` must already be attached
|
|
35092
35490
|
* to the project when the bundles are first read.
|
|
35491
|
+
*
|
|
35492
|
+
* Every **config-driven convention rule** is likewise resolved here
|
|
35493
|
+
* and seeded into its owning bundle, so the rule enters the rule map
|
|
35494
|
+
* already carrying the consumer's settings. Rewriting those rules
|
|
35495
|
+
* after the map was assembled — the previous approach — silently
|
|
35496
|
+
* discarded any `ruleExtensions` append or same-name `rules`
|
|
35497
|
+
* override that had already been merged in.
|
|
35093
35498
|
*/
|
|
35094
35499
|
get pathAwareBundles() {
|
|
35095
35500
|
if (!this.cachedBundles) {
|
|
@@ -35099,11 +35504,52 @@ var AgentConfig = class _AgentConfig extends import_projen8.Component {
|
|
|
35099
35504
|
resolveDefaultAgentTier(this.options),
|
|
35100
35505
|
resolveBundleAgentTiers(this.options),
|
|
35101
35506
|
resolvePrReviewPolicy(this.options.prReviewPolicy),
|
|
35102
|
-
resolveBuildPolicy(this.project)
|
|
35507
|
+
resolveBuildPolicy(this.project),
|
|
35508
|
+
this.resolvedRuleConventions
|
|
35103
35509
|
);
|
|
35104
35510
|
}
|
|
35105
35511
|
return this.cachedBundles;
|
|
35106
35512
|
}
|
|
35513
|
+
/**
|
|
35514
|
+
* Resolved settings for every config-driven convention rule, derived
|
|
35515
|
+
* from this project's options. Consumed by `buildBuiltInBundles` so
|
|
35516
|
+
* the `base` and `orchestrator` bundles seed final rule content.
|
|
35517
|
+
*
|
|
35518
|
+
* `excludeBundles` feeds two of these: the orchestrator's rendered
|
|
35519
|
+
* tier table / scope-gate overrides / scheduled-tasks registry drop
|
|
35520
|
+
* rows owned by excluded bundles, and the issue-templates rule falls
|
|
35521
|
+
* back to its disabled stub once every downstream-issue-kind bundle
|
|
35522
|
+
* has been excluded.
|
|
35523
|
+
*/
|
|
35524
|
+
get resolvedRuleConventions() {
|
|
35525
|
+
const excludeBundles = this.options.excludeBundles ?? [];
|
|
35526
|
+
const orchestratorAssets = resolveOrchestratorAssets(
|
|
35527
|
+
this.options.tiers,
|
|
35528
|
+
this.options.scopeGate,
|
|
35529
|
+
this.options.runRatio,
|
|
35530
|
+
this.options.scheduledTasks,
|
|
35531
|
+
this.options.unblockDependents,
|
|
35532
|
+
excludeBundles
|
|
35533
|
+
);
|
|
35534
|
+
return {
|
|
35535
|
+
base: {
|
|
35536
|
+
progressFiles: resolveProgressFiles(this.options.progressFiles),
|
|
35537
|
+
sharedEditing: resolveSharedEditing(this.options.sharedEditing),
|
|
35538
|
+
temporalFraming: resolveTemporalFraming(this.options.temporalFraming),
|
|
35539
|
+
skillEvals: resolveSkillEvals(this.options.skillEvals),
|
|
35540
|
+
issueTemplates: resolveIssueTemplates(this.options.issueTemplates),
|
|
35541
|
+
hasDownstreamIssueKindBundles: hasAnyDownstreamIssueKindBundle(excludeBundles)
|
|
35542
|
+
},
|
|
35543
|
+
orchestrator: {
|
|
35544
|
+
tiers: orchestratorAssets.tiers,
|
|
35545
|
+
scopeGate: orchestratorAssets.scopeGate,
|
|
35546
|
+
runRatio: orchestratorAssets.runRatio,
|
|
35547
|
+
scheduledTasks: orchestratorAssets.scheduledTasks,
|
|
35548
|
+
unblockDependents: orchestratorAssets.unblockDependents,
|
|
35549
|
+
excludeBundles
|
|
35550
|
+
}
|
|
35551
|
+
};
|
|
35552
|
+
}
|
|
35107
35553
|
/**
|
|
35108
35554
|
* Returns the bundles that are active for this project: auto-detected
|
|
35109
35555
|
* bundles (when `autoDetectBundles !== false`) plus force-included
|
|
@@ -35201,11 +35647,34 @@ var AgentConfig = class _AgentConfig extends import_projen8.Component {
|
|
|
35201
35647
|
).split("\n"),
|
|
35202
35648
|
executable: true
|
|
35203
35649
|
});
|
|
35650
|
+
new import_projen8.TextFile(
|
|
35651
|
+
this,
|
|
35652
|
+
".claude/procedures/check-issue-template-labels.sh",
|
|
35653
|
+
{
|
|
35654
|
+
lines: renderIssueTemplateLabelsCheckerScript(
|
|
35655
|
+
resolvedIssueTemplates
|
|
35656
|
+
).split("\n"),
|
|
35657
|
+
executable: true
|
|
35658
|
+
}
|
|
35659
|
+
);
|
|
35204
35660
|
}
|
|
35205
35661
|
if (resolvedIssueTemplates.emitStarterDoc) {
|
|
35206
35662
|
new import_projen8.SampleFile(this.project, resolvedIssueTemplates.templatesPath, {
|
|
35207
35663
|
contents: renderIssueTemplatesStarterPage(resolvedIssueTemplates)
|
|
35208
35664
|
});
|
|
35665
|
+
new import_projen8.TextFile(
|
|
35666
|
+
this,
|
|
35667
|
+
issueTemplatesGeneratedPath(resolvedIssueTemplates.templatesPath),
|
|
35668
|
+
{
|
|
35669
|
+
lines: renderIssueTemplatesGeneratedPage(
|
|
35670
|
+
resolvedIssueTemplates,
|
|
35671
|
+
collectIssueTemplateRecipeStubs(
|
|
35672
|
+
this.activeBundles,
|
|
35673
|
+
resolveIssueDefaults(this.options.issueDefaults)
|
|
35674
|
+
)
|
|
35675
|
+
).split("\n")
|
|
35676
|
+
}
|
|
35677
|
+
);
|
|
35209
35678
|
}
|
|
35210
35679
|
}
|
|
35211
35680
|
const resolvedTemporalFraming = validateTemporalFramingConfig(
|
|
@@ -35395,43 +35864,10 @@ ${section}`
|
|
|
35395
35864
|
}
|
|
35396
35865
|
}
|
|
35397
35866
|
const excludedBundleNames = this.options.excludeBundles ?? [];
|
|
35398
|
-
if (this.options.tiers || this.options.scopeGate || this.options.runRatio || this.options.scheduledTasks || this.options.unblockDependents || excludedBundleNames.length > 0) {
|
|
35399
|
-
const orchestratorRule = ruleMap.get("orchestrator-conventions");
|
|
35400
|
-
if (orchestratorRule) {
|
|
35401
|
-
const { conventionsContent } = resolveOrchestratorAssets(
|
|
35402
|
-
this.options.tiers,
|
|
35403
|
-
this.options.scopeGate,
|
|
35404
|
-
this.options.runRatio,
|
|
35405
|
-
this.options.scheduledTasks,
|
|
35406
|
-
this.options.unblockDependents,
|
|
35407
|
-
excludedBundleNames
|
|
35408
|
-
);
|
|
35409
|
-
if (conventionsContent !== orchestratorRule.content) {
|
|
35410
|
-
ruleMap.set("orchestrator-conventions", {
|
|
35411
|
-
...orchestratorRule,
|
|
35412
|
-
content: conventionsContent
|
|
35413
|
-
});
|
|
35414
|
-
}
|
|
35415
|
-
}
|
|
35416
|
-
}
|
|
35417
35867
|
const injectBundleHooks = this.options.claudeMd?.injectBundleHooks ?? true;
|
|
35418
35868
|
const resolvedProgressFiles = resolveProgressFiles(
|
|
35419
35869
|
this.options.progressFiles
|
|
35420
35870
|
);
|
|
35421
|
-
if (this.options.progressFiles) {
|
|
35422
|
-
const progressRule = ruleMap.get("progress-file-convention");
|
|
35423
|
-
if (progressRule) {
|
|
35424
|
-
const progressContent = renderProgressFilesRuleContent(
|
|
35425
|
-
resolvedProgressFiles
|
|
35426
|
-
);
|
|
35427
|
-
if (progressContent !== progressRule.content) {
|
|
35428
|
-
ruleMap.set("progress-file-convention", {
|
|
35429
|
-
...progressRule,
|
|
35430
|
-
content: progressContent
|
|
35431
|
-
});
|
|
35432
|
-
}
|
|
35433
|
-
}
|
|
35434
|
-
}
|
|
35435
35871
|
if (injectBundleHooks && resolvedProgressFiles.enabled) {
|
|
35436
35872
|
for (const [ruleName, label] of PROGRESS_FILE_BUNDLE_HOOKS) {
|
|
35437
35873
|
const existing = ruleMap.get(ruleName);
|
|
@@ -35458,20 +35894,6 @@ ${hook}`
|
|
|
35458
35894
|
const resolvedSharedEditingForRules = resolveSharedEditing(
|
|
35459
35895
|
this.options.sharedEditing
|
|
35460
35896
|
);
|
|
35461
|
-
if (this.options.sharedEditing) {
|
|
35462
|
-
const sharedEditingRule = ruleMap.get("shared-editing-safety");
|
|
35463
|
-
if (sharedEditingRule) {
|
|
35464
|
-
const sharedEditingContent = renderSharedEditingRuleContent(
|
|
35465
|
-
resolvedSharedEditingForRules
|
|
35466
|
-
);
|
|
35467
|
-
if (sharedEditingContent !== sharedEditingRule.content) {
|
|
35468
|
-
ruleMap.set("shared-editing-safety", {
|
|
35469
|
-
...sharedEditingRule,
|
|
35470
|
-
content: sharedEditingContent
|
|
35471
|
-
});
|
|
35472
|
-
}
|
|
35473
|
-
}
|
|
35474
|
-
}
|
|
35475
35897
|
if (injectBundleHooks && resolvedSharedEditingForRules.enabled) {
|
|
35476
35898
|
for (const [ruleName, label] of SHARED_EDITING_BUNDLE_HOOKS) {
|
|
35477
35899
|
const existing = ruleMap.get(ruleName);
|
|
@@ -35498,20 +35920,6 @@ ${hook}`
|
|
|
35498
35920
|
const resolvedSkillEvalsForRules = resolveSkillEvals(
|
|
35499
35921
|
this.options.skillEvals
|
|
35500
35922
|
);
|
|
35501
|
-
if (this.options.skillEvals) {
|
|
35502
|
-
const skillEvalsRule = ruleMap.get("skill-evals");
|
|
35503
|
-
if (skillEvalsRule) {
|
|
35504
|
-
const skillEvalsContent = renderSkillEvalsRuleContent(
|
|
35505
|
-
resolvedSkillEvalsForRules
|
|
35506
|
-
);
|
|
35507
|
-
if (skillEvalsContent !== skillEvalsRule.content) {
|
|
35508
|
-
ruleMap.set("skill-evals", {
|
|
35509
|
-
...skillEvalsRule,
|
|
35510
|
-
content: skillEvalsContent
|
|
35511
|
-
});
|
|
35512
|
-
}
|
|
35513
|
-
}
|
|
35514
|
-
}
|
|
35515
35923
|
if (injectBundleHooks && resolvedSkillEvalsForRules.enabled) {
|
|
35516
35924
|
for (const [ruleName, label] of SKILL_EVALS_BUNDLE_HOOKS) {
|
|
35517
35925
|
const existing = ruleMap.get(ruleName);
|
|
@@ -35539,21 +35947,6 @@ ${hook}`
|
|
|
35539
35947
|
this.options.issueTemplates
|
|
35540
35948
|
);
|
|
35541
35949
|
const hasDownstreamBundles = hasAnyDownstreamIssueKindBundle(excludedBundleNames);
|
|
35542
|
-
if (this.options.issueTemplates || !hasDownstreamBundles) {
|
|
35543
|
-
const issueTemplatesRule = ruleMap.get("issue-templates-convention");
|
|
35544
|
-
if (issueTemplatesRule) {
|
|
35545
|
-
const issueTemplatesContent = renderIssueTemplatesRuleContent(
|
|
35546
|
-
resolvedIssueTemplatesForRules,
|
|
35547
|
-
hasDownstreamBundles
|
|
35548
|
-
);
|
|
35549
|
-
if (issueTemplatesContent !== issueTemplatesRule.content) {
|
|
35550
|
-
ruleMap.set("issue-templates-convention", {
|
|
35551
|
-
...issueTemplatesRule,
|
|
35552
|
-
content: issueTemplatesContent
|
|
35553
|
-
});
|
|
35554
|
-
}
|
|
35555
|
-
}
|
|
35556
|
-
}
|
|
35557
35950
|
if (injectBundleHooks && resolvedIssueTemplatesForRules.enabled && hasDownstreamBundles) {
|
|
35558
35951
|
for (const [ruleName, label] of ISSUE_TEMPLATES_BUNDLE_HOOKS) {
|
|
35559
35952
|
const existing = ruleMap.get(ruleName);
|
|
@@ -35577,23 +35970,6 @@ ${hook}`
|
|
|
35577
35970
|
});
|
|
35578
35971
|
}
|
|
35579
35972
|
}
|
|
35580
|
-
const resolvedTemporalFramingForRules = resolveTemporalFraming(
|
|
35581
|
-
this.options.temporalFraming
|
|
35582
|
-
);
|
|
35583
|
-
if (this.options.temporalFraming) {
|
|
35584
|
-
const temporalFramingRule = ruleMap.get("temporal-framing-convention");
|
|
35585
|
-
if (temporalFramingRule) {
|
|
35586
|
-
const temporalFramingContent = renderTemporalFramingRuleContent(
|
|
35587
|
-
resolvedTemporalFramingForRules
|
|
35588
|
-
);
|
|
35589
|
-
if (temporalFramingContent !== temporalFramingRule.content) {
|
|
35590
|
-
ruleMap.set("temporal-framing-convention", {
|
|
35591
|
-
...temporalFramingRule,
|
|
35592
|
-
content: temporalFramingContent
|
|
35593
|
-
});
|
|
35594
|
-
}
|
|
35595
|
-
}
|
|
35596
|
-
}
|
|
35597
35973
|
const tierExamples = this.options.features?.sourceTierExamples;
|
|
35598
35974
|
if (_AgentConfig.hasActiveTierExamples(tierExamples)) {
|
|
35599
35975
|
const sourceRule = ruleMap.get("source-quality-verification");
|
|
@@ -41806,6 +42182,7 @@ export const collections = {
|
|
|
41806
42182
|
DEFAULT_API_EXTRACTOR_REPORT_FILENAME,
|
|
41807
42183
|
DEFAULT_API_EXTRACTOR_REPORT_FOLDER,
|
|
41808
42184
|
DEFAULT_AUDIT_REPORT_DIR,
|
|
42185
|
+
DEFAULT_BASE_CONVENTIONS,
|
|
41809
42186
|
DEFAULT_BUILD_POLICY,
|
|
41810
42187
|
DEFAULT_BUNDLE_OVERRIDES,
|
|
41811
42188
|
DEFAULT_DECOMPOSITION_TEMPLATE,
|
|
@@ -41822,6 +42199,7 @@ export const collections = {
|
|
|
41822
42199
|
DEFAULT_ISSUE_TEMPLATES_PATH,
|
|
41823
42200
|
DEFAULT_ISSUE_TEMPLATES_REQUIRE_REFERENCE,
|
|
41824
42201
|
DEFAULT_OFF_PEAK_CRON_EXAMPLE,
|
|
42202
|
+
DEFAULT_ORCHESTRATOR_CONVENTIONS,
|
|
41825
42203
|
DEFAULT_PARTIAL_UNBLOCK_COMMENT_TEMPLATE,
|
|
41826
42204
|
DEFAULT_PATHS_EXEMPT_FROM_SIZE,
|
|
41827
42205
|
DEFAULT_PRIORITY_LABELS,
|
|
@@ -41834,6 +42212,7 @@ export const collections = {
|
|
|
41834
42212
|
DEFAULT_REQUIREMENT_CATEGORY_DIRS,
|
|
41835
42213
|
DEFAULT_REQUIRE_PRODUCT_CONTEXT,
|
|
41836
42214
|
DEFAULT_RESOLVED_ISSUE_DEFAULTS,
|
|
42215
|
+
DEFAULT_RULE_CONVENTIONS,
|
|
41837
42216
|
DEFAULT_SAMPLE_COMPILER_OPTIONS,
|
|
41838
42217
|
DEFAULT_SCHEDULED_TASKS_ROOT,
|
|
41839
42218
|
DEFAULT_SCHEDULED_TASK_ENTRIES,
|
|
@@ -41860,6 +42239,7 @@ export const collections = {
|
|
|
41860
42239
|
DOCS_SYNC_AUDIT_SCHEMA_VERSION,
|
|
41861
42240
|
GITHUB_ISSUE_TYPES,
|
|
41862
42241
|
GITHUB_ISSUE_TYPE_BY_TITLE_PREFIX,
|
|
42242
|
+
ISSUE_TEMPLATES_GENERATED_SUFFIX,
|
|
41863
42243
|
JsiiFaker,
|
|
41864
42244
|
LAYOUT_ENFORCEMENT,
|
|
41865
42245
|
LAYOUT_ROOT_BY_PROJECT_TYPE,
|
|
@@ -41936,6 +42316,7 @@ export const collections = {
|
|
|
41936
42316
|
buildIndustryDiscoveryBundle,
|
|
41937
42317
|
buildMaintenanceAuditBundle,
|
|
41938
42318
|
buildMeetingAnalysisBundle,
|
|
42319
|
+
buildOrchestratorBundle,
|
|
41939
42320
|
buildOrchestratorConventionsContent,
|
|
41940
42321
|
buildPeopleProfileBundle,
|
|
41941
42322
|
buildPrReviewBundle,
|
|
@@ -41955,6 +42336,7 @@ export const collections = {
|
|
|
41955
42336
|
checkLinksProcedure,
|
|
41956
42337
|
classifyIssueScope,
|
|
41957
42338
|
classifyRun,
|
|
42339
|
+
collectIssueTemplateRecipeStubs,
|
|
41958
42340
|
companyProfileBundle,
|
|
41959
42341
|
compileFencedSamples,
|
|
41960
42342
|
createApiDiffCheck,
|
|
@@ -41980,6 +42362,8 @@ export const collections = {
|
|
|
41980
42362
|
isScheduledTaskOwnedByExcluded,
|
|
41981
42363
|
isSuppressedWorkflowRule,
|
|
41982
42364
|
isTypeLabelOwnedByExcluded,
|
|
42365
|
+
issueTemplatesChildGlob,
|
|
42366
|
+
issueTemplatesGeneratedPath,
|
|
41983
42367
|
jestBundle,
|
|
41984
42368
|
labelsForPhase,
|
|
41985
42369
|
maintenanceAuditBundle,
|
|
@@ -42030,8 +42414,10 @@ export const collections = {
|
|
|
42030
42414
|
renderFocusSection,
|
|
42031
42415
|
renderGithubIssueTypeSection,
|
|
42032
42416
|
renderGithubIssueTypeSectionLines,
|
|
42417
|
+
renderIssueTemplateLabelsCheckerScript,
|
|
42033
42418
|
renderIssueTemplatesBundleHook,
|
|
42034
42419
|
renderIssueTemplatesCheckerScript,
|
|
42420
|
+
renderIssueTemplatesGeneratedPage,
|
|
42035
42421
|
renderIssueTemplatesRuleContent,
|
|
42036
42422
|
renderIssueTemplatesStarterPage,
|
|
42037
42423
|
renderIssueTypeAssignmentBlanket,
|