@codedrifters/configulator 0.0.298 → 0.0.299
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 +49 -14
- package/lib/index.d.ts +49 -14
- package/lib/index.js +482 -128
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +480 -128
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
package/lib/index.mjs
CHANGED
|
@@ -1080,6 +1080,47 @@ var awsCdkBundle = {
|
|
|
1080
1080
|
"- When adding a `NodejsFunction` with a bundled handler, ensure the `entry` path is explicitly configured",
|
|
1081
1081
|
"- Verify the entry is included in the build tool config (e.g., tsup entry list) so the runtime can find the handler",
|
|
1082
1082
|
"",
|
|
1083
|
+
"## Lambda Construct Encapsulation",
|
|
1084
|
+
"",
|
|
1085
|
+
"When a Lambda construct is event-driven, it should own:",
|
|
1086
|
+
"",
|
|
1087
|
+
"- The EventBridge Rule (or other trigger) that routes events to itself.",
|
|
1088
|
+
"- The IAM permissions it needs on resources passed in via props.",
|
|
1089
|
+
"",
|
|
1090
|
+
"Pass the resources (event bus, table, queue, etc.) into the Lambda",
|
|
1091
|
+
"construct's props rather than defining triggers and grants in the",
|
|
1092
|
+
"enclosing workflow or service. The Lambda construct then becomes",
|
|
1093
|
+
'self-describing \u2014 "what triggers me, what I write to" lives in one',
|
|
1094
|
+
"file \u2014 and reverting or refactoring a single Lambda doesn't ripple",
|
|
1095
|
+
"through unrelated constructs.",
|
|
1096
|
+
"",
|
|
1097
|
+
"```typescript",
|
|
1098
|
+
"export interface MyLambdaProps {",
|
|
1099
|
+
" readonly eventBus: IEventBus;",
|
|
1100
|
+
" readonly dataStoreTable: ITable;",
|
|
1101
|
+
"}",
|
|
1102
|
+
"",
|
|
1103
|
+
"export class MyLambda extends Construct {",
|
|
1104
|
+
" public readonly lambda: NodejsFunction;",
|
|
1105
|
+
" public readonly rule: Rule;",
|
|
1106
|
+
"",
|
|
1107
|
+
" constructor(scope: Construct, props: MyLambdaProps) {",
|
|
1108
|
+
' super(scope, "my-lambda");',
|
|
1109
|
+
"",
|
|
1110
|
+
' this.lambda = new NodejsFunction(this, "handler", { /* ... */ });',
|
|
1111
|
+
" props.dataStoreTable.grantReadWriteData(this.lambda);",
|
|
1112
|
+
' this.rule = new Rule(this, "rule", {',
|
|
1113
|
+
" eventBus: props.eventBus,",
|
|
1114
|
+
" eventPattern: { /* ... */ },",
|
|
1115
|
+
" targets: [new LambdaFunction(this.lambda)],",
|
|
1116
|
+
" });",
|
|
1117
|
+
" }",
|
|
1118
|
+
"}",
|
|
1119
|
+
"```",
|
|
1120
|
+
"",
|
|
1121
|
+
"A workflow or service construct then composes these Lambda constructs",
|
|
1122
|
+
"without owning their triggers or grants directly.",
|
|
1123
|
+
"",
|
|
1083
1124
|
"## CDK Testing",
|
|
1084
1125
|
"",
|
|
1085
1126
|
"- Mock `Code.fromAsset` in any test file that synthesizes CDK stacks",
|
|
@@ -13193,11 +13234,10 @@ function shellSingleQuote(value) {
|
|
|
13193
13234
|
}
|
|
13194
13235
|
|
|
13195
13236
|
// src/agent/bundles/orchestrator.ts
|
|
13196
|
-
function buildCheckBlockedScript(tiers, scopeGate,
|
|
13237
|
+
function buildCheckBlockedScript(tiers, scopeGate, _runRatio) {
|
|
13197
13238
|
const tierCase = renderAgentTierCaseStatement(tiers);
|
|
13198
13239
|
const scopeHelper = renderScopeGateShellHelpers(scopeGate);
|
|
13199
13240
|
const scopeHelperIndented = scopeHelper.split("\n").map((line) => line.length > 0 ? line : "").join("\n");
|
|
13200
|
-
const runRatioHelper = renderRunRatioShellHelpers(runRatio);
|
|
13201
13241
|
return [
|
|
13202
13242
|
"#!/usr/bin/env bash",
|
|
13203
13243
|
"# check-blocked.sh \u2014 Token-efficient issue triage for agent loops.",
|
|
@@ -13209,9 +13249,9 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio) {
|
|
|
13209
13249
|
"# .claude/procedures/check-blocked.sh eligible",
|
|
13210
13250
|
"# .claude/procedures/check-blocked.sh stale",
|
|
13211
13251
|
"# .claude/procedures/check-blocked.sh orphaned",
|
|
13252
|
+
"# .claude/procedures/check-blocked.sh maintenance",
|
|
13212
13253
|
"# .claude/procedures/check-blocked.sh prs",
|
|
13213
13254
|
"# .claude/procedures/check-blocked.sh scope <issue-number>",
|
|
13214
|
-
"# .claude/procedures/check-blocked.sh tick",
|
|
13215
13255
|
"",
|
|
13216
13256
|
"set -uo pipefail",
|
|
13217
13257
|
"",
|
|
@@ -13225,9 +13265,6 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio) {
|
|
|
13225
13265
|
`SCOPE_AC_MEDIUM_MAX=${scopeGate.acceptanceCriteria.mediumMax}`,
|
|
13226
13266
|
`SCOPE_SOURCES_SMALL_MAX=${scopeGate.sources.smallMax}`,
|
|
13227
13267
|
`SCOPE_SOURCES_MEDIUM_MAX=${scopeGate.sources.mediumMax}`,
|
|
13228
|
-
`RUN_RATIO_ENABLED=${runRatio.enabled ? "1" : "0"}`,
|
|
13229
|
-
`RUN_RATIO_DISPATCH_PER_HOUSEKEEPING=${runRatio.ratio}`,
|
|
13230
|
-
`ORCHESTRATOR_STATE_FILE="${runRatio.stateFilePath}"`,
|
|
13231
13268
|
"",
|
|
13232
13269
|
"# \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",
|
|
13233
13270
|
"",
|
|
@@ -13258,8 +13295,6 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio) {
|
|
|
13258
13295
|
"",
|
|
13259
13296
|
scopeHelperIndented,
|
|
13260
13297
|
"",
|
|
13261
|
-
runRatioHelper,
|
|
13262
|
-
"",
|
|
13263
13298
|
"# \u2500\u2500 subcommands \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",
|
|
13264
13299
|
"",
|
|
13265
13300
|
"cmd_unblock() {",
|
|
@@ -13270,7 +13305,7 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio) {
|
|
|
13270
13305
|
" local count",
|
|
13271
13306
|
` count=$(echo "$issues" | jq 'length')`,
|
|
13272
13307
|
' if [[ "$count" -eq 0 ]]; then',
|
|
13273
|
-
' echo "
|
|
13308
|
+
' echo "TRIAGE_DONE unblocked=0 still_blocked=0"',
|
|
13274
13309
|
" return 0",
|
|
13275
13310
|
" fi",
|
|
13276
13311
|
"",
|
|
@@ -13281,18 +13316,36 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio) {
|
|
|
13281
13316
|
' "\\(.number)\\t\\($dep_line)"',
|
|
13282
13317
|
" ')",
|
|
13283
13318
|
"",
|
|
13319
|
+
" # Counters for the summary line. The orchestrator reads only",
|
|
13320
|
+
" # TRIAGE_DONE; the per-issue lines below are for log visibility,",
|
|
13321
|
+
" # mirroring unblock-dependents.sh.",
|
|
13322
|
+
" local unblocked_count=0",
|
|
13323
|
+
" local still_blocked_count=0",
|
|
13324
|
+
"",
|
|
13284
13325
|
" while IFS=$'\\t' read -r num dep_line; do",
|
|
13285
13326
|
' [[ -z "$num" ]] && continue',
|
|
13286
13327
|
"",
|
|
13287
13328
|
' if [[ -z "$dep_line" ]]; then',
|
|
13288
13329
|
' echo "BLOCKED #${num} \u2014 no Depends on field found"',
|
|
13330
|
+
" still_blocked_count=$((still_blocked_count + 1))",
|
|
13289
13331
|
" continue",
|
|
13290
13332
|
" fi",
|
|
13291
13333
|
"",
|
|
13292
13334
|
" local deps",
|
|
13293
13335
|
' deps=$(parse_deps "$dep_line")',
|
|
13294
13336
|
' if [[ -z "${deps// /}" ]]; then',
|
|
13295
|
-
|
|
13337
|
+
" # Empty dependency list \u2014 treat as eligible for unblocking.",
|
|
13338
|
+
' if gh issue edit "$num" \\',
|
|
13339
|
+
' --remove-label "status:blocked" \\',
|
|
13340
|
+
' --add-label "status:ready" >/dev/null 2>&1; then',
|
|
13341
|
+
' gh issue comment "$num" \\',
|
|
13342
|
+
' --body "Dependencies resolved \u2014 unblocking." >/dev/null 2>&1 || true',
|
|
13343
|
+
' echo "UNBLOCKED #${num} \u2014 no dependencies"',
|
|
13344
|
+
" unblocked_count=$((unblocked_count + 1))",
|
|
13345
|
+
" else",
|
|
13346
|
+
' echo "UNBLOCK_FAILED #${num} \u2014 label flip failed (no dependencies)"',
|
|
13347
|
+
" still_blocked_count=$((still_blocked_count + 1))",
|
|
13348
|
+
" fi",
|
|
13296
13349
|
" continue",
|
|
13297
13350
|
" fi",
|
|
13298
13351
|
"",
|
|
@@ -13309,11 +13362,30 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio) {
|
|
|
13309
13362
|
" done",
|
|
13310
13363
|
"",
|
|
13311
13364
|
" if $all_closed; then",
|
|
13312
|
-
|
|
13365
|
+
" # The label flip is the load-bearing edit; if it fails we must",
|
|
13366
|
+
" # report the failure so the orchestrator does not double-count.",
|
|
13367
|
+
" # The comment is best-effort (its absence is recoverable on the",
|
|
13368
|
+
" # next sweep), so a failed `gh issue comment` does not block the",
|
|
13369
|
+
" # unblock from being recorded as successful.",
|
|
13370
|
+
' if gh issue edit "$num" \\',
|
|
13371
|
+
' --remove-label "status:blocked" \\',
|
|
13372
|
+
' --add-label "status:ready" >/dev/null 2>&1; then',
|
|
13373
|
+
' gh issue comment "$num" \\',
|
|
13374
|
+
' --body "Dependencies resolved \u2014 unblocking." >/dev/null 2>&1 || true',
|
|
13375
|
+
' echo "UNBLOCKED #${num} \u2014 all deps closed (${closed_deps% })"',
|
|
13376
|
+
" unblocked_count=$((unblocked_count + 1))",
|
|
13377
|
+
" else",
|
|
13378
|
+
' echo "UNBLOCK_FAILED #${num} \u2014 label flip failed (all deps closed: ${closed_deps% })"',
|
|
13379
|
+
" still_blocked_count=$((still_blocked_count + 1))",
|
|
13380
|
+
" fi",
|
|
13313
13381
|
" else",
|
|
13314
|
-
' echo "
|
|
13382
|
+
' echo "STILL_BLOCKED #${num} \u2014 waiting on ${open_deps% }"',
|
|
13383
|
+
" still_blocked_count=$((still_blocked_count + 1))",
|
|
13315
13384
|
" fi",
|
|
13316
13385
|
' done <<< "$issue_data"',
|
|
13386
|
+
"",
|
|
13387
|
+
" # Single summary line consumed by the orchestrator.",
|
|
13388
|
+
' echo "TRIAGE_DONE unblocked=${unblocked_count} still_blocked=${still_blocked_count}"',
|
|
13317
13389
|
"}",
|
|
13318
13390
|
"",
|
|
13319
13391
|
"cmd_eligible() {",
|
|
@@ -13505,6 +13577,101 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio) {
|
|
|
13505
13577
|
" fi",
|
|
13506
13578
|
"}",
|
|
13507
13579
|
"",
|
|
13580
|
+
"cmd_maintenance() {",
|
|
13581
|
+
" # Phase D maintenance sweep: flag stale issues with",
|
|
13582
|
+
" # `status:needs-attention`, count orphan branches/PRs (no",
|
|
13583
|
+
" # auto-deletion), and emit a single MAINTENANCE_DONE summary",
|
|
13584
|
+
" # line so the orchestrator never iterates raw stale/orphan",
|
|
13585
|
+
" # output. Mirrors the discipline of cmd_unblock \u2014 per-issue",
|
|
13586
|
+
" # informational lines (FLAGGED #N, ORPHAN_BRANCH \u2026) survive",
|
|
13587
|
+
" # for log visibility but are not load-bearing for the",
|
|
13588
|
+
" # orchestrator.",
|
|
13589
|
+
" #",
|
|
13590
|
+
" # SAFETY: this subcommand NEVER auto-resets stale issues to",
|
|
13591
|
+
" # `status:ready`. It only adds `status:needs-attention`; the",
|
|
13592
|
+
" # existing `status:in-progress` or `status:blocked` label",
|
|
13593
|
+
" # stays in place so partial implementation work on a branch",
|
|
13594
|
+
" # remains visible to humans.",
|
|
13595
|
+
"",
|
|
13596
|
+
" local flagged_stale_count=0",
|
|
13597
|
+
" local flagged_blocked_count=0",
|
|
13598
|
+
" local orphan_branches_count=0",
|
|
13599
|
+
" local orphan_prs_count=0",
|
|
13600
|
+
"",
|
|
13601
|
+
" # \u2500\u2500 stale detection + flagging \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",
|
|
13602
|
+
" local stale_output",
|
|
13603
|
+
" stale_output=$(cmd_stale)",
|
|
13604
|
+
"",
|
|
13605
|
+
" while IFS= read -r line; do",
|
|
13606
|
+
' [[ -z "$line" ]] && continue',
|
|
13607
|
+
' case "$line" in',
|
|
13608
|
+
" 'STALE #'*)",
|
|
13609
|
+
" # Extract the issue number after the '#' and before the ' '.",
|
|
13610
|
+
" local num=${line#STALE #}",
|
|
13611
|
+
" num=${num%% *}",
|
|
13612
|
+
' if gh issue edit "$num" --add-label "status:needs-attention" >/dev/null 2>&1; then',
|
|
13613
|
+
' gh issue comment "$num" \\',
|
|
13614
|
+
' --body "Flagged: in-progress for >3 days with no activity." >/dev/null 2>&1 || true',
|
|
13615
|
+
' echo "FLAGGED_STALE #${num} \u2014 added status:needs-attention"',
|
|
13616
|
+
" flagged_stale_count=$((flagged_stale_count + 1))",
|
|
13617
|
+
" else",
|
|
13618
|
+
' echo "FLAG_FAILED #${num} \u2014 could not add status:needs-attention (stale)"',
|
|
13619
|
+
" fi",
|
|
13620
|
+
" # Surface the original informational line for log visibility.",
|
|
13621
|
+
' echo "$line"',
|
|
13622
|
+
" ;;",
|
|
13623
|
+
" 'STALE_BLOCKED #'*)",
|
|
13624
|
+
" local num=${line#STALE_BLOCKED #}",
|
|
13625
|
+
" num=${num%% *}",
|
|
13626
|
+
' if gh issue edit "$num" --add-label "status:needs-attention" >/dev/null 2>&1; then',
|
|
13627
|
+
' gh issue comment "$num" \\',
|
|
13628
|
+
' --body "Flagged: blocked for >7 days \u2014 may need human intervention." >/dev/null 2>&1 || true',
|
|
13629
|
+
' echo "FLAGGED_BLOCKED #${num} \u2014 added status:needs-attention"',
|
|
13630
|
+
" flagged_blocked_count=$((flagged_blocked_count + 1))",
|
|
13631
|
+
" else",
|
|
13632
|
+
' echo "FLAG_FAILED #${num} \u2014 could not add status:needs-attention (blocked)"',
|
|
13633
|
+
" fi",
|
|
13634
|
+
' echo "$line"',
|
|
13635
|
+
" ;;",
|
|
13636
|
+
" 'NO_STALE_ISSUES')",
|
|
13637
|
+
" # Surface the no-op marker for log visibility; counters",
|
|
13638
|
+
" # stay at zero.",
|
|
13639
|
+
' echo "$line"',
|
|
13640
|
+
" ;;",
|
|
13641
|
+
" esac",
|
|
13642
|
+
' done <<< "$stale_output"',
|
|
13643
|
+
"",
|
|
13644
|
+
" # \u2500\u2500 orphan detection (count only \u2014 no auto-deletion) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
13645
|
+
" local orphan_output",
|
|
13646
|
+
" orphan_output=$(cmd_orphaned)",
|
|
13647
|
+
"",
|
|
13648
|
+
" while IFS= read -r line; do",
|
|
13649
|
+
' [[ -z "$line" ]] && continue',
|
|
13650
|
+
' case "$line" in',
|
|
13651
|
+
" 'ORPHAN_BRANCH '*)",
|
|
13652
|
+
" orphan_branches_count=$((orphan_branches_count + 1))",
|
|
13653
|
+
' echo "$line"',
|
|
13654
|
+
" ;;",
|
|
13655
|
+
" 'ORPHAN_PR '*)",
|
|
13656
|
+
" orphan_prs_count=$((orphan_prs_count + 1))",
|
|
13657
|
+
' echo "$line"',
|
|
13658
|
+
" ;;",
|
|
13659
|
+
" 'NO_ORPHANED_RESOURCES')",
|
|
13660
|
+
' echo "$line"',
|
|
13661
|
+
" ;;",
|
|
13662
|
+
" esac",
|
|
13663
|
+
' done <<< "$orphan_output"',
|
|
13664
|
+
"",
|
|
13665
|
+
" # \u2500\u2500 needs-attention total \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",
|
|
13666
|
+
" local needs_attention_total",
|
|
13667
|
+
' needs_attention_total=$(gh issue list --label "status:needs-attention" --state open \\',
|
|
13668
|
+
" --json number --limit 100 2>/dev/null | jq 'length' 2>/dev/null || echo 0)",
|
|
13669
|
+
" needs_attention_total=${needs_attention_total:-0}",
|
|
13670
|
+
"",
|
|
13671
|
+
" # Single summary line consumed by the orchestrator.",
|
|
13672
|
+
' echo "MAINTENANCE_DONE flagged_stale=${flagged_stale_count} flagged_blocked=${flagged_blocked_count} orphan_branches=${orphan_branches_count} orphan_prs=${orphan_prs_count} needs_attention_total=${needs_attention_total}"',
|
|
13673
|
+
"}",
|
|
13674
|
+
"",
|
|
13508
13675
|
"cmd_prs() {",
|
|
13509
13676
|
" local prs",
|
|
13510
13677
|
" prs=$(gh pr list --state open --json number,title,isDraft,headRefName,labels,body \\",
|
|
@@ -13643,31 +13810,18 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio) {
|
|
|
13643
13810
|
" fi",
|
|
13644
13811
|
"}",
|
|
13645
13812
|
"",
|
|
13646
|
-
"cmd_tick() {",
|
|
13647
|
-
" # DEPRECATED: the orchestrator no longer maintains a dispatch /",
|
|
13648
|
-
" # housekeeping run-counter \u2014 every invocation runs the full",
|
|
13649
|
-
" # end-to-end cycle. This subcommand is retained as a no-op for one",
|
|
13650
|
-
" # release so any consumer mid-flight does not error out, then will",
|
|
13651
|
-
" # be removed entirely. Existing state files at",
|
|
13652
|
-
' # "$ORCHESTRATOR_STATE_FILE" can be left alone (they will become',
|
|
13653
|
-
" # orphaned).",
|
|
13654
|
-
' echo "tick: deprecated no-op (orchestrator runs a single linear cycle every invocation)" >&2',
|
|
13655
|
-
' echo "run=0 type=dispatch (deprecated)"',
|
|
13656
|
-
" return 0",
|
|
13657
|
-
"}",
|
|
13658
|
-
"",
|
|
13659
13813
|
"# \u2500\u2500 main \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",
|
|
13660
13814
|
"",
|
|
13661
13815
|
'case "${1:-help}" in',
|
|
13662
|
-
' unblock)
|
|
13663
|
-
' eligible)
|
|
13664
|
-
' stale)
|
|
13665
|
-
' orphaned)
|
|
13666
|
-
'
|
|
13667
|
-
'
|
|
13668
|
-
'
|
|
13816
|
+
' unblock) shift; cmd_unblock "$@" ;;',
|
|
13817
|
+
' eligible) shift; cmd_eligible "$@" ;;',
|
|
13818
|
+
' stale) shift; cmd_stale "$@" ;;',
|
|
13819
|
+
' orphaned) shift; cmd_orphaned "$@" ;;',
|
|
13820
|
+
' maintenance) shift; cmd_maintenance "$@" ;;',
|
|
13821
|
+
' prs) shift; cmd_prs "$@" ;;',
|
|
13822
|
+
' scope) shift; cmd_scope "$@" ;;',
|
|
13669
13823
|
" help|*)",
|
|
13670
|
-
' echo "Usage: check-blocked.sh <unblock|eligible|stale|orphaned|prs|scope
|
|
13824
|
+
' echo "Usage: check-blocked.sh <unblock|eligible|stale|orphaned|maintenance|prs|scope>"',
|
|
13671
13825
|
" exit 1",
|
|
13672
13826
|
" ;;",
|
|
13673
13827
|
"esac"
|
|
@@ -13676,7 +13830,7 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio) {
|
|
|
13676
13830
|
function buildCheckBlockedProcedure(tiers, scopeGate = resolveScopeGate(), runRatio = resolveRunRatio()) {
|
|
13677
13831
|
return {
|
|
13678
13832
|
name: "check-blocked.sh",
|
|
13679
|
-
description: "Token-efficient issue triage script with subcommands: eligible, unblock, stale, orphaned, prs, scope
|
|
13833
|
+
description: "Token-efficient issue triage script with subcommands: eligible, unblock, stale, orphaned, maintenance, prs, scope. Sorts eligible issues by priority desc \u2192 funnel tier asc \u2192 issue number asc; the scope subcommand classifies a single issue against the scope-gate thresholds; the unblock subcommand applies the `status:blocked` \u2192 `status:ready` label flip itself, posts the canned unblock comment, and emits a single `TRIAGE_DONE unblocked=N still_blocked=M` summary line; the maintenance subcommand flags stale issues with `status:needs-attention` (never auto-resets to `status:ready`), counts orphan branches/PRs, and emits a single `MAINTENANCE_DONE flagged_stale=N flagged_blocked=M orphan_branches=A orphan_prs=B needs_attention_total=T` summary line.",
|
|
13680
13834
|
content: buildCheckBlockedScript(tiers, scopeGate, runRatio)
|
|
13681
13835
|
};
|
|
13682
13836
|
}
|
|
@@ -13695,6 +13849,59 @@ function buildUnblockDependentsProcedure(unblockDependents = resolveUnblockDepen
|
|
|
13695
13849
|
var unblockDependentsProcedure = buildUnblockDependentsProcedure(
|
|
13696
13850
|
resolveUnblockDependents()
|
|
13697
13851
|
);
|
|
13852
|
+
function buildPrSweepScript() {
|
|
13853
|
+
return [
|
|
13854
|
+
"#!/usr/bin/env bash",
|
|
13855
|
+
"# pr-sweep.sh \u2014 Token-efficient PR-eligibility filter for the",
|
|
13856
|
+
"# orchestrator's Phase B PR review sweep. Emits one summary line",
|
|
13857
|
+
"# per open PR; the orchestrator reads only the PR numbers and",
|
|
13858
|
+
"# dispatches `pr-reviewer` per eligible PR.",
|
|
13859
|
+
"#",
|
|
13860
|
+
"# Skip rules:",
|
|
13861
|
+
"# - isDraft = true \u2192 reason=draft",
|
|
13862
|
+
"# - review:human-required label \u2192 reason=human-required",
|
|
13863
|
+
"# - review:awaiting-human label \u2192 reason=awaiting-human",
|
|
13864
|
+
"#",
|
|
13865
|
+
"# Usage:",
|
|
13866
|
+
"# .claude/procedures/pr-sweep.sh",
|
|
13867
|
+
"",
|
|
13868
|
+
"set -uo pipefail",
|
|
13869
|
+
"",
|
|
13870
|
+
"prs=$(gh pr list --state open --json number,isDraft,labels \\",
|
|
13871
|
+
' --limit 50 2>/dev/null || echo "[]")',
|
|
13872
|
+
"",
|
|
13873
|
+
`count=$(echo "$prs" | jq 'length')`,
|
|
13874
|
+
'if [[ "$count" -eq 0 ]]; then',
|
|
13875
|
+
' echo "NO_OPEN_PRS"',
|
|
13876
|
+
" exit 0",
|
|
13877
|
+
"fi",
|
|
13878
|
+
"",
|
|
13879
|
+
"# Emit one PR_ELIGIBLE / PR_SKIP line per open PR, sorted by PR",
|
|
13880
|
+
"# number ascending so the order is deterministic across runs.",
|
|
13881
|
+
`echo "$prs" | jq -r '`,
|
|
13882
|
+
" sort_by(.number) |",
|
|
13883
|
+
" .[] |",
|
|
13884
|
+
" (.labels | map(.name)) as $labels |",
|
|
13885
|
+
" if .isDraft then",
|
|
13886
|
+
' "PR_SKIP #\\(.number) reason=draft"',
|
|
13887
|
+
' elif ($labels | index("review:human-required")) then',
|
|
13888
|
+
' "PR_SKIP #\\(.number) reason=human-required"',
|
|
13889
|
+
' elif ($labels | index("review:awaiting-human")) then',
|
|
13890
|
+
' "PR_SKIP #\\(.number) reason=awaiting-human"',
|
|
13891
|
+
" else",
|
|
13892
|
+
' "PR_ELIGIBLE #\\(.number)"',
|
|
13893
|
+
" end",
|
|
13894
|
+
"'"
|
|
13895
|
+
].join("\n");
|
|
13896
|
+
}
|
|
13897
|
+
function buildPrSweepProcedure() {
|
|
13898
|
+
return {
|
|
13899
|
+
name: "pr-sweep.sh",
|
|
13900
|
+
description: "Token-efficient PR-eligibility filter for the orchestrator's Phase B PR review sweep. Emits one `PR_ELIGIBLE #<n>` or `PR_SKIP #<n> reason=<draft|human-required|awaiting-human>` line per open PR; the orchestrator reads only the eligible numbers and dispatches `pr-reviewer` per eligible PR.",
|
|
13901
|
+
content: buildPrSweepScript()
|
|
13902
|
+
};
|
|
13903
|
+
}
|
|
13904
|
+
var prSweepProcedure = buildPrSweepProcedure();
|
|
13698
13905
|
var orchestratorSubAgent = {
|
|
13699
13906
|
name: "orchestrator",
|
|
13700
13907
|
description: "End-to-end pipeline manager that runs one full cycle every invocation: triage \u2192 maintenance \u2192 queue scan \u2192 delegate the picked issue to the issue-worker \u2192 cleanup",
|
|
@@ -13705,13 +13912,16 @@ var orchestratorSubAgent = {
|
|
|
13705
13912
|
"# Orchestrator Agent",
|
|
13706
13913
|
"",
|
|
13707
13914
|
"You are the pipeline orchestrator for the **{{repository.owner}}/{{repository.name}}** repository.",
|
|
13708
|
-
"Each invocation runs **one full end-to-end cycle**. The cycle
|
|
13709
|
-
"
|
|
13710
|
-
"
|
|
13711
|
-
"
|
|
13712
|
-
"
|
|
13713
|
-
"
|
|
13714
|
-
"
|
|
13915
|
+
"Each invocation runs **one full end-to-end cycle**. The cycle pulls",
|
|
13916
|
+
"the default branch, sweeps eligible open PRs through the `pr-reviewer`",
|
|
13917
|
+
"sub-agent, triages blocked issues, runs maintenance scans, picks the",
|
|
13918
|
+
"next ready issue, and **delegates implementation to the `issue-worker`**",
|
|
13919
|
+
"sub-agent in scheduled mode. The orchestrator itself never implements",
|
|
13920
|
+
"code, creates branches, pushes commits, or merges PRs \u2014 it routes",
|
|
13921
|
+
"work to other agents. The merge decision is still owned by the",
|
|
13922
|
+
"`pr-reviewer` sub-agent; the orchestrator only chooses which PRs the",
|
|
13923
|
+
"reviewer should look at and dispatches one reviewer session per",
|
|
13924
|
+
"eligible PR.",
|
|
13715
13925
|
"",
|
|
13716
13926
|
"Run the phases below in order on every invocation. There is no",
|
|
13717
13927
|
"dispatch/housekeeping fork \u2014 every phase runs every time.",
|
|
@@ -13719,16 +13929,20 @@ var orchestratorSubAgent = {
|
|
|
13719
13929
|
"Phase ordering (each runs exactly once per invocation):",
|
|
13720
13930
|
"",
|
|
13721
13931
|
"1. **Phase A \u2014 Startup.** Pull the default branch.",
|
|
13722
|
-
"2. **Phase
|
|
13932
|
+
"2. **Phase B \u2014 PR Review Sweep.** Read the procedure-script's",
|
|
13933
|
+
" eligibility summary and dispatch the `pr-reviewer` sub-agent",
|
|
13934
|
+
" in scheduled mode against each eligible open PR. Failures on",
|
|
13935
|
+
" one PR never stop the sweep.",
|
|
13936
|
+
"3. **Phase C \u2014 Triage / Unblock.** Flip dependents that have all",
|
|
13723
13937
|
" their dependencies closed back to `status:ready`.",
|
|
13724
|
-
"
|
|
13938
|
+
"4. **Phase D \u2014 Maintenance.** Stale-issue and orphaned-resource scan",
|
|
13725
13939
|
" plus a needs-attention summary.",
|
|
13726
|
-
"
|
|
13940
|
+
"5. **Phase E \u2014 Queue Scan.** Pick the highest-priority `PICK` line",
|
|
13727
13941
|
" and run the scope gate. If the result is `large`, flag and stop.",
|
|
13728
|
-
"
|
|
13942
|
+
"6. **Phase G \u2014 Delegate Implementation.** Hand the picked issue off",
|
|
13729
13943
|
" to the `issue-worker` sub-agent in scheduled mode. The worker",
|
|
13730
13944
|
" handles claim \u2192 branch \u2192 implement \u2192 commit \u2192 PR autonomously.",
|
|
13731
|
-
"
|
|
13945
|
+
"7. **Phase F \u2014 Cleanup.** Return to the default branch and log the",
|
|
13732
13946
|
" run summary.",
|
|
13733
13947
|
"",
|
|
13734
13948
|
"Phase letters are stable identifiers \u2014 letters skipped in the list",
|
|
@@ -13747,76 +13961,160 @@ var orchestratorSubAgent = {
|
|
|
13747
13961
|
"git checkout main && git pull origin main",
|
|
13748
13962
|
"```",
|
|
13749
13963
|
"",
|
|
13750
|
-
"## Phase
|
|
13964
|
+
"## Phase B: PR Review Sweep",
|
|
13965
|
+
"",
|
|
13966
|
+
"Sweep every open PR through the `pr-reviewer` sub-agent before the",
|
|
13967
|
+
"queue scan so a single `/orchestrate` invocation merges ready PRs",
|
|
13968
|
+
"and dispatches new issue work in one pass.",
|
|
13969
|
+
"",
|
|
13970
|
+
"### Step 1 \u2014 read the eligibility summary",
|
|
13751
13971
|
"",
|
|
13752
|
-
"
|
|
13972
|
+
"Run the bundled `pr-sweep.sh` procedure and read **only** the",
|
|
13973
|
+
"summary lines it emits. Do **not** iterate raw `gh pr list` JSON",
|
|
13974
|
+
"yourself \u2014 the procedure is the single source of PR-eligibility",
|
|
13975
|
+
"metadata, mirroring the discipline of Phase E's bucketed queue scan.",
|
|
13753
13976
|
"",
|
|
13754
13977
|
"```bash",
|
|
13755
|
-
".claude/procedures/
|
|
13978
|
+
".claude/procedures/pr-sweep.sh",
|
|
13756
13979
|
"```",
|
|
13757
13980
|
"",
|
|
13758
|
-
"
|
|
13759
|
-
"unblocking. Every agent that applies `status:done` already runs",
|
|
13760
|
-
"`.claude/procedures/unblock-dependents.sh <n>` as part of that",
|
|
13761
|
-
"transition, so in steady state Phase C should usually report",
|
|
13762
|
-
"`NO_BLOCKED_ISSUES` or leave dependents untouched. Phase C still",
|
|
13763
|
-
"runs on every cycle so issues that slipped through \u2014 human",
|
|
13764
|
-
"closures, manual `status:done` edits, or crashes mid-sweep \u2014 get",
|
|
13765
|
-
"picked up within one cycle. See the **Agent-driven",
|
|
13766
|
-
"unblocking** section in `CLAUDE.md` for the per-agent contract.",
|
|
13981
|
+
"Each line follows one of these shapes:",
|
|
13767
13982
|
"",
|
|
13768
|
-
"
|
|
13769
|
-
"
|
|
13770
|
-
|
|
13771
|
-
|
|
13983
|
+
"```",
|
|
13984
|
+
"PR_ELIGIBLE #<n>",
|
|
13985
|
+
"PR_SKIP #<n> reason=draft",
|
|
13986
|
+
"PR_SKIP #<n> reason=human-required",
|
|
13987
|
+
"PR_SKIP #<n> reason=awaiting-human",
|
|
13772
13988
|
"```",
|
|
13773
13989
|
"",
|
|
13774
|
-
"
|
|
13775
|
-
"catch it if it's been blocked too long).",
|
|
13990
|
+
"Skip rules (PRs that never reach the reviewer in this sweep):",
|
|
13776
13991
|
"",
|
|
13777
|
-
"
|
|
13992
|
+
"- `isDraft: true` \u2192 `reason=draft` (the author has not yet asked for review)",
|
|
13993
|
+
"- Carries the `review:human-required` label \u2192 `reason=human-required`",
|
|
13994
|
+
" (operator override \u2014 the reviewer's auto-merge path is forbidden)",
|
|
13995
|
+
"- Carries the `review:awaiting-human` label \u2192 `reason=awaiting-human`",
|
|
13996
|
+
" (the reviewer already handed off; a human is the next actor)",
|
|
13778
13997
|
"",
|
|
13779
|
-
"
|
|
13998
|
+
"If the script emits `NO_OPEN_PRS`, log the empty result and skip",
|
|
13999
|
+
"directly to Phase C.",
|
|
13780
14000
|
"",
|
|
13781
|
-
"###
|
|
14001
|
+
"### Step 2 \u2014 dispatch the reviewer per eligible PR",
|
|
13782
14002
|
"",
|
|
13783
|
-
"
|
|
13784
|
-
"
|
|
13785
|
-
"
|
|
14003
|
+
"For each `PR_ELIGIBLE #<n>` line in the order the procedure",
|
|
14004
|
+
"emitted them, invoke the `pr-reviewer` sub-agent **in scheduled",
|
|
14005
|
+
"mode** with the brief below. Substitute `<n>` with the PR number",
|
|
14006
|
+
"from the line.",
|
|
14007
|
+
"",
|
|
14008
|
+
"> `scheduled mode`: review PR #<n>. Run the full review pipeline",
|
|
14009
|
+
"> (eligibility, AC checklist, CI status, policy decision, sticky",
|
|
14010
|
+
"> reviewer-notes update) and either enable squash auto-merge or",
|
|
14011
|
+
"> apply `review:awaiting-human`. Do not pause for approval.",
|
|
14012
|
+
"> Return a one-line summary as the final line of your response in",
|
|
14013
|
+
"> the form `REVIEWER_DONE pr:#<n> outcome:<merged|awaiting-human|commented>`",
|
|
14014
|
+
"> on success or `REVIEWER_FAILED pr:#<n> reason:<short>` on failure.",
|
|
14015
|
+
"",
|
|
14016
|
+
"The orchestrator does **not** call `gh pr merge`, apply review",
|
|
14017
|
+
"labels, or post review comments directly \u2014 the reviewer's existing",
|
|
14018
|
+
"logic owns merge dispatch, AC verification, and the sticky",
|
|
14019
|
+
"`## Reviewer notes` comment. Phase B is a thin invoker, not an",
|
|
14020
|
+
"absorber.",
|
|
14021
|
+
"",
|
|
14022
|
+
"### Step 3 \u2014 failure semantics",
|
|
14023
|
+
"",
|
|
14024
|
+
"A single PR's reviewer failure (missing or malformed",
|
|
14025
|
+
"`REVIEWER_*` final line, sub-agent error, CI flake) **never stops",
|
|
14026
|
+
"the sweep**. Log the failure as",
|
|
14027
|
+
"`REVIEWER_FAILED pr:#<n> reason:<observed>` and continue to the",
|
|
14028
|
+
"next eligible PR. The next orchestrator invocation re-scans the",
|
|
14029
|
+
"PR list and re-dispatches the reviewer if the PR is still",
|
|
14030
|
+
"eligible.",
|
|
14031
|
+
"",
|
|
14032
|
+
"After every eligible PR has been processed (or zero eligible PRs",
|
|
14033
|
+
"were emitted), continue to Phase C regardless of outcomes.",
|
|
14034
|
+
"",
|
|
14035
|
+
"## Phase C: Triage \u2014 Unblock",
|
|
14036
|
+
"",
|
|
14037
|
+
"Run the bundled `check-blocked.sh unblock` procedure and read",
|
|
14038
|
+
"**only** the final `TRIAGE_DONE` summary line it emits. The",
|
|
14039
|
+
"procedure applies the label flips (`status:blocked` \u2192",
|
|
14040
|
+
"`status:ready`) and posts the canned",
|
|
14041
|
+
"`Dependencies resolved \u2014 unblocking.` comment itself, mirroring",
|
|
14042
|
+
"the discipline of Phase B (`pr-sweep.sh`) and Phase E",
|
|
14043
|
+
"(`check-blocked.sh eligible`) \u2014 the orchestrator never iterates",
|
|
14044
|
+
"raw `gh` responses, only the procedure's summary lines.",
|
|
13786
14045
|
"",
|
|
13787
|
-
"For each `STALE #N` line (in-progress >72h without activity):",
|
|
13788
14046
|
"```bash",
|
|
13789
|
-
|
|
13790
|
-
'gh issue comment N --body "Flagged: in-progress for >3 days with no activity."',
|
|
14047
|
+
".claude/procedures/check-blocked.sh unblock",
|
|
13791
14048
|
"```",
|
|
13792
14049
|
"",
|
|
13793
|
-
"
|
|
13794
|
-
"
|
|
13795
|
-
'gh issue edit N --add-label "status:needs-attention"',
|
|
13796
|
-
'gh issue comment N --body "Flagged: blocked for >7 days \u2014 may need human intervention."',
|
|
14050
|
+
"The script emits one summary line in this shape:",
|
|
14051
|
+
"",
|
|
13797
14052
|
"```",
|
|
14053
|
+
"TRIAGE_DONE unblocked=<N> still_blocked=<M>",
|
|
14054
|
+
"```",
|
|
14055
|
+
"",
|
|
14056
|
+
"Per-issue informational lines (`UNBLOCKED #N`, `UNBLOCK_FAILED #N`,",
|
|
14057
|
+
"`STILL_BLOCKED #N`, `BLOCKED #N \u2014 no Depends on field found`) are",
|
|
14058
|
+
"emitted for log visibility but are **not** load-bearing for the",
|
|
14059
|
+
"orchestrator \u2014 partial failures (one bad `gh` call) do not abort",
|
|
14060
|
+
"the sweep, they are simply counted toward `still_blocked`.",
|
|
14061
|
+
"",
|
|
14062
|
+
"This phase is the **fallback safety net** for agent-driven",
|
|
14063
|
+
"unblocking. Every agent that applies `status:done` already runs",
|
|
14064
|
+
"`.claude/procedures/unblock-dependents.sh <n>` as part of that",
|
|
14065
|
+
"transition, so in steady state Phase C should usually report",
|
|
14066
|
+
"`TRIAGE_DONE unblocked=0 still_blocked=0` or leave dependents",
|
|
14067
|
+
"untouched. Phase C still runs on every cycle so issues that",
|
|
14068
|
+
"slipped through \u2014 human closures, manual `status:done` edits, or",
|
|
14069
|
+
"crashes mid-sweep \u2014 get picked up within one cycle. See the",
|
|
14070
|
+
"**Agent-driven unblocking** section in `CLAUDE.md` for the",
|
|
14071
|
+
"per-agent contract.",
|
|
14072
|
+
"",
|
|
14073
|
+
"Log the summary line and continue to Phase D regardless of",
|
|
14074
|
+
"outcomes \u2014 a non-zero `still_blocked` count is normal (issues",
|
|
14075
|
+
"with open dependencies stay blocked) and Phase D will surface",
|
|
14076
|
+
"any that have been blocked too long.",
|
|
13798
14077
|
"",
|
|
13799
|
-
"
|
|
13800
|
-
"implementation work may exist on a branch.",
|
|
14078
|
+
"## Phase D: Maintenance",
|
|
13801
14079
|
"",
|
|
13802
|
-
"
|
|
14080
|
+
"Run the bundled `check-blocked.sh maintenance` procedure and read",
|
|
14081
|
+
"**only** the final `MAINTENANCE_DONE` summary line it emits. The",
|
|
14082
|
+
"procedure folds the stale-detection, orphan-detection, and",
|
|
14083
|
+
"needs-attention summary that earlier revisions split across D1,",
|
|
14084
|
+
"D2, and D3 into a single sweep \u2014 applying the",
|
|
14085
|
+
"`status:needs-attention` label and posting the canned flag comment",
|
|
14086
|
+
"for each stale / stale-blocked issue itself, mirroring the",
|
|
14087
|
+
"discipline of Phase B (`pr-sweep.sh`) and Phase C",
|
|
14088
|
+
"(`check-blocked.sh unblock`).",
|
|
13803
14089
|
"",
|
|
13804
14090
|
"```bash",
|
|
13805
|
-
".claude/procedures/check-blocked.sh
|
|
14091
|
+
".claude/procedures/check-blocked.sh maintenance",
|
|
13806
14092
|
"```",
|
|
13807
14093
|
"",
|
|
13808
|
-
"
|
|
13809
|
-
"or PRs whose linked issues are closed or missing. Log them for visibility",
|
|
13810
|
-
"but do not delete branches automatically.",
|
|
13811
|
-
"",
|
|
13812
|
-
"### D3: Needs-Attention Summary",
|
|
14094
|
+
"The script emits one summary line in this shape:",
|
|
13813
14095
|
"",
|
|
13814
|
-
"
|
|
13815
|
-
"
|
|
13816
|
-
'gh issue list --label "status:needs-attention" --state open --json number,title',
|
|
14096
|
+
"```",
|
|
14097
|
+
"MAINTENANCE_DONE flagged_stale=<N> flagged_blocked=<M> orphan_branches=<A> orphan_prs=<B> needs_attention_total=<T>",
|
|
13817
14098
|
"```",
|
|
13818
14099
|
"",
|
|
13819
|
-
"
|
|
14100
|
+
"Per-issue / per-orphan informational lines (`FLAGGED_STALE #N`,",
|
|
14101
|
+
"`FLAGGED_BLOCKED #N`, `STALE #N \u2014 \u2026`, `STALE_BLOCKED #N \u2014 \u2026`,",
|
|
14102
|
+
"`ORPHAN_BRANCH \u2026`, `ORPHAN_PR #N \u2014 \u2026`, `FLAG_FAILED #N \u2014 \u2026`) are",
|
|
14103
|
+
"emitted for log visibility but are **not** load-bearing for the",
|
|
14104
|
+
"orchestrator \u2014 partial failures (one bad `gh` call) do not abort",
|
|
14105
|
+
"the sweep, they are simply omitted from the `flagged_*` counters.",
|
|
14106
|
+
"",
|
|
14107
|
+
"**Important:** the script never auto-resets stale issues to",
|
|
14108
|
+
"`status:ready`. It only adds `status:needs-attention`; the",
|
|
14109
|
+
"existing `status:in-progress` or `status:blocked` label stays in",
|
|
14110
|
+
"place so partial implementation work on a branch remains visible",
|
|
14111
|
+
"to humans. Orphan branches and PRs are surfaced in the counters",
|
|
14112
|
+
"but are never deleted by the orchestrator \u2014 a human reviews the",
|
|
14113
|
+
"log lines and prunes orphans manually.",
|
|
14114
|
+
"",
|
|
14115
|
+
"Log the summary line and continue to Phase E regardless of",
|
|
14116
|
+
"outcomes \u2014 a non-zero `flagged_*` or `orphan_*` count is",
|
|
14117
|
+
"informational, not a failure.",
|
|
13820
14118
|
"",
|
|
13821
14119
|
"## Phase E: Queue Scan",
|
|
13822
14120
|
"",
|
|
@@ -13976,27 +14274,30 @@ var orchestratorSubAgent = {
|
|
|
13976
14274
|
"",
|
|
13977
14275
|
"1. **Never implement code.** You triage, scan, and delegate \u2014 you do not code.",
|
|
13978
14276
|
"2. **Never claim issues.** Do not add `status:in-progress` or create branches for issues. Phase G's `issue-worker` delegation is the only path that flips an issue's claim labels.",
|
|
13979
|
-
"3. **
|
|
13980
|
-
"4. **
|
|
13981
|
-
"5. **
|
|
13982
|
-
"6. **
|
|
13983
|
-
"7. **Never dispatch a `large` issue.** Always run the scope check",
|
|
14277
|
+
"3. **Always use procedure scripts.** Issue triage queries go through `.claude/procedures/check-blocked.sh`; PR-eligibility filtering goes through `.claude/procedures/pr-sweep.sh`. Never iterate raw `gh issue list` / `gh pr list` JSON in-context.",
|
|
14278
|
+
"4. **Follow CLAUDE.md conventions** for all git and gh operations.",
|
|
14279
|
+
"5. **Priority order:** critical > high > medium > low > trivial, then **funnel tier asc** (lower tier wins ties), then FIFO by issue number.",
|
|
14280
|
+
"6. **Never dispatch a `large` issue.** Always run the scope check",
|
|
13984
14281
|
" on the top `PICK` line before reporting `NEXT_WORK_ITEM`. A",
|
|
13985
14282
|
" `large` issue must be flagged with `status:needs-attention` and",
|
|
13986
14283
|
" handed a decomposition proposal \u2014 never claimed, never branched,",
|
|
13987
14284
|
" never delegated to the `issue-worker`.",
|
|
13988
|
-
"
|
|
14285
|
+
"7. **Sweep dependents whenever you apply `status:done`.** Every",
|
|
13989
14286
|
" `status:done` transition must be immediately followed by",
|
|
13990
14287
|
" `.claude/procedures/unblock-dependents.sh <n>` so downstream",
|
|
13991
14288
|
" `Depends on: #<n>` issues flip to `status:ready` without",
|
|
13992
14289
|
" waiting for the next cycle. See the **Agent-driven unblocking**",
|
|
13993
14290
|
" section in `CLAUDE.md` for the contract.",
|
|
13994
|
-
"
|
|
13995
|
-
"
|
|
13996
|
-
"
|
|
13997
|
-
"
|
|
13998
|
-
" the phrase the
|
|
13999
|
-
" delegation stalls."
|
|
14291
|
+
"8. **Always invoke child sub-agents in scheduled mode.** Phase B's",
|
|
14292
|
+
" `pr-reviewer` dispatch and Phase G's `issue-worker` delegation",
|
|
14293
|
+
" prompts must each contain the literal phrase `scheduled mode`",
|
|
14294
|
+
" so the child sub-agent skips its interactive approval pause and",
|
|
14295
|
+
" runs autonomously. Without the phrase the child pauses for",
|
|
14296
|
+
" human approval and the delegation stalls.",
|
|
14297
|
+
"9. **A failed reviewer never stops the sweep.** Phase B continues",
|
|
14298
|
+
" to the next eligible PR after a `REVIEWER_FAILED` line and",
|
|
14299
|
+
" proceeds to Phase C regardless of how many PRs failed. Do not",
|
|
14300
|
+
" abort the cycle on a single PR's reviewer failure."
|
|
14000
14301
|
].join("\n")
|
|
14001
14302
|
};
|
|
14002
14303
|
var issueWorkerSubAgent = {
|
|
@@ -14471,9 +14772,9 @@ var ORCHESTRATOR_CONVENTIONS_PREAMBLE = [
|
|
|
14471
14772
|
"",
|
|
14472
14773
|
"When running the orchestrator agent (`.claude/agents/orchestrator.md`):",
|
|
14473
14774
|
"",
|
|
14474
|
-
"- The orchestrator runs **one full end-to-end cycle every invocation**: triage / unblock \u2192 maintenance \u2192 queue scan \u2192 delegate to `issue-worker` \u2192 cleanup",
|
|
14475
|
-
"- The orchestrator **never** implements code, creates branches, pushes commits
|
|
14476
|
-
"- All triage queries use `.claude/procedures/check-blocked.sh` for token efficiency",
|
|
14775
|
+
"- The orchestrator runs **one full end-to-end cycle every invocation**: startup \u2192 PR review sweep \u2192 triage / unblock \u2192 maintenance \u2192 queue scan \u2192 delegate to `issue-worker` \u2192 cleanup",
|
|
14776
|
+
"- The orchestrator **never** implements code, creates branches, or pushes commits \u2014 it routes work to other sub-agents. The merge decision is still owned by the `pr-reviewer` sub-agent; Phase B only chooses which open PRs the reviewer should look at and dispatches one reviewer session per eligible PR (skipping drafts and any PR carrying `review:human-required` or `review:awaiting-human`).",
|
|
14777
|
+
"- All triage queries use `.claude/procedures/check-blocked.sh` for token efficiency. PR-eligibility filtering for Phase B uses `.claude/procedures/pr-sweep.sh`, which emits `PR_ELIGIBLE` / `PR_SKIP` lines so the orchestrator never iterates raw `gh pr list` JSON.",
|
|
14477
14778
|
"- The queue scan reads only `priority:*` and `status:*` labels \u2014 type-routing (which typed agent handles a given `type:*` label) is the `issue-worker`'s concern, not the orchestrator's. The orchestrator's funnel-tier sort is a tie-breaker on `priority:*`, not a routing decision.",
|
|
14478
14779
|
"- Priority order: critical > high > medium > low > trivial, then **funnel tier asc** (lower tier wins ties), then FIFO by issue number. Phase E's queue scan walks each priority bucket in turn (one `gh issue list` call per bucket, **capped at 50 issues per bucket**) and short-circuits on the first bucket whose survivors clear the `Depends on:` filter, so every higher-priority issue is visible even when the global ready backlog is much larger than 50.",
|
|
14479
14780
|
"- Stale thresholds: 72h for in-progress, 168h for blocked",
|
|
@@ -14481,11 +14782,11 @@ var ORCHESTRATOR_CONVENTIONS_PREAMBLE = [
|
|
|
14481
14782
|
"",
|
|
14482
14783
|
"## Depth-0 invocation requirement",
|
|
14483
14784
|
"",
|
|
14484
|
-
'The orchestrator agent **must run as the top-level (depth-0) session**
|
|
14785
|
+
'The orchestrator agent **must run as the top-level (depth-0) session** because both Phase B (PR review sweep) and Phase G (issue delegation) need to spawn child sub-agents. Phase B dispatches the `pr-reviewer` sub-agent once per eligible open PR; Phase G dispatches the `issue-worker` sub-agent against the picked issue. The Claude Code harness forbids nested sub-agent spawning \u2014 *"Subagents cannot spawn other subagents. If your workflow requires nested delegation, use Skills or chain subagents from the main conversation."* (see <https://code.claude.com/docs/en/sub-agents>). If the orchestrator itself were spawned as a depth-1 sub-agent (e.g. via `Agent(subagent_type: "orchestrator")` from another session), the `Agent` tool needed to reach `pr-reviewer` and `issue-worker` at depth-2 would not be available and both Phase B and Phase G would silently abort.',
|
|
14485
14786
|
"",
|
|
14486
|
-
'Practical implication for scheduled-task wiring: the `worker-orchestrator` scheduled task\'s `SKILL.md` instructs the **scheduled-task session itself** to read `.claude/agents/orchestrator.md` and execute its phase pipeline in-session, then use the `Agent` tool to delegate
|
|
14787
|
+
'Practical implication for scheduled-task wiring: the `worker-orchestrator` scheduled task\'s `SKILL.md` instructs the **scheduled-task session itself** to read `.claude/agents/orchestrator.md` and execute its phase pipeline in-session, then use the `Agent` tool to delegate to `pr-reviewer` (Phase B) and `issue-worker` (Phase G) at depth-1. The scheduled task does **not** call `Agent(subagent_type: "orchestrator")` \u2014 that would put the orchestrator at depth-1 and break both delegation chains.'
|
|
14487
14788
|
].join("\n");
|
|
14488
|
-
function buildOrchestratorConventionsContent(tiers, scopeGate = resolveScopeGate(),
|
|
14789
|
+
function buildOrchestratorConventionsContent(tiers, scopeGate = resolveScopeGate(), _runRatio = resolveRunRatio(), scheduledTasks = resolveScheduledTasks(), unblockDependents = resolveUnblockDependents(), excludeBundles = []) {
|
|
14489
14790
|
return [
|
|
14490
14791
|
ORCHESTRATOR_CONVENTIONS_PREAMBLE,
|
|
14491
14792
|
"",
|
|
@@ -14493,8 +14794,6 @@ function buildOrchestratorConventionsContent(tiers, scopeGate = resolveScopeGate
|
|
|
14493
14794
|
"",
|
|
14494
14795
|
renderScopeGateSection(scopeGate, excludeBundles),
|
|
14495
14796
|
"",
|
|
14496
|
-
renderRunRatioSection(runRatio),
|
|
14497
|
-
"",
|
|
14498
14797
|
renderScheduledTasksSection(scheduledTasks),
|
|
14499
14798
|
"",
|
|
14500
14799
|
renderUnblockDependentsSection(unblockDependents)
|
|
@@ -14563,13 +14862,18 @@ var checkBlockedCommand = {
|
|
|
14563
14862
|
'bash .claude/procedures/check-blocked.sh "$@"',
|
|
14564
14863
|
"```",
|
|
14565
14864
|
"",
|
|
14566
|
-
"Pass any extra arguments through verbatim. The
|
|
14567
|
-
"`status:blocked` issue, re-checks each `Depends on:`
|
|
14568
|
-
"
|
|
14569
|
-
"
|
|
14570
|
-
"",
|
|
14571
|
-
"
|
|
14572
|
-
"
|
|
14865
|
+
"Pass any extra arguments through verbatim. The `unblock` subcommand",
|
|
14866
|
+
"walks every `status:blocked` issue, re-checks each `Depends on:`",
|
|
14867
|
+
"reference, applies the `status:blocked` \u2192 `status:ready` label flip",
|
|
14868
|
+
"itself, posts the canned `Dependencies resolved \u2014 unblocking.`",
|
|
14869
|
+
"comment, and emits a single",
|
|
14870
|
+
"`TRIAGE_DONE unblocked=<N> still_blocked=<M>` summary line. Per-issue",
|
|
14871
|
+
"informational lines (`UNBLOCKED`, `UNBLOCK_FAILED`, `STILL_BLOCKED`)",
|
|
14872
|
+
"are also emitted for log visibility.",
|
|
14873
|
+
"",
|
|
14874
|
+
"Summarise the output (the `TRIAGE_DONE` counts and the first few",
|
|
14875
|
+
"per-issue lines) \u2014 do **not** apply additional label flips yourself;",
|
|
14876
|
+
"the script already transitioned every eligible issue.",
|
|
14573
14877
|
""
|
|
14574
14878
|
].join("\n")
|
|
14575
14879
|
};
|
|
@@ -14619,7 +14923,11 @@ var orchestratorBundle = {
|
|
|
14619
14923
|
}
|
|
14620
14924
|
],
|
|
14621
14925
|
subAgents: [orchestratorSubAgent, issueWorkerSubAgent],
|
|
14622
|
-
procedures: [
|
|
14926
|
+
procedures: [
|
|
14927
|
+
checkBlockedProcedure,
|
|
14928
|
+
unblockDependentsProcedure,
|
|
14929
|
+
prSweepProcedure
|
|
14930
|
+
],
|
|
14623
14931
|
commands: [orchestrateCommand, checkBlockedCommand, scanCommand],
|
|
14624
14932
|
claudePermissions: {
|
|
14625
14933
|
allow: [
|
|
@@ -27687,7 +27995,8 @@ function renderPriorityRulesSection(rules) {
|
|
|
27687
27995
|
}
|
|
27688
27996
|
|
|
27689
27997
|
// src/agent/bundles/index.ts
|
|
27690
|
-
function buildBuiltInBundles(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS, defaultAgentTier = AGENT_MODEL.BALANCED) {
|
|
27998
|
+
function buildBuiltInBundles(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAULT_RESOLVED_ISSUE_DEFAULTS, defaultAgentTier = AGENT_MODEL.BALANCED, bundleAgentTiers = /* @__PURE__ */ new Map()) {
|
|
27999
|
+
const tierFor = (bundle) => bundleAgentTiers.get(bundle) ?? defaultAgentTier;
|
|
27691
28000
|
return [
|
|
27692
28001
|
buildBaseBundle(paths),
|
|
27693
28002
|
upstreamConfigulatorDocsBundle,
|
|
@@ -27700,7 +28009,7 @@ function buildBuiltInBundles(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAUL
|
|
|
27700
28009
|
projenBundle,
|
|
27701
28010
|
githubWorkflowBundle,
|
|
27702
28011
|
slackBundle,
|
|
27703
|
-
buildMeetingAnalysisBundle(
|
|
28012
|
+
buildMeetingAnalysisBundle(tierFor("meeting-analysis")),
|
|
27704
28013
|
agendaBundle,
|
|
27705
28014
|
orchestratorBundle,
|
|
27706
28015
|
prReviewBundle,
|
|
@@ -27708,16 +28017,28 @@ function buildBuiltInBundles(paths = DEFAULT_AGENT_PATHS, issueDefaults = DEFAUL
|
|
|
27708
28017
|
buildRequirementsWriterBundle(paths, issueDefaults),
|
|
27709
28018
|
buildRequirementsReviewerBundle(paths, issueDefaults),
|
|
27710
28019
|
buildResearchPipelineBundle(paths, issueDefaults),
|
|
27711
|
-
buildCompanyProfileBundle(paths, issueDefaults,
|
|
27712
|
-
buildCustomerProfileBundle(
|
|
27713
|
-
|
|
27714
|
-
|
|
28020
|
+
buildCompanyProfileBundle(paths, issueDefaults, tierFor("company-profile")),
|
|
28021
|
+
buildCustomerProfileBundle(
|
|
28022
|
+
paths,
|
|
28023
|
+
issueDefaults,
|
|
28024
|
+
tierFor("customer-profile")
|
|
28025
|
+
),
|
|
28026
|
+
buildPeopleProfileBundle(paths, issueDefaults, tierFor("people-profile")),
|
|
28027
|
+
buildSoftwareProfileBundle(
|
|
28028
|
+
paths,
|
|
28029
|
+
issueDefaults,
|
|
28030
|
+
tierFor("software-profile")
|
|
28031
|
+
),
|
|
27715
28032
|
buildIndustryDiscoveryBundle(paths, issueDefaults),
|
|
27716
28033
|
buildBusinessModelsBundle(paths, issueDefaults),
|
|
27717
28034
|
buildBcmWriterBundle(paths, issueDefaults),
|
|
27718
28035
|
buildStandardsResearchBundle(paths, issueDefaults),
|
|
27719
28036
|
buildRegulatoryResearchBundle(paths, issueDefaults),
|
|
27720
|
-
buildMaintenanceAuditBundle(
|
|
28037
|
+
buildMaintenanceAuditBundle(
|
|
28038
|
+
paths,
|
|
28039
|
+
issueDefaults,
|
|
28040
|
+
tierFor("maintenance-audit")
|
|
28041
|
+
),
|
|
27721
28042
|
buildDocsSyncBundle(paths)
|
|
27722
28043
|
];
|
|
27723
28044
|
}
|
|
@@ -28352,8 +28673,8 @@ var CopilotRenderer = class {
|
|
|
28352
28673
|
};
|
|
28353
28674
|
|
|
28354
28675
|
// src/agent/agent-config.ts
|
|
28355
|
-
function
|
|
28356
|
-
switch (
|
|
28676
|
+
function mapAgentTier(value) {
|
|
28677
|
+
switch (value) {
|
|
28357
28678
|
case "powerful":
|
|
28358
28679
|
return AGENT_MODEL.POWERFUL;
|
|
28359
28680
|
case "fast":
|
|
@@ -28363,6 +28684,34 @@ function resolveDefaultAgentTier(options) {
|
|
|
28363
28684
|
return AGENT_MODEL.BALANCED;
|
|
28364
28685
|
}
|
|
28365
28686
|
}
|
|
28687
|
+
function resolveDefaultAgentTier(options) {
|
|
28688
|
+
return mapAgentTier(options?.defaultAgentTier);
|
|
28689
|
+
}
|
|
28690
|
+
var TIER_AWARE_BUNDLE_NAMES = [
|
|
28691
|
+
"company-profile",
|
|
28692
|
+
"customer-profile",
|
|
28693
|
+
"maintenance-audit",
|
|
28694
|
+
"meeting-analysis",
|
|
28695
|
+
"people-profile",
|
|
28696
|
+
"software-profile"
|
|
28697
|
+
];
|
|
28698
|
+
function resolveBundleAgentTiers(options) {
|
|
28699
|
+
const overrides = options?.bundleAgentTiers;
|
|
28700
|
+
if (!overrides) {
|
|
28701
|
+
return /* @__PURE__ */ new Map();
|
|
28702
|
+
}
|
|
28703
|
+
const validNames = new Set(TIER_AWARE_BUNDLE_NAMES);
|
|
28704
|
+
const out = /* @__PURE__ */ new Map();
|
|
28705
|
+
for (const [name, value] of Object.entries(overrides)) {
|
|
28706
|
+
if (!validNames.has(name)) {
|
|
28707
|
+
throw new Error(
|
|
28708
|
+
`bundleAgentTiers contains unknown bundle name "${name}". Valid names are: ${TIER_AWARE_BUNDLE_NAMES.join(", ")}.`
|
|
28709
|
+
);
|
|
28710
|
+
}
|
|
28711
|
+
out.set(name, mapAgentTier(value));
|
|
28712
|
+
}
|
|
28713
|
+
return out;
|
|
28714
|
+
}
|
|
28366
28715
|
var DEFAULT_CLAUDE_ALLOW = [
|
|
28367
28716
|
// ── Git ──────────────────────────────────────────────────────────────
|
|
28368
28717
|
"Bash(git add *)",
|
|
@@ -28715,7 +29064,8 @@ var AgentConfig = class _AgentConfig extends Component8 {
|
|
|
28715
29064
|
this.cachedBundles = buildBuiltInBundles(
|
|
28716
29065
|
this.resolvedPaths,
|
|
28717
29066
|
resolveIssueDefaults(this.options.issueDefaults),
|
|
28718
|
-
resolveDefaultAgentTier(this.options)
|
|
29067
|
+
resolveDefaultAgentTier(this.options),
|
|
29068
|
+
resolveBundleAgentTiers(this.options)
|
|
28719
29069
|
);
|
|
28720
29070
|
}
|
|
28721
29071
|
return this.cachedBundles;
|
|
@@ -33981,6 +34331,7 @@ export {
|
|
|
33981
34331
|
SUPPRESSED_WORKFLOW_RULE_NAMES,
|
|
33982
34332
|
SampleLang,
|
|
33983
34333
|
StarlightProject,
|
|
34334
|
+
TIER_AWARE_BUNDLE_NAMES,
|
|
33984
34335
|
TestRunner,
|
|
33985
34336
|
TsDocCoverageKind,
|
|
33986
34337
|
TurboRepo,
|
|
@@ -34113,6 +34464,7 @@ export {
|
|
|
34113
34464
|
resolveAgentTiers,
|
|
34114
34465
|
resolveAstroProjectOutdir,
|
|
34115
34466
|
resolveAwsCdkProjectOutdir,
|
|
34467
|
+
resolveBundleAgentTiers,
|
|
34116
34468
|
resolveDefaultAgentTier,
|
|
34117
34469
|
resolveIssueDefaults,
|
|
34118
34470
|
resolveIssueTemplates,
|