@codedrifters/configulator 0.0.407 → 0.0.409
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 +2632 -2472
- package/lib/index.d.ts +2633 -2473
- package/lib/index.js +586 -154
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +580 -154
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
package/lib/index.mjs
CHANGED
|
@@ -5027,7 +5027,15 @@ var createRuleSkill = {
|
|
|
5027
5027
|
"- Use `ruleExtensions` to add project-specific content to existing bundle rules instead of replacing them"
|
|
5028
5028
|
].join("\n")
|
|
5029
5029
|
};
|
|
5030
|
-
|
|
5030
|
+
var DEFAULT_BASE_CONVENTIONS = {
|
|
5031
|
+
progressFiles: resolveProgressFiles(),
|
|
5032
|
+
sharedEditing: resolveSharedEditing(),
|
|
5033
|
+
temporalFraming: resolveTemporalFraming(),
|
|
5034
|
+
skillEvals: resolveSkillEvals(),
|
|
5035
|
+
issueTemplates: resolveIssueTemplates(),
|
|
5036
|
+
hasDownstreamIssueKindBundles: true
|
|
5037
|
+
};
|
|
5038
|
+
function buildBaseBundle(paths = DEFAULT_AGENT_PATHS, conventions = DEFAULT_BASE_CONVENTIONS) {
|
|
5031
5039
|
return {
|
|
5032
5040
|
name: "base",
|
|
5033
5041
|
description: "Core rules: project overview, interaction style, and general coding conventions",
|
|
@@ -5696,7 +5704,7 @@ function buildBaseBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
|
5696
5704
|
// them via `agentConfig.additionalRulePaths`; other consumers
|
|
5697
5705
|
// get a clean default.
|
|
5698
5706
|
filePatterns: [".claude/agents/*.md", ".claude/procedures/**"],
|
|
5699
|
-
content: renderProgressFilesRuleContent(
|
|
5707
|
+
content: renderProgressFilesRuleContent(conventions.progressFiles),
|
|
5700
5708
|
platforms: {
|
|
5701
5709
|
cursor: { exclude: true }
|
|
5702
5710
|
},
|
|
@@ -5707,7 +5715,7 @@ function buildBaseBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
|
5707
5715
|
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.",
|
|
5708
5716
|
scope: AGENT_RULE_SCOPE.FILE_PATTERN,
|
|
5709
5717
|
filePatterns: DEFAULT_SHARED_INDEX_PATHS,
|
|
5710
|
-
content: renderSharedEditingRuleContent(
|
|
5718
|
+
content: renderSharedEditingRuleContent(conventions.sharedEditing),
|
|
5711
5719
|
platforms: {
|
|
5712
5720
|
cursor: { exclude: true }
|
|
5713
5721
|
},
|
|
@@ -5725,7 +5733,7 @@ function buildBaseBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
|
5725
5733
|
"docs/src/content/docs/standards-research/**/*.md",
|
|
5726
5734
|
"docs/src/content/docs/customer-research/**/*.md"
|
|
5727
5735
|
],
|
|
5728
|
-
content: renderTemporalFramingRuleContent(
|
|
5736
|
+
content: renderTemporalFramingRuleContent(conventions.temporalFraming),
|
|
5729
5737
|
platforms: {
|
|
5730
5738
|
cursor: { exclude: true }
|
|
5731
5739
|
},
|
|
@@ -5738,7 +5746,7 @@ function buildBaseBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
|
5738
5746
|
// Bundle defaults exclude paths into configulator's own
|
|
5739
5747
|
// source — see comment on progress-file-convention above.
|
|
5740
5748
|
filePatterns: [".claude/skills/**"],
|
|
5741
|
-
content: renderSkillEvalsRuleContent(
|
|
5749
|
+
content: renderSkillEvalsRuleContent(conventions.skillEvals),
|
|
5742
5750
|
platforms: {
|
|
5743
5751
|
cursor: { exclude: true }
|
|
5744
5752
|
},
|
|
@@ -5755,7 +5763,10 @@ function buildBaseBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
|
5755
5763
|
".claude/agents/*.md",
|
|
5756
5764
|
`${paths.docsRoot}/agents/issue-templates.md`
|
|
5757
5765
|
],
|
|
5758
|
-
content: renderIssueTemplatesRuleContent(
|
|
5766
|
+
content: renderIssueTemplatesRuleContent(
|
|
5767
|
+
conventions.issueTemplates,
|
|
5768
|
+
conventions.hasDownstreamIssueKindBundles
|
|
5769
|
+
),
|
|
5759
5770
|
platforms: {
|
|
5760
5771
|
cursor: { exclude: true }
|
|
5761
5772
|
},
|
|
@@ -11373,6 +11384,278 @@ var docsSyncBundle = buildDocsSyncBundle();
|
|
|
11373
11384
|
|
|
11374
11385
|
// src/agent/bundles/github-workflow.ts
|
|
11375
11386
|
import { GitHub } from "projen/lib/github";
|
|
11387
|
+
|
|
11388
|
+
// src/agent/bundles/closing-keywords.ts
|
|
11389
|
+
function renderCheckClosingKeywordsScript() {
|
|
11390
|
+
return [
|
|
11391
|
+
"#!/usr/bin/env bash",
|
|
11392
|
+
"# check-closing-keywords.sh \u2014 Detect PR bodies that strand issues.",
|
|
11393
|
+
"#",
|
|
11394
|
+
"# GitHub honours exactly ONE issue reference per closing keyword. A",
|
|
11395
|
+
"# body that writes `Closes #593, #594, #595` closes #593 and leaves",
|
|
11396
|
+
"# #594 and #595 open forever. The only correct form is one keyword",
|
|
11397
|
+
"# per issue, each on its own line:",
|
|
11398
|
+
"#",
|
|
11399
|
+
"# Closes #593",
|
|
11400
|
+
"# Closes #594",
|
|
11401
|
+
"#",
|
|
11402
|
+
"# Usage:",
|
|
11403
|
+
"# .claude/procedures/check-closing-keywords.sh <pr-number>",
|
|
11404
|
+
"# .claude/procedures/check-closing-keywords.sh --body-file <path>",
|
|
11405
|
+
"#",
|
|
11406
|
+
"# Output (one stable line per reference, then a summary line):",
|
|
11407
|
+
"# CLOSES #<n> line=<L>",
|
|
11408
|
+
"# A reference GitHub WILL honour (the first one after a keyword).",
|
|
11409
|
+
"# STRANDED #<n> line=<L> keyword=<kw> first=#<n>",
|
|
11410
|
+
"# A reference chained onto an earlier one. GitHub will NOT",
|
|
11411
|
+
"# close it \u2014 the issue is stranded.",
|
|
11412
|
+
"# CLOSING_KEYWORDS_OK closes=<K>",
|
|
11413
|
+
"# CLOSING_KEYWORDS_MALFORMED closes=<K> stranded=<S>",
|
|
11414
|
+
"# NO_CLOSING_KEYWORD",
|
|
11415
|
+
"#",
|
|
11416
|
+
"# Exit codes:",
|
|
11417
|
+
"# 0 \u2014 at least one closing keyword, every one well-formed",
|
|
11418
|
+
"# 1 \u2014 at least one stranded reference (malformed body)",
|
|
11419
|
+
"# 2 \u2014 argument error",
|
|
11420
|
+
"# 3 \u2014 required command not on PATH",
|
|
11421
|
+
"# 4 \u2014 could not read the PR body",
|
|
11422
|
+
"# 5 \u2014 no closing keyword found at all",
|
|
11423
|
+
"",
|
|
11424
|
+
"set -uo pipefail",
|
|
11425
|
+
"",
|
|
11426
|
+
"# \u2500\u2500 helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
11427
|
+
"",
|
|
11428
|
+
"err() {",
|
|
11429
|
+
' printf "check-closing-keywords.sh: %s\\n" "$*" >&2',
|
|
11430
|
+
"}",
|
|
11431
|
+
"",
|
|
11432
|
+
"usage() {",
|
|
11433
|
+
" cat >&2 <<'USAGE'",
|
|
11434
|
+
"Usage: check-closing-keywords.sh <pr-number>",
|
|
11435
|
+
" check-closing-keywords.sh --body-file <path>",
|
|
11436
|
+
"",
|
|
11437
|
+
" <pr-number> Positive integer PR number; the body is read",
|
|
11438
|
+
" via `gh pr view <n> --json body`.",
|
|
11439
|
+
" --body-file <path> Read the body from a file instead. Use this to",
|
|
11440
|
+
" check a drafted body BEFORE `gh pr create`.",
|
|
11441
|
+
"",
|
|
11442
|
+
"Emits one CLOSES / STRANDED line per issue reference, then a summary.",
|
|
11443
|
+
"Exits 1 when any reference is stranded by a multi-issue keyword.",
|
|
11444
|
+
"USAGE",
|
|
11445
|
+
"}",
|
|
11446
|
+
"",
|
|
11447
|
+
"# \u2500\u2500 argument parsing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
11448
|
+
"",
|
|
11449
|
+
'mode=""',
|
|
11450
|
+
'arg=""',
|
|
11451
|
+
"",
|
|
11452
|
+
"while [[ $# -gt 0 ]]; do",
|
|
11453
|
+
' case "$1" in',
|
|
11454
|
+
" --body-file)",
|
|
11455
|
+
' if [[ $# -lt 2 || -z "${2:-}" ]]; then',
|
|
11456
|
+
' err "--body-file requires a value"',
|
|
11457
|
+
" usage",
|
|
11458
|
+
" exit 2",
|
|
11459
|
+
" fi",
|
|
11460
|
+
' if [[ -n "$mode" ]]; then',
|
|
11461
|
+
' err "specify either a PR number or --body-file, not both"',
|
|
11462
|
+
" exit 2",
|
|
11463
|
+
" fi",
|
|
11464
|
+
' mode="file"',
|
|
11465
|
+
' arg="$2"',
|
|
11466
|
+
" shift 2",
|
|
11467
|
+
" ;;",
|
|
11468
|
+
" -h|--help)",
|
|
11469
|
+
" usage",
|
|
11470
|
+
" exit 0",
|
|
11471
|
+
" ;;",
|
|
11472
|
+
" -*)",
|
|
11473
|
+
' err "unknown option: $1"',
|
|
11474
|
+
" usage",
|
|
11475
|
+
" exit 2",
|
|
11476
|
+
" ;;",
|
|
11477
|
+
" *)",
|
|
11478
|
+
' if [[ -n "$mode" ]]; then',
|
|
11479
|
+
' err "unexpected extra argument: $1"',
|
|
11480
|
+
" usage",
|
|
11481
|
+
" exit 2",
|
|
11482
|
+
" fi",
|
|
11483
|
+
' mode="pr"',
|
|
11484
|
+
' arg="$1"',
|
|
11485
|
+
" shift",
|
|
11486
|
+
" ;;",
|
|
11487
|
+
" esac",
|
|
11488
|
+
"done",
|
|
11489
|
+
"",
|
|
11490
|
+
'if [[ -z "$mode" ]]; then',
|
|
11491
|
+
' err "expected a PR number or --body-file <path>"',
|
|
11492
|
+
" usage",
|
|
11493
|
+
" exit 2",
|
|
11494
|
+
"fi",
|
|
11495
|
+
"",
|
|
11496
|
+
"# \u2500\u2500 read the body \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
11497
|
+
"",
|
|
11498
|
+
'body=""',
|
|
11499
|
+
"",
|
|
11500
|
+
'if [[ "$mode" == "file" ]]; then',
|
|
11501
|
+
' if [[ ! -r "$arg" ]]; then',
|
|
11502
|
+
' err "body file not readable: $arg"',
|
|
11503
|
+
" exit 4",
|
|
11504
|
+
" fi",
|
|
11505
|
+
' body=$(cat "$arg")',
|
|
11506
|
+
"else",
|
|
11507
|
+
' if ! [[ "$arg" =~ ^[1-9][0-9]*$ ]]; then',
|
|
11508
|
+
` err "PR number must be a positive integer (got: '$arg')"`,
|
|
11509
|
+
" exit 2",
|
|
11510
|
+
" fi",
|
|
11511
|
+
" if ! command -v gh >/dev/null 2>&1; then",
|
|
11512
|
+
' err "required command not found on PATH: gh"',
|
|
11513
|
+
" exit 3",
|
|
11514
|
+
" fi",
|
|
11515
|
+
` if ! body=$(gh pr view "$arg" --json body -q '.body' 2>/dev/null); then`,
|
|
11516
|
+
' err "could not read the body of PR #${arg} via gh"',
|
|
11517
|
+
" exit 4",
|
|
11518
|
+
" fi",
|
|
11519
|
+
"fi",
|
|
11520
|
+
"",
|
|
11521
|
+
"# \u2500\u2500 parsing contract \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
11522
|
+
"#",
|
|
11523
|
+
"# Regexes live in single-quoted variables so backticks and other shell",
|
|
11524
|
+
"# metacharacters inside them are never expanded by [[ ]].",
|
|
11525
|
+
"#",
|
|
11526
|
+
"# kw_re matches a closing keyword plus its FIRST issue reference. The",
|
|
11527
|
+
"# leading (^|[^[:alnum:]_]) is a word boundary so `prefixes #1` is not",
|
|
11528
|
+
"# read as `fixes #1`.",
|
|
11529
|
+
"#",
|
|
11530
|
+
"# sep_re / ws_re walk the tail AFTER that first reference, matching",
|
|
11531
|
+
"# only references CHAINED directly onto it by a separator a human",
|
|
11532
|
+
"# would mistake for a list: `,` `/` `&` `+` `and` `, and`, or",
|
|
11533
|
+
"# bare whitespace. Anything else \u2014 a period, a dash, a word, an",
|
|
11534
|
+
"# opening paren \u2014 terminates the chain. That is what keeps prose like",
|
|
11535
|
+
"# `Closes #893. See #607 and #860 for context.` from false-positiving:",
|
|
11536
|
+
"# the `.` after #893 ends the chain before `#607` is ever considered.",
|
|
11537
|
+
"",
|
|
11538
|
+
"fence_re='^[[:space:]]{0,3}(```+|~~~+)'",
|
|
11539
|
+
"quote_re='^[[:space:]]*>'",
|
|
11540
|
+
"kw_re='(^|[^[:alnum:]_])(closes|closed|close|fixes|fixed|fix|resolves|resolved|resolve)[[:space:]]*:?[[:space:]]*#([0-9]+)(.*)$'",
|
|
11541
|
+
"sep_re='^[[:space:]]*(,[[:space:]]*and|,|/|&|[+]|and)[[:space:]]*#([0-9]+)(.*)$'",
|
|
11542
|
+
"ws_re='^[[:space:]]+#([0-9]+)(.*)$'",
|
|
11543
|
+
"",
|
|
11544
|
+
"# Keywords are case-insensitive on GitHub, so the scan is too.",
|
|
11545
|
+
"shopt -s nocasematch",
|
|
11546
|
+
"",
|
|
11547
|
+
"# A single backtick, held in a variable so the code-span stripper",
|
|
11548
|
+
"# never has to quote one inline.",
|
|
11549
|
+
"bt='`'",
|
|
11550
|
+
"",
|
|
11551
|
+
"# Remove inline code spans (`...`) from a line. A PR body that",
|
|
11552
|
+
"# DISCUSSES the malformed form \u2014 writing `Closes #593, #594` inside",
|
|
11553
|
+
"# backticks \u2014 must not trip the detector.",
|
|
11554
|
+
"strip_code_spans() {",
|
|
11555
|
+
' local s="$1"',
|
|
11556
|
+
' local out=""',
|
|
11557
|
+
' while [[ "$s" == *"$bt"*"$bt"* ]]; do',
|
|
11558
|
+
' out="$out${s%%$bt*}"',
|
|
11559
|
+
' s="${s#*$bt}"',
|
|
11560
|
+
' s="${s#*$bt}"',
|
|
11561
|
+
" done",
|
|
11562
|
+
` printf '%s%s' "$out" "$s"`,
|
|
11563
|
+
"}",
|
|
11564
|
+
"",
|
|
11565
|
+
"# \u2500\u2500 scan \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
11566
|
+
"",
|
|
11567
|
+
"line_no=0",
|
|
11568
|
+
"in_fence=0",
|
|
11569
|
+
'fence_marker=""',
|
|
11570
|
+
"closes_count=0",
|
|
11571
|
+
"stranded_count=0",
|
|
11572
|
+
"",
|
|
11573
|
+
'while IFS= read -r raw || [[ -n "$raw" ]]; do',
|
|
11574
|
+
" line_no=$((line_no + 1))",
|
|
11575
|
+
" # gh returns CRLF bodies; strip the CR so end-of-line matching works.",
|
|
11576
|
+
` raw="\${raw//$'\\r'/}"`,
|
|
11577
|
+
"",
|
|
11578
|
+
" # Fenced code blocks are quoted content, never the PR's own intent.",
|
|
11579
|
+
' if [[ "$raw" =~ $fence_re ]]; then',
|
|
11580
|
+
' marker="${BASH_REMATCH[1]:0:1}"',
|
|
11581
|
+
" if [[ $in_fence -eq 0 ]]; then",
|
|
11582
|
+
" in_fence=1",
|
|
11583
|
+
' fence_marker="$marker"',
|
|
11584
|
+
' elif [[ "$marker" == "$fence_marker" ]]; then',
|
|
11585
|
+
" in_fence=0",
|
|
11586
|
+
' fence_marker=""',
|
|
11587
|
+
" fi",
|
|
11588
|
+
" continue",
|
|
11589
|
+
" fi",
|
|
11590
|
+
" if [[ $in_fence -eq 1 ]]; then",
|
|
11591
|
+
" continue",
|
|
11592
|
+
" fi",
|
|
11593
|
+
"",
|
|
11594
|
+
" # Blockquoted text is someone else's words being cited.",
|
|
11595
|
+
' if [[ "$raw" =~ $quote_re ]]; then',
|
|
11596
|
+
" continue",
|
|
11597
|
+
" fi",
|
|
11598
|
+
"",
|
|
11599
|
+
' line=$(strip_code_spans "$raw")',
|
|
11600
|
+
"",
|
|
11601
|
+
' rest="$line"',
|
|
11602
|
+
' while [[ "$rest" =~ $kw_re ]]; do',
|
|
11603
|
+
' kw="${BASH_REMATCH[2]}"',
|
|
11604
|
+
' first="${BASH_REMATCH[3]}"',
|
|
11605
|
+
' tail="${BASH_REMATCH[4]}"',
|
|
11606
|
+
"",
|
|
11607
|
+
` printf 'CLOSES #%s line=%s\\n' "$first" "$line_no"`,
|
|
11608
|
+
" closes_count=$((closes_count + 1))",
|
|
11609
|
+
"",
|
|
11610
|
+
" # Walk every reference chained onto this keyword's first one.",
|
|
11611
|
+
' t="$tail"',
|
|
11612
|
+
" while :; do",
|
|
11613
|
+
' if [[ "$t" =~ $sep_re ]]; then',
|
|
11614
|
+
' extra="${BASH_REMATCH[2]}"',
|
|
11615
|
+
' t="${BASH_REMATCH[3]}"',
|
|
11616
|
+
' elif [[ "$t" =~ $ws_re ]]; then',
|
|
11617
|
+
' extra="${BASH_REMATCH[1]}"',
|
|
11618
|
+
' t="${BASH_REMATCH[2]}"',
|
|
11619
|
+
" else",
|
|
11620
|
+
" break",
|
|
11621
|
+
" fi",
|
|
11622
|
+
" printf 'STRANDED #%s line=%s keyword=%s first=#%s\\n' \\",
|
|
11623
|
+
' "$extra" "$line_no" "$kw" "$first"',
|
|
11624
|
+
" stranded_count=$((stranded_count + 1))",
|
|
11625
|
+
" done",
|
|
11626
|
+
"",
|
|
11627
|
+
' rest="$t"',
|
|
11628
|
+
" done",
|
|
11629
|
+
'done <<< "$body"',
|
|
11630
|
+
"",
|
|
11631
|
+
"# \u2500\u2500 summary \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
11632
|
+
"",
|
|
11633
|
+
"if [[ $closes_count -eq 0 ]]; then",
|
|
11634
|
+
' echo "NO_CLOSING_KEYWORD"',
|
|
11635
|
+
" exit 5",
|
|
11636
|
+
"fi",
|
|
11637
|
+
"",
|
|
11638
|
+
"if [[ $stranded_count -gt 0 ]]; then",
|
|
11639
|
+
" printf 'CLOSING_KEYWORDS_MALFORMED closes=%s stranded=%s\\n' \\",
|
|
11640
|
+
' "$closes_count" "$stranded_count"',
|
|
11641
|
+
' err "GitHub honours only ONE issue reference per closing keyword."',
|
|
11642
|
+
' err "Give every issue its own keyword, one per line:"',
|
|
11643
|
+
' err " Closes #123"',
|
|
11644
|
+
' err " Closes #456"',
|
|
11645
|
+
" exit 1",
|
|
11646
|
+
"fi",
|
|
11647
|
+
"",
|
|
11648
|
+
`printf 'CLOSING_KEYWORDS_OK closes=%s\\n' "$closes_count"`,
|
|
11649
|
+
"exit 0"
|
|
11650
|
+
].join("\n");
|
|
11651
|
+
}
|
|
11652
|
+
var checkClosingKeywordsProcedure = {
|
|
11653
|
+
name: "check-closing-keywords.sh",
|
|
11654
|
+
description: "Parse a PR body (by PR number or --body-file) and report every closing-keyword issue reference as CLOSES (GitHub will honour it) or STRANDED (chained onto an earlier reference and silently ignored). Exits 1 when any reference is stranded. Skips fenced code blocks, blockquotes, and inline code spans.",
|
|
11655
|
+
content: renderCheckClosingKeywordsScript()
|
|
11656
|
+
};
|
|
11657
|
+
|
|
11658
|
+
// src/agent/bundles/github-workflow.ts
|
|
11376
11659
|
var setIssueTypeProcedure = {
|
|
11377
11660
|
name: "set-issue-type.sh",
|
|
11378
11661
|
description: "Assign a GitHub issue type (Feature / Task / Epic / Bug / etc.) via the updateIssueIssueType GraphQL mutation in a single step",
|
|
@@ -12047,8 +12330,24 @@ function buildGithubWorkflowBundle(buildPolicy = DEFAULT_BUILD_POLICY) {
|
|
|
12047
12330
|
"5. **Push the branch** to origin: `git push -u origin <branch>`",
|
|
12048
12331
|
"6. **Create the PR** using `gh pr create`:",
|
|
12049
12332
|
" - **Title**: use a conventional commit style title (e.g., `feat(scope): short description`)",
|
|
12050
|
-
" - **Body**: include `Closes #<issue-number>` (derived from the branch name) and a brief summary of changes",
|
|
12051
|
-
"7. **
|
|
12333
|
+
" - **Body**: include one `Closes #<issue-number>` line per issue the PR closes (derived from the branch name and any additional issues in scope) and a brief summary of changes. See **Closing Keywords** below \u2014 never list several issues after a single keyword.",
|
|
12334
|
+
"7. **Verify the closing keywords** with `.claude/procedures/check-closing-keywords.sh --body-file <path>` on the body you are about to post, then `.claude/procedures/check-closing-keywords.sh <pr-number>` on the body that landed. Exit `0` means every referenced issue will auto-close; exit `1` prints a `STRANDED #<n>` line per issue GitHub would silently leave open \u2014 fix the body with `gh pr edit <pr-number> --body-file <path>` and re-run until it exits `0`.",
|
|
12335
|
+
"8. **Delegate review and merge to the `pr-reviewer` sub-agent.** After the PR is created, invoke the `/review-pr <pr-number>` skill (or otherwise hand the new PR number to the `pr-reviewer` sub-agent). The reviewer verifies the diff against the linked issue's acceptance criteria and enables squash auto-merge when all checks pass. Do **not** run `gh pr merge --auto` yourself \u2014 review/merge policy lives solely in the `pr-reviewer` agent.",
|
|
12336
|
+
"",
|
|
12337
|
+
"### Closing Keywords",
|
|
12338
|
+
"",
|
|
12339
|
+
"**GitHub honours exactly ONE issue reference per closing keyword.** `Closes #593, #594, #595` closes **#593 only** \u2014 #594 and #595 stay open forever with no warning anywhere. `Closes #821 / #837` and `Closes #821 and #837` strand the second issue the same way. Give every issue its own keyword, one per line:",
|
|
12340
|
+
"",
|
|
12341
|
+
"```markdown",
|
|
12342
|
+
"Closes #593 <- correct: repeat the keyword, one issue each",
|
|
12343
|
+
"Closes #594",
|
|
12344
|
+
"",
|
|
12345
|
+
"Closes #593, #594 <- WRONG: closes #593, strands #594",
|
|
12346
|
+
"Closes #821 / #837 <- WRONG: closes #821, strands #837",
|
|
12347
|
+
"Closes #821 and #837 <- WRONG: closes #821, strands #837",
|
|
12348
|
+
"```",
|
|
12349
|
+
"",
|
|
12350
|
+
"`Fixes` and `Resolves` behave identically \u2014 the rule is the keyword-to-issue ratio, not the verb. Non-closing references (`Refs #849`, `Related to #607`) are unaffected. `.claude/procedures/check-closing-keywords.sh` is the mechanical check; it skips fenced code blocks, blockquotes, and inline code spans, so a body that *discusses* the malformed form does not trip it.",
|
|
12052
12351
|
"",
|
|
12053
12352
|
"### PR Body Template",
|
|
12054
12353
|
"",
|
|
@@ -12065,10 +12364,18 @@ function buildGithubWorkflowBundle(buildPolicy = DEFAULT_BUILD_POLICY) {
|
|
|
12065
12364
|
"- [ ] Relevant changes have been reviewed",
|
|
12066
12365
|
"```",
|
|
12067
12366
|
"",
|
|
12367
|
+
"When the PR closes more than one issue, the closing block expands to one keyword per issue \u2014 it never becomes a list:",
|
|
12368
|
+
"",
|
|
12369
|
+
"```markdown",
|
|
12370
|
+
"Closes #<first-issue-number>",
|
|
12371
|
+
"Closes #<second-issue-number>",
|
|
12372
|
+
"```",
|
|
12373
|
+
"",
|
|
12068
12374
|
"### Important",
|
|
12069
12375
|
"",
|
|
12070
12376
|
"- Always derive the issue number from the branch name (e.g., `feat/42-add-login` \u2192 `#42`)",
|
|
12071
12377
|
"- Use conventional commit format for the PR title",
|
|
12378
|
+
"- **One closing keyword per issue, each on its own line.** Never `Closes #A, #B` \u2014 GitHub closes only `#A`. Run `.claude/procedures/check-closing-keywords.sh` before and after `gh pr create`; a non-zero exit means the PR would strand an issue",
|
|
12072
12379
|
"- Delegate merge to the `pr-reviewer` sub-agent \u2014 do not merge manually and do not enable auto-merge directly"
|
|
12073
12380
|
].join("\n"),
|
|
12074
12381
|
tags: ["workflow"]
|
|
@@ -12101,7 +12408,11 @@ function buildGithubWorkflowBundle(buildPolicy = DEFAULT_BUILD_POLICY) {
|
|
|
12101
12408
|
}
|
|
12102
12409
|
],
|
|
12103
12410
|
skills: [cleanMergedBranchesSkill],
|
|
12104
|
-
procedures: [
|
|
12411
|
+
procedures: [
|
|
12412
|
+
setIssueTypeProcedure,
|
|
12413
|
+
cleanMergedBranchesProcedure,
|
|
12414
|
+
checkClosingKeywordsProcedure
|
|
12415
|
+
]
|
|
12105
12416
|
};
|
|
12106
12417
|
}
|
|
12107
12418
|
var githubWorkflowBundle = buildGithubWorkflowBundle();
|
|
@@ -19189,6 +19500,27 @@ var issueWorkerSubAgent = {
|
|
|
19189
19500
|
'Closes #<issue-number>"',
|
|
19190
19501
|
"```",
|
|
19191
19502
|
"",
|
|
19503
|
+
"**One closing keyword per issue, each on its own line.** GitHub honours",
|
|
19504
|
+
"only one issue reference per keyword, so `Closes #A, #B` closes `#A` and",
|
|
19505
|
+
"leaves `#B` open forever \u2014 the same is true of `Closes #A / #B` and",
|
|
19506
|
+
"`Closes #A and #B`. A PR that closes several issues repeats the keyword:",
|
|
19507
|
+
"",
|
|
19508
|
+
"```",
|
|
19509
|
+
"Closes #<first-issue-number>",
|
|
19510
|
+
"Closes #<second-issue-number>",
|
|
19511
|
+
"```",
|
|
19512
|
+
"",
|
|
19513
|
+
"Verify it mechanically before moving on \u2014 this exits non-zero and names",
|
|
19514
|
+
"every issue the body would strand:",
|
|
19515
|
+
"",
|
|
19516
|
+
"```bash",
|
|
19517
|
+
".claude/procedures/check-closing-keywords.sh <pr-number>",
|
|
19518
|
+
"```",
|
|
19519
|
+
"",
|
|
19520
|
+
"If it reports `CLOSING_KEYWORDS_MALFORMED`, fix the body with",
|
|
19521
|
+
"`gh pr edit <pr-number> --body-file <path>` and re-run until it exits",
|
|
19522
|
+
"`0`. See the **Closing Keywords** section of the `pr-workflow` rule.",
|
|
19523
|
+
"",
|
|
19192
19524
|
"Do **not** enable auto-merge yourself. The `pr-reviewer` sub-agent owns",
|
|
19193
19525
|
"review and merge for every PR \u2014 it verifies the diff against the issue's",
|
|
19194
19526
|
"acceptance criteria and enables squash auto-merge only when all checks",
|
|
@@ -19462,37 +19794,7 @@ var scanCommand = {
|
|
|
19462
19794
|
""
|
|
19463
19795
|
].join("\n")
|
|
19464
19796
|
};
|
|
19465
|
-
var
|
|
19466
|
-
name: "orchestrator",
|
|
19467
|
-
description: "Pipeline orchestrator agent for issue triage, PR review, and queue management",
|
|
19468
|
-
// Always included by default
|
|
19469
|
-
appliesWhen: () => true,
|
|
19470
|
-
rules: [
|
|
19471
|
-
{
|
|
19472
|
-
name: "orchestrator-conventions",
|
|
19473
|
-
description: "Guidelines for orchestrator agent behavior and pipeline management, including the funnel-tier dispatch sort, scope gate, and per-agent scheduled-task layout",
|
|
19474
|
-
scope: AGENT_RULE_SCOPE.FILE_PATTERN,
|
|
19475
|
-
// Bundle defaults exclude paths into configulator's own source
|
|
19476
|
-
// (only meaningful when configulator is a workspace package).
|
|
19477
|
-
// codedrifters/packages restores them via
|
|
19478
|
-
// `agentConfig.additionalRulePaths`.
|
|
19479
|
-
filePatterns: [
|
|
19480
|
-
".claude/agents/orchestrator.md",
|
|
19481
|
-
".claude/scheduled-tasks/**"
|
|
19482
|
-
],
|
|
19483
|
-
content: buildOrchestratorConventionsContent(
|
|
19484
|
-
DEFAULT_AGENT_TIERS,
|
|
19485
|
-
resolveScopeGate(),
|
|
19486
|
-
resolveRunRatio(),
|
|
19487
|
-
resolveScheduledTasks(),
|
|
19488
|
-
resolveUnblockDependents()
|
|
19489
|
-
),
|
|
19490
|
-
platforms: {
|
|
19491
|
-
cursor: { exclude: true }
|
|
19492
|
-
},
|
|
19493
|
-
tags: ["workflow"]
|
|
19494
|
-
}
|
|
19495
|
-
],
|
|
19797
|
+
var ORCHESTRATOR_BUNDLE_STATIC = {
|
|
19496
19798
|
subAgents: [orchestratorSubAgent, issueWorkerSubAgent],
|
|
19497
19799
|
procedures: [
|
|
19498
19800
|
checkBlockedProcedure,
|
|
@@ -19508,6 +19810,51 @@ var orchestratorBundle = {
|
|
|
19508
19810
|
]
|
|
19509
19811
|
}
|
|
19510
19812
|
};
|
|
19813
|
+
var DEFAULT_ORCHESTRATOR_CONVENTIONS = {
|
|
19814
|
+
tiers: DEFAULT_AGENT_TIERS,
|
|
19815
|
+
scopeGate: resolveScopeGate(),
|
|
19816
|
+
runRatio: resolveRunRatio(),
|
|
19817
|
+
scheduledTasks: resolveScheduledTasks(),
|
|
19818
|
+
unblockDependents: resolveUnblockDependents(),
|
|
19819
|
+
excludeBundles: []
|
|
19820
|
+
};
|
|
19821
|
+
function buildOrchestratorBundle(conventions = DEFAULT_ORCHESTRATOR_CONVENTIONS) {
|
|
19822
|
+
return {
|
|
19823
|
+
name: "orchestrator",
|
|
19824
|
+
description: "Pipeline orchestrator agent for issue triage, PR review, and queue management",
|
|
19825
|
+
// Always included by default
|
|
19826
|
+
appliesWhen: () => true,
|
|
19827
|
+
rules: [
|
|
19828
|
+
{
|
|
19829
|
+
name: "orchestrator-conventions",
|
|
19830
|
+
description: "Guidelines for orchestrator agent behavior and pipeline management, including the funnel-tier dispatch sort, scope gate, and per-agent scheduled-task layout",
|
|
19831
|
+
scope: AGENT_RULE_SCOPE.FILE_PATTERN,
|
|
19832
|
+
// Bundle defaults exclude paths into configulator's own source
|
|
19833
|
+
// (only meaningful when configulator is a workspace package).
|
|
19834
|
+
// codedrifters/packages restores them via
|
|
19835
|
+
// `agentConfig.additionalRulePaths`.
|
|
19836
|
+
filePatterns: [
|
|
19837
|
+
".claude/agents/orchestrator.md",
|
|
19838
|
+
".claude/scheduled-tasks/**"
|
|
19839
|
+
],
|
|
19840
|
+
content: buildOrchestratorConventionsContent(
|
|
19841
|
+
conventions.tiers,
|
|
19842
|
+
conventions.scopeGate,
|
|
19843
|
+
conventions.runRatio,
|
|
19844
|
+
conventions.scheduledTasks,
|
|
19845
|
+
conventions.unblockDependents,
|
|
19846
|
+
conventions.excludeBundles
|
|
19847
|
+
),
|
|
19848
|
+
platforms: {
|
|
19849
|
+
cursor: { exclude: true }
|
|
19850
|
+
},
|
|
19851
|
+
tags: ["workflow"]
|
|
19852
|
+
}
|
|
19853
|
+
],
|
|
19854
|
+
...ORCHESTRATOR_BUNDLE_STATIC
|
|
19855
|
+
};
|
|
19856
|
+
}
|
|
19857
|
+
var orchestratorBundle = buildOrchestratorBundle();
|
|
19511
19858
|
|
|
19512
19859
|
// src/agent/bundles/people-profile.ts
|
|
19513
19860
|
function buildPeopleProfileAnalystSubAgent(paths, issueDefaults, tier) {
|
|
@@ -20853,8 +21200,32 @@ var prReviewerSubAgent = {
|
|
|
20853
21200
|
" resolve CI via the **CI Verification** section's Actions-runs",
|
|
20854
21201
|
" fallback before deciding eligibility \u2014 do **not** treat the 403 as",
|
|
20855
21202
|
" either a pass or an automatic disqualification.",
|
|
20856
|
-
"3. The PR body contains
|
|
20857
|
-
" `Closes #N`, `Fixes #N`,
|
|
21203
|
+
"3. The PR body contains at least one linked issue via a closing",
|
|
21204
|
+
" keyword (`Closes #N`, `Fixes #N`, `Resolves #N`, case-insensitive).",
|
|
21205
|
+
" Resolve this mechanically \u2014 do **not** eyeball the body:",
|
|
21206
|
+
"",
|
|
21207
|
+
"```bash",
|
|
21208
|
+
".claude/procedures/check-closing-keywords.sh <pr-number>",
|
|
21209
|
+
"```",
|
|
21210
|
+
"",
|
|
21211
|
+
" The procedure is the single source of truth for closing-keyword",
|
|
21212
|
+
" parsing in this pipeline. It emits one `CLOSES #<n> line=<L>` line",
|
|
21213
|
+
" per reference GitHub will honour, one",
|
|
21214
|
+
" `STRANDED #<n> line=<L> keyword=<kw> first=#<n>` line per reference",
|
|
21215
|
+
" GitHub will silently ignore, then a summary line. It skips fenced",
|
|
21216
|
+
" code blocks, blockquotes, and inline code spans, so a body that",
|
|
21217
|
+
" merely discusses closing keywords does not confuse it.",
|
|
21218
|
+
"",
|
|
21219
|
+
" - Exit `5` / `NO_CLOSING_KEYWORD` \u2014 check (3) **fails**; the PR has",
|
|
21220
|
+
" no linked issue.",
|
|
21221
|
+
" - Exit `0` / `CLOSING_KEYWORDS_OK` \u2014 check (3) passes. Record the",
|
|
21222
|
+
" `CLOSES` set as the **linked-issue set** for the rest of the pass.",
|
|
21223
|
+
" - Exit `1` / `CLOSING_KEYWORDS_MALFORMED` \u2014 check (3) **passes**",
|
|
21224
|
+
" (there is a linked issue), but the body would strand every",
|
|
21225
|
+
" `STRANDED` issue. This is **not** an eligibility rejection \u2014 the",
|
|
21226
|
+
" code is not at fault. Record both the `CLOSES` and `STRANDED`",
|
|
21227
|
+
" sets as the linked-issue set and carry the malformed finding into",
|
|
21228
|
+
" Phase 4 and Phase 5.",
|
|
20858
21229
|
"",
|
|
20859
21230
|
"If the **CI** check (2) or the **linked-issue** check (3) fails, post",
|
|
20860
21231
|
"a short comment explaining the reason and stop. Do not proceed to",
|
|
@@ -20922,16 +21293,29 @@ var prReviewerSubAgent = {
|
|
|
20922
21293
|
"gh pr checks <pr-number>",
|
|
20923
21294
|
"```",
|
|
20924
21295
|
"",
|
|
20925
|
-
"
|
|
20926
|
-
"
|
|
21296
|
+
"Use the **linked-issue set** already computed in Phase 1.5 \u2014 the union",
|
|
21297
|
+
"of the `CLOSES` and `STRANDED` issue numbers the",
|
|
21298
|
+
"`check-closing-keywords.sh` run reported. Do not re-derive it by",
|
|
21299
|
+
"reading the body yourself.",
|
|
21300
|
+
"",
|
|
21301
|
+
"Most PRs link exactly one issue, and every phase below reads naturally",
|
|
21302
|
+
"in the singular. When the set has more than one member, treat **every**",
|
|
21303
|
+
"member as a linked issue: fetch each one, union their acceptance",
|
|
21304
|
+
"criteria in Phase 3, and close each one in Phase 5. The **primary**",
|
|
21305
|
+
"linked issue \u2014 the one cited in the sticky summary and the structured",
|
|
21306
|
+
"report \u2014 is the first `CLOSES` entry.",
|
|
20927
21307
|
"",
|
|
20928
|
-
"Then fetch
|
|
20929
|
-
"evaluate the issue-type portion of the review policy:",
|
|
21308
|
+
"Then fetch each linked issue, including its `issueType` so Phase 2.75",
|
|
21309
|
+
"can evaluate the issue-type portion of the review policy:",
|
|
20930
21310
|
"",
|
|
20931
21311
|
"```bash",
|
|
20932
21312
|
"gh issue view <issue-number> --json number,title,body,labels,state,issueType",
|
|
20933
21313
|
"```",
|
|
20934
21314
|
"",
|
|
21315
|
+
"When several issues are linked, Phase 2.75's issue-type rule matches if",
|
|
21316
|
+
"**any** linked issue's type is in `human-required.issue-types` \u2014 the",
|
|
21317
|
+
"conservative reading, consistent with the policy's mixed-signal rule.",
|
|
21318
|
+
"",
|
|
20935
21319
|
"## Phase 2.5: Gather Comments",
|
|
20936
21320
|
"",
|
|
20937
21321
|
"Before deciding review mode, collect every human comment on the PR so",
|
|
@@ -21229,6 +21613,14 @@ var prReviewerSubAgent = {
|
|
|
21229
21613
|
"",
|
|
21230
21614
|
"- **Convention compliance** \u2014 PR title uses a conventional commit prefix,",
|
|
21231
21615
|
" body includes a closing keyword, branch name follows project conventions",
|
|
21616
|
+
"- **Closing-keyword integrity** \u2014 the Phase 1.5",
|
|
21617
|
+
" `check-closing-keywords.sh` run exited `0`. A",
|
|
21618
|
+
" `CLOSING_KEYWORDS_MALFORMED` result is a **Suggested** finding (not",
|
|
21619
|
+
" blocking): the diff is unaffected, and Phase 5 closes the stranded",
|
|
21620
|
+
" issues deterministically, so gating the merge on it would wedge a",
|
|
21621
|
+
" correct PR over a body typo. Record every `STRANDED #<n>` in the",
|
|
21622
|
+
" findings and in the sticky summary so the malformed body is visible",
|
|
21623
|
+
" rather than silent.",
|
|
21232
21624
|
"- **Test coverage** \u2014 new or changed behavior has tests",
|
|
21233
21625
|
"- **CI status** \u2014 resolve CI via the **CI Verification** section",
|
|
21234
21626
|
" (primary check-runs read, with the Actions-runs fallback on a",
|
|
@@ -21591,7 +21983,38 @@ var prReviewerSubAgent = {
|
|
|
21591
21983
|
"",
|
|
21592
21984
|
"### If all acceptance criteria are met and CI is green",
|
|
21593
21985
|
"",
|
|
21594
|
-
"
|
|
21986
|
+
"#### Pre-merge closing-keyword check",
|
|
21987
|
+
"",
|
|
21988
|
+
"Run this **before** branching on the review mode \u2014 it applies in both",
|
|
21989
|
+
"modes and is the last cheap moment to catch a body that would strand",
|
|
21990
|
+
"issues on merge:",
|
|
21991
|
+
"",
|
|
21992
|
+
"```bash",
|
|
21993
|
+
".claude/procedures/check-closing-keywords.sh <pr-number>",
|
|
21994
|
+
"```",
|
|
21995
|
+
"",
|
|
21996
|
+
"Re-run it here rather than reusing the Phase 1.5 result: the body may",
|
|
21997
|
+
"have been edited since, and the merge is about to make the answer",
|
|
21998
|
+
"permanent.",
|
|
21999
|
+
"",
|
|
22000
|
+
"- **Exit `0`** \u2014 nothing to do; every linked issue will auto-close.",
|
|
22001
|
+
"- **Exit `1`** \u2014 the body strands at least one issue. Do **not** block",
|
|
22002
|
+
" the merge; post one comment naming the stranded issues and the",
|
|
22003
|
+
" corrected block, then continue. Phase 5 closes the survivors",
|
|
22004
|
+
" explicitly, so the malformed body costs a comment, not a wedged PR.",
|
|
22005
|
+
"",
|
|
22006
|
+
"```bash",
|
|
22007
|
+
"gh pr comment <pr-number> --body 'GitHub honours only one issue reference per closing keyword, so this body would close #<first> and silently leave #<stranded\u2026> open. Give each issue its own keyword, one per line:",
|
|
22008
|
+
"",
|
|
22009
|
+
"Closes #<first>",
|
|
22010
|
+
"Closes #<stranded>",
|
|
22011
|
+
"",
|
|
22012
|
+
"Merging anyway \u2014 Phase 5 will close the stranded issues explicitly.'",
|
|
22013
|
+
"```",
|
|
22014
|
+
"",
|
|
22015
|
+
"Carry the full stranded set into Phase 5 verbatim.",
|
|
22016
|
+
"",
|
|
22017
|
+
"Then branch on the **review mode** decided in Phase 2.75:",
|
|
21595
22018
|
"",
|
|
21596
22019
|
"#### Mode `auto-merge`",
|
|
21597
22020
|
"",
|
|
@@ -21779,6 +22202,7 @@ var prReviewerSubAgent = {
|
|
|
21779
22202
|
"**Outstanding:** <list of comments still open with their classification and author>",
|
|
21780
22203
|
"**Pushbacks:** <list of disputes with reasons>",
|
|
21781
22204
|
"**Label reconciliation:** <consistent | corrections applied this pass>",
|
|
22205
|
+
"**Closing keywords:** ok | malformed \u2014 strands #<n>[, #<n>\u2026]",
|
|
21782
22206
|
"**Last pass:** <ISO timestamp>",
|
|
21783
22207
|
"```",
|
|
21784
22208
|
"",
|
|
@@ -21803,6 +22227,11 @@ var prReviewerSubAgent = {
|
|
|
21803
22227
|
" the corrections applied this pass (the detected violation combo,",
|
|
21804
22228
|
" the label(s) removed, and the resulting self-consistent set).",
|
|
21805
22229
|
" Every reconciliation correction is recorded here for auditability.",
|
|
22230
|
+
"- **Closing keywords** \u2014 the",
|
|
22231
|
+
" `.claude/procedures/check-closing-keywords.sh` verdict: `ok`, or",
|
|
22232
|
+
" `malformed` plus every `STRANDED #<n>` the body would leave open.",
|
|
22233
|
+
" Recorded on every pass so a body that strands issues is visible to a",
|
|
22234
|
+
" human before the merge, not only after Phase 5 repairs it.",
|
|
21806
22235
|
"- **Last pass** \u2014 the ISO 8601 timestamp of this run.",
|
|
21807
22236
|
"",
|
|
21808
22237
|
"### Step 3: Create or edit in place",
|
|
@@ -22187,42 +22616,64 @@ var prReviewerSubAgent = {
|
|
|
22187
22616
|
"gh pr view <pr-number> --json state --jq '.state'",
|
|
22188
22617
|
"```",
|
|
22189
22618
|
"",
|
|
22190
|
-
"- **`MERGED`** \u2014 clean up locally **and** verify
|
|
22619
|
+
"- **`MERGED`** \u2014 clean up locally **and** verify **every** linked issue",
|
|
22620
|
+
" closed:",
|
|
22191
22621
|
" ```bash",
|
|
22192
22622
|
" git checkout {{repository.defaultBranch}}",
|
|
22193
22623
|
" git pull origin {{repository.defaultBranch}}",
|
|
22194
22624
|
" git fetch --prune origin",
|
|
22195
22625
|
" git branch -d <branch-name> 2>/dev/null || git branch -D <branch-name> 2>/dev/null || true",
|
|
22196
22626
|
" ```",
|
|
22197
|
-
"
|
|
22198
|
-
"
|
|
22627
|
+
"",
|
|
22628
|
+
" **Post-merge closure verification.** Iterate the **full linked-issue",
|
|
22629
|
+
" set** from Phase 1.5 \u2014 the union of the `CLOSES` and `STRANDED`",
|
|
22630
|
+
" numbers `check-closing-keywords.sh` reported \u2014 not just the primary",
|
|
22631
|
+
" issue. This loop is the structural guard against the stranded-issue",
|
|
22632
|
+
" defect class: GitHub honours only one issue reference per closing",
|
|
22633
|
+
" keyword, so a body written as `Closes #A, #B` closes `#A` and leaves",
|
|
22634
|
+
" `#B` open forever with no signal anywhere. Because the reviewer",
|
|
22635
|
+
" already knows the full set, every survivor is closed here",
|
|
22636
|
+
" deterministically instead of being discovered months later by an",
|
|
22637
|
+
" audit.",
|
|
22638
|
+
"",
|
|
22639
|
+
" For **each** issue in the set, in order:",
|
|
22640
|
+
"",
|
|
22641
|
+
" 1. Transition it to `status:done` (replaces whichever of",
|
|
22642
|
+
" `status:ready-for-review` or `status:in-progress` it was carrying):",
|
|
22199
22643
|
" ```bash",
|
|
22200
22644
|
" gh issue edit <issue-number> \\",
|
|
22201
22645
|
' --remove-label "status:ready-for-review" \\',
|
|
22202
22646
|
' --remove-label "status:in-progress" \\',
|
|
22203
22647
|
' --add-label "status:done"',
|
|
22204
22648
|
" ```",
|
|
22205
|
-
"
|
|
22649
|
+
" 2. Check its state:",
|
|
22206
22650
|
" ```bash",
|
|
22207
22651
|
" gh issue view <issue-number> --json state --jq '.state'",
|
|
22208
22652
|
" ```",
|
|
22209
|
-
" If the issue is **not** `CLOSED`, close it explicitly (this covers",
|
|
22210
|
-
"
|
|
22653
|
+
" 3. If the issue is **not** `CLOSED`, close it explicitly (this covers",
|
|
22654
|
+
" both a missing closing keyword and an issue stranded by a",
|
|
22655
|
+
" multi-issue keyword):",
|
|
22211
22656
|
" ```bash",
|
|
22212
22657
|
" gh issue close <issue-number> --reason completed",
|
|
22213
22658
|
" gh issue comment <issue-number> --body 'PR #<pr-number> merged. Closing issue.'",
|
|
22214
22659
|
" ```",
|
|
22215
|
-
" Once `status:done` is applied (either via the edit above or the",
|
|
22216
|
-
"
|
|
22217
|
-
"
|
|
22218
|
-
"
|
|
22660
|
+
" 4. Once `status:done` is applied (either via the edit above or the",
|
|
22661
|
+
" explicit close path), run the targeted unblock sweep so any",
|
|
22662
|
+
" dependents waiting on this issue flip from `status:blocked` to",
|
|
22663
|
+
" `status:ready` immediately:",
|
|
22219
22664
|
" ```bash",
|
|
22220
22665
|
" .claude/procedures/unblock-dependents.sh <issue-number>",
|
|
22221
22666
|
" ```",
|
|
22667
|
+
"",
|
|
22222
22668
|
" Log the sweep's output (one line per processed dependent:",
|
|
22223
22669
|
" `UNBLOCKED #<n>` / `STILL_BLOCKED #<n>` / `NO_DEPENDENTS #<m>`)",
|
|
22224
22670
|
" in the PR review summary. See the **Agent-driven unblocking**",
|
|
22225
22671
|
" section in `CLAUDE.md` for the full contract.",
|
|
22672
|
+
"",
|
|
22673
|
+
" Report one `Issue #<n>: <closed-by-github | closed-explicitly>` line",
|
|
22674
|
+
" per member of the set. Any issue that needed the explicit close was",
|
|
22675
|
+
" stranded by the PR body \u2014 say so in the summary so the authoring",
|
|
22676
|
+
" defect is visible, not just repaired.",
|
|
22226
22677
|
"- **`CLOSED` (not merged)** \u2014 leave the branch in place; report the closure.",
|
|
22227
22678
|
"- **Still `OPEN`** \u2014 auto-merge is pending; report and stop without deleting.",
|
|
22228
22679
|
"",
|
|
@@ -22235,6 +22686,8 @@ var prReviewerSubAgent = {
|
|
|
22235
22686
|
"```",
|
|
22236
22687
|
"PR #<number> \u2014 <title>",
|
|
22237
22688
|
"Linked issue: #<issue-number>",
|
|
22689
|
+
"Linked issue set: #<n> [, #<n>\u2026] (from check-closing-keywords.sh)",
|
|
22690
|
+
"Closing keywords: <ok | malformed: strands #<n>[, #<n>\u2026]>",
|
|
22238
22691
|
"Review mode: <auto-merge | human-required>",
|
|
22239
22692
|
"Reason: <short explanation from Phase 2.75>",
|
|
22240
22693
|
"Verdict: AUTO_MERGE_ENABLED | AWAITING_HUMAN | DELEGATED_TO_WORKER | NEEDS_CHANGES | INELIGIBLE | BLOCKED",
|
|
@@ -22275,6 +22728,14 @@ var prReviewerSubAgent = {
|
|
|
22275
22728
|
" PR in turn.",
|
|
22276
22729
|
"2. **Never merge without a linked issue.** If the PR body has no",
|
|
22277
22730
|
" `Closes #N` / `Fixes #N` / `Resolves #N`, comment and stop.",
|
|
22731
|
+
"2a. **Never merge without verifying every linked issue closes.** Resolve",
|
|
22732
|
+
" the linked-issue set with",
|
|
22733
|
+
" `.claude/procedures/check-closing-keywords.sh <pr-number>`, never by",
|
|
22734
|
+
" eyeballing the body. GitHub honours only one issue reference per",
|
|
22735
|
+
" closing keyword, so a `STRANDED` line means that issue will stay",
|
|
22736
|
+
" open after the merge unless Phase 5 closes it. Phase 5 must iterate",
|
|
22737
|
+
" the **whole** set \u2014 `CLOSES` plus `STRANDED` \u2014 and explicitly close",
|
|
22738
|
+
" every issue GitHub left open.",
|
|
22278
22739
|
"3. **Never merge with failing CI.** Even if every criterion is met,",
|
|
22279
22740
|
" block on red checks. Resolve CI status via the **CI",
|
|
22280
22741
|
" Verification** section: read check-runs first, and only on a",
|
|
@@ -33981,10 +34442,14 @@ function renderPriorityRulesSection(rules) {
|
|
|
33981
34442
|
}
|
|
33982
34443
|
|
|
33983
34444
|
// src/agent/bundles/index.ts
|
|
33984
|
-
|
|
34445
|
+
var DEFAULT_RULE_CONVENTIONS = {
|
|
34446
|
+
base: DEFAULT_BASE_CONVENTIONS,
|
|
34447
|
+
orchestrator: DEFAULT_ORCHESTRATOR_CONVENTIONS
|
|
34448
|
+
};
|
|
34449
|
+
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) {
|
|
33985
34450
|
const tierFor = (bundle) => bundleAgentTiers.get(bundle) ?? defaultAgentTier;
|
|
33986
34451
|
return [
|
|
33987
|
-
buildBaseBundle(paths),
|
|
34452
|
+
buildBaseBundle(paths, conventions.base),
|
|
33988
34453
|
upstreamConfigulatorDocsBundle,
|
|
33989
34454
|
typescriptBundle,
|
|
33990
34455
|
vitestBundle,
|
|
@@ -33997,7 +34462,7 @@ function buildBuiltInBundles(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAUL
|
|
|
33997
34462
|
slackBundle,
|
|
33998
34463
|
buildMeetingAnalysisBundle(tierFor("meeting-analysis")),
|
|
33999
34464
|
agendaBundle,
|
|
34000
|
-
|
|
34465
|
+
buildOrchestratorBundle(conventions.orchestrator),
|
|
34001
34466
|
buildPrReviewBundle(prReviewPolicy),
|
|
34002
34467
|
buildRequirementsAnalystBundle(paths, issueDefaults),
|
|
34003
34468
|
buildRequirementsWriterBundle(paths, issueDefaults),
|
|
@@ -35085,6 +35550,13 @@ var AgentConfig = class _AgentConfig extends Component8 {
|
|
|
35085
35550
|
* credential requirement when a remote cache actually exists. The
|
|
35086
35551
|
* getter is lazy by design — `TurboRepo` must already be attached
|
|
35087
35552
|
* to the project when the bundles are first read.
|
|
35553
|
+
*
|
|
35554
|
+
* Every **config-driven convention rule** is likewise resolved here
|
|
35555
|
+
* and seeded into its owning bundle, so the rule enters the rule map
|
|
35556
|
+
* already carrying the consumer's settings. Rewriting those rules
|
|
35557
|
+
* after the map was assembled — the previous approach — silently
|
|
35558
|
+
* discarded any `ruleExtensions` append or same-name `rules`
|
|
35559
|
+
* override that had already been merged in.
|
|
35088
35560
|
*/
|
|
35089
35561
|
get pathAwareBundles() {
|
|
35090
35562
|
if (!this.cachedBundles) {
|
|
@@ -35094,11 +35566,52 @@ var AgentConfig = class _AgentConfig extends Component8 {
|
|
|
35094
35566
|
resolveDefaultAgentTier(this.options),
|
|
35095
35567
|
resolveBundleAgentTiers(this.options),
|
|
35096
35568
|
resolvePrReviewPolicy(this.options.prReviewPolicy),
|
|
35097
|
-
resolveBuildPolicy(this.project)
|
|
35569
|
+
resolveBuildPolicy(this.project),
|
|
35570
|
+
this.resolvedRuleConventions
|
|
35098
35571
|
);
|
|
35099
35572
|
}
|
|
35100
35573
|
return this.cachedBundles;
|
|
35101
35574
|
}
|
|
35575
|
+
/**
|
|
35576
|
+
* Resolved settings for every config-driven convention rule, derived
|
|
35577
|
+
* from this project's options. Consumed by `buildBuiltInBundles` so
|
|
35578
|
+
* the `base` and `orchestrator` bundles seed final rule content.
|
|
35579
|
+
*
|
|
35580
|
+
* `excludeBundles` feeds two of these: the orchestrator's rendered
|
|
35581
|
+
* tier table / scope-gate overrides / scheduled-tasks registry drop
|
|
35582
|
+
* rows owned by excluded bundles, and the issue-templates rule falls
|
|
35583
|
+
* back to its disabled stub once every downstream-issue-kind bundle
|
|
35584
|
+
* has been excluded.
|
|
35585
|
+
*/
|
|
35586
|
+
get resolvedRuleConventions() {
|
|
35587
|
+
const excludeBundles = this.options.excludeBundles ?? [];
|
|
35588
|
+
const orchestratorAssets = resolveOrchestratorAssets(
|
|
35589
|
+
this.options.tiers,
|
|
35590
|
+
this.options.scopeGate,
|
|
35591
|
+
this.options.runRatio,
|
|
35592
|
+
this.options.scheduledTasks,
|
|
35593
|
+
this.options.unblockDependents,
|
|
35594
|
+
excludeBundles
|
|
35595
|
+
);
|
|
35596
|
+
return {
|
|
35597
|
+
base: {
|
|
35598
|
+
progressFiles: resolveProgressFiles(this.options.progressFiles),
|
|
35599
|
+
sharedEditing: resolveSharedEditing(this.options.sharedEditing),
|
|
35600
|
+
temporalFraming: resolveTemporalFraming(this.options.temporalFraming),
|
|
35601
|
+
skillEvals: resolveSkillEvals(this.options.skillEvals),
|
|
35602
|
+
issueTemplates: resolveIssueTemplates(this.options.issueTemplates),
|
|
35603
|
+
hasDownstreamIssueKindBundles: hasAnyDownstreamIssueKindBundle(excludeBundles)
|
|
35604
|
+
},
|
|
35605
|
+
orchestrator: {
|
|
35606
|
+
tiers: orchestratorAssets.tiers,
|
|
35607
|
+
scopeGate: orchestratorAssets.scopeGate,
|
|
35608
|
+
runRatio: orchestratorAssets.runRatio,
|
|
35609
|
+
scheduledTasks: orchestratorAssets.scheduledTasks,
|
|
35610
|
+
unblockDependents: orchestratorAssets.unblockDependents,
|
|
35611
|
+
excludeBundles
|
|
35612
|
+
}
|
|
35613
|
+
};
|
|
35614
|
+
}
|
|
35102
35615
|
/**
|
|
35103
35616
|
* Returns the bundles that are active for this project: auto-detected
|
|
35104
35617
|
* bundles (when `autoDetectBundles !== false`) plus force-included
|
|
@@ -35413,43 +35926,10 @@ ${section}`
|
|
|
35413
35926
|
}
|
|
35414
35927
|
}
|
|
35415
35928
|
const excludedBundleNames = this.options.excludeBundles ?? [];
|
|
35416
|
-
if (this.options.tiers || this.options.scopeGate || this.options.runRatio || this.options.scheduledTasks || this.options.unblockDependents || excludedBundleNames.length > 0) {
|
|
35417
|
-
const orchestratorRule = ruleMap.get("orchestrator-conventions");
|
|
35418
|
-
if (orchestratorRule) {
|
|
35419
|
-
const { conventionsContent } = resolveOrchestratorAssets(
|
|
35420
|
-
this.options.tiers,
|
|
35421
|
-
this.options.scopeGate,
|
|
35422
|
-
this.options.runRatio,
|
|
35423
|
-
this.options.scheduledTasks,
|
|
35424
|
-
this.options.unblockDependents,
|
|
35425
|
-
excludedBundleNames
|
|
35426
|
-
);
|
|
35427
|
-
if (conventionsContent !== orchestratorRule.content) {
|
|
35428
|
-
ruleMap.set("orchestrator-conventions", {
|
|
35429
|
-
...orchestratorRule,
|
|
35430
|
-
content: conventionsContent
|
|
35431
|
-
});
|
|
35432
|
-
}
|
|
35433
|
-
}
|
|
35434
|
-
}
|
|
35435
35929
|
const injectBundleHooks = this.options.claudeMd?.injectBundleHooks ?? true;
|
|
35436
35930
|
const resolvedProgressFiles = resolveProgressFiles(
|
|
35437
35931
|
this.options.progressFiles
|
|
35438
35932
|
);
|
|
35439
|
-
if (this.options.progressFiles) {
|
|
35440
|
-
const progressRule = ruleMap.get("progress-file-convention");
|
|
35441
|
-
if (progressRule) {
|
|
35442
|
-
const progressContent = renderProgressFilesRuleContent(
|
|
35443
|
-
resolvedProgressFiles
|
|
35444
|
-
);
|
|
35445
|
-
if (progressContent !== progressRule.content) {
|
|
35446
|
-
ruleMap.set("progress-file-convention", {
|
|
35447
|
-
...progressRule,
|
|
35448
|
-
content: progressContent
|
|
35449
|
-
});
|
|
35450
|
-
}
|
|
35451
|
-
}
|
|
35452
|
-
}
|
|
35453
35933
|
if (injectBundleHooks && resolvedProgressFiles.enabled) {
|
|
35454
35934
|
for (const [ruleName, label] of PROGRESS_FILE_BUNDLE_HOOKS) {
|
|
35455
35935
|
const existing = ruleMap.get(ruleName);
|
|
@@ -35476,20 +35956,6 @@ ${hook}`
|
|
|
35476
35956
|
const resolvedSharedEditingForRules = resolveSharedEditing(
|
|
35477
35957
|
this.options.sharedEditing
|
|
35478
35958
|
);
|
|
35479
|
-
if (this.options.sharedEditing) {
|
|
35480
|
-
const sharedEditingRule = ruleMap.get("shared-editing-safety");
|
|
35481
|
-
if (sharedEditingRule) {
|
|
35482
|
-
const sharedEditingContent = renderSharedEditingRuleContent(
|
|
35483
|
-
resolvedSharedEditingForRules
|
|
35484
|
-
);
|
|
35485
|
-
if (sharedEditingContent !== sharedEditingRule.content) {
|
|
35486
|
-
ruleMap.set("shared-editing-safety", {
|
|
35487
|
-
...sharedEditingRule,
|
|
35488
|
-
content: sharedEditingContent
|
|
35489
|
-
});
|
|
35490
|
-
}
|
|
35491
|
-
}
|
|
35492
|
-
}
|
|
35493
35959
|
if (injectBundleHooks && resolvedSharedEditingForRules.enabled) {
|
|
35494
35960
|
for (const [ruleName, label] of SHARED_EDITING_BUNDLE_HOOKS) {
|
|
35495
35961
|
const existing = ruleMap.get(ruleName);
|
|
@@ -35516,20 +35982,6 @@ ${hook}`
|
|
|
35516
35982
|
const resolvedSkillEvalsForRules = resolveSkillEvals(
|
|
35517
35983
|
this.options.skillEvals
|
|
35518
35984
|
);
|
|
35519
|
-
if (this.options.skillEvals) {
|
|
35520
|
-
const skillEvalsRule = ruleMap.get("skill-evals");
|
|
35521
|
-
if (skillEvalsRule) {
|
|
35522
|
-
const skillEvalsContent = renderSkillEvalsRuleContent(
|
|
35523
|
-
resolvedSkillEvalsForRules
|
|
35524
|
-
);
|
|
35525
|
-
if (skillEvalsContent !== skillEvalsRule.content) {
|
|
35526
|
-
ruleMap.set("skill-evals", {
|
|
35527
|
-
...skillEvalsRule,
|
|
35528
|
-
content: skillEvalsContent
|
|
35529
|
-
});
|
|
35530
|
-
}
|
|
35531
|
-
}
|
|
35532
|
-
}
|
|
35533
35985
|
if (injectBundleHooks && resolvedSkillEvalsForRules.enabled) {
|
|
35534
35986
|
for (const [ruleName, label] of SKILL_EVALS_BUNDLE_HOOKS) {
|
|
35535
35987
|
const existing = ruleMap.get(ruleName);
|
|
@@ -35557,21 +36009,6 @@ ${hook}`
|
|
|
35557
36009
|
this.options.issueTemplates
|
|
35558
36010
|
);
|
|
35559
36011
|
const hasDownstreamBundles = hasAnyDownstreamIssueKindBundle(excludedBundleNames);
|
|
35560
|
-
if (this.options.issueTemplates || !hasDownstreamBundles) {
|
|
35561
|
-
const issueTemplatesRule = ruleMap.get("issue-templates-convention");
|
|
35562
|
-
if (issueTemplatesRule) {
|
|
35563
|
-
const issueTemplatesContent = renderIssueTemplatesRuleContent(
|
|
35564
|
-
resolvedIssueTemplatesForRules,
|
|
35565
|
-
hasDownstreamBundles
|
|
35566
|
-
);
|
|
35567
|
-
if (issueTemplatesContent !== issueTemplatesRule.content) {
|
|
35568
|
-
ruleMap.set("issue-templates-convention", {
|
|
35569
|
-
...issueTemplatesRule,
|
|
35570
|
-
content: issueTemplatesContent
|
|
35571
|
-
});
|
|
35572
|
-
}
|
|
35573
|
-
}
|
|
35574
|
-
}
|
|
35575
36012
|
if (injectBundleHooks && resolvedIssueTemplatesForRules.enabled && hasDownstreamBundles) {
|
|
35576
36013
|
for (const [ruleName, label] of ISSUE_TEMPLATES_BUNDLE_HOOKS) {
|
|
35577
36014
|
const existing = ruleMap.get(ruleName);
|
|
@@ -35595,23 +36032,6 @@ ${hook}`
|
|
|
35595
36032
|
});
|
|
35596
36033
|
}
|
|
35597
36034
|
}
|
|
35598
|
-
const resolvedTemporalFramingForRules = resolveTemporalFraming(
|
|
35599
|
-
this.options.temporalFraming
|
|
35600
|
-
);
|
|
35601
|
-
if (this.options.temporalFraming) {
|
|
35602
|
-
const temporalFramingRule = ruleMap.get("temporal-framing-convention");
|
|
35603
|
-
if (temporalFramingRule) {
|
|
35604
|
-
const temporalFramingContent = renderTemporalFramingRuleContent(
|
|
35605
|
-
resolvedTemporalFramingForRules
|
|
35606
|
-
);
|
|
35607
|
-
if (temporalFramingContent !== temporalFramingRule.content) {
|
|
35608
|
-
ruleMap.set("temporal-framing-convention", {
|
|
35609
|
-
...temporalFramingRule,
|
|
35610
|
-
content: temporalFramingContent
|
|
35611
|
-
});
|
|
35612
|
-
}
|
|
35613
|
-
}
|
|
35614
|
-
}
|
|
35615
36035
|
const tierExamples = this.options.features?.sourceTierExamples;
|
|
35616
36036
|
if (_AgentConfig.hasActiveTierExamples(tierExamples)) {
|
|
35617
36037
|
const sourceRule = ruleMap.get("source-quality-verification");
|
|
@@ -41836,6 +42256,7 @@ export {
|
|
|
41836
42256
|
DEFAULT_API_EXTRACTOR_REPORT_FILENAME,
|
|
41837
42257
|
DEFAULT_API_EXTRACTOR_REPORT_FOLDER,
|
|
41838
42258
|
DEFAULT_AUDIT_REPORT_DIR,
|
|
42259
|
+
DEFAULT_BASE_CONVENTIONS,
|
|
41839
42260
|
DEFAULT_BUILD_POLICY,
|
|
41840
42261
|
DEFAULT_BUNDLE_OVERRIDES,
|
|
41841
42262
|
DEFAULT_DECOMPOSITION_TEMPLATE,
|
|
@@ -41852,6 +42273,7 @@ export {
|
|
|
41852
42273
|
DEFAULT_ISSUE_TEMPLATES_PATH,
|
|
41853
42274
|
DEFAULT_ISSUE_TEMPLATES_REQUIRE_REFERENCE,
|
|
41854
42275
|
DEFAULT_OFF_PEAK_CRON_EXAMPLE,
|
|
42276
|
+
DEFAULT_ORCHESTRATOR_CONVENTIONS,
|
|
41855
42277
|
DEFAULT_PARTIAL_UNBLOCK_COMMENT_TEMPLATE,
|
|
41856
42278
|
DEFAULT_PATHS_EXEMPT_FROM_SIZE,
|
|
41857
42279
|
DEFAULT_PRIORITY_LABELS,
|
|
@@ -41864,6 +42286,7 @@ export {
|
|
|
41864
42286
|
DEFAULT_REQUIREMENT_CATEGORY_DIRS,
|
|
41865
42287
|
DEFAULT_REQUIRE_PRODUCT_CONTEXT,
|
|
41866
42288
|
DEFAULT_RESOLVED_ISSUE_DEFAULTS,
|
|
42289
|
+
DEFAULT_RULE_CONVENTIONS,
|
|
41867
42290
|
DEFAULT_SAMPLE_COMPILER_OPTIONS,
|
|
41868
42291
|
DEFAULT_SCHEDULED_TASKS_ROOT,
|
|
41869
42292
|
DEFAULT_SCHEDULED_TASK_ENTRIES,
|
|
@@ -41967,6 +42390,7 @@ export {
|
|
|
41967
42390
|
buildIndustryDiscoveryBundle,
|
|
41968
42391
|
buildMaintenanceAuditBundle,
|
|
41969
42392
|
buildMeetingAnalysisBundle,
|
|
42393
|
+
buildOrchestratorBundle,
|
|
41970
42394
|
buildOrchestratorConventionsContent,
|
|
41971
42395
|
buildPeopleProfileBundle,
|
|
41972
42396
|
buildPrReviewBundle,
|
|
@@ -41982,6 +42406,7 @@ export {
|
|
|
41982
42406
|
buildUnblockDependentsProcedure,
|
|
41983
42407
|
bundleNameForWorkflowRule,
|
|
41984
42408
|
businessModelsBundle,
|
|
42409
|
+
checkClosingKeywordsProcedure,
|
|
41985
42410
|
checkDocSamplesProcedure,
|
|
41986
42411
|
checkLinksProcedure,
|
|
41987
42412
|
classifyIssueScope,
|
|
@@ -42056,6 +42481,7 @@ export {
|
|
|
42056
42481
|
renderCdkRollback,
|
|
42057
42482
|
renderCdkSynth,
|
|
42058
42483
|
renderCdkWatch,
|
|
42484
|
+
renderCheckClosingKeywordsScript,
|
|
42059
42485
|
renderCheckDocSamplesProcedure,
|
|
42060
42486
|
renderCheckLinksProcedure,
|
|
42061
42487
|
renderCustomDocSectionBlock,
|