@codedrifters/configulator 0.0.287 → 0.0.289
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 +17 -249
- package/lib/index.d.ts +18 -250
- package/lib/index.js +307 -501
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +307 -493
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -206,7 +206,6 @@ __export(index_exports, {
|
|
|
206
206
|
DEFAULT_API_EXTRACTOR_REPORT_FOLDER: () => DEFAULT_API_EXTRACTOR_REPORT_FOLDER,
|
|
207
207
|
DEFAULT_AUDIT_REPORT_DIR: () => DEFAULT_AUDIT_REPORT_DIR,
|
|
208
208
|
DEFAULT_DECOMPOSITION_TEMPLATE: () => DEFAULT_DECOMPOSITION_TEMPLATE,
|
|
209
|
-
DEFAULT_DELEGATE_TO_PR_REVIEWER: () => DEFAULT_DELEGATE_TO_PR_REVIEWER,
|
|
210
209
|
DEFAULT_DISPATCH_MODEL: () => DEFAULT_DISPATCH_MODEL,
|
|
211
210
|
DEFAULT_DISPATCH_TO_HOUSEKEEPING_RATIO: () => DEFAULT_DISPATCH_TO_HOUSEKEEPING_RATIO,
|
|
212
211
|
DEFAULT_HOUSEKEEPING_MODEL: () => DEFAULT_HOUSEKEEPING_MODEL,
|
|
@@ -216,7 +215,6 @@ __export(index_exports, {
|
|
|
216
215
|
DEFAULT_ISSUE_TEMPLATES_ENABLED: () => DEFAULT_ISSUE_TEMPLATES_ENABLED,
|
|
217
216
|
DEFAULT_ISSUE_TEMPLATES_PATH: () => DEFAULT_ISSUE_TEMPLATES_PATH,
|
|
218
217
|
DEFAULT_ISSUE_TEMPLATES_REQUIRE_REFERENCE: () => DEFAULT_ISSUE_TEMPLATES_REQUIRE_REFERENCE,
|
|
219
|
-
DEFAULT_MERGE_METHOD: () => DEFAULT_MERGE_METHOD,
|
|
220
218
|
DEFAULT_OFF_PEAK_CRON_EXAMPLE: () => DEFAULT_OFF_PEAK_CRON_EXAMPLE,
|
|
221
219
|
DEFAULT_PARTIAL_UNBLOCK_COMMENT_TEMPLATE: () => DEFAULT_PARTIAL_UNBLOCK_COMMENT_TEMPLATE,
|
|
222
220
|
DEFAULT_PRIORITY_LABELS: () => DEFAULT_PRIORITY_LABELS,
|
|
@@ -226,7 +224,6 @@ __export(index_exports, {
|
|
|
226
224
|
DEFAULT_PROGRESS_FILES_FORMAT: () => DEFAULT_PROGRESS_FILES_FORMAT,
|
|
227
225
|
DEFAULT_PROGRESS_FILES_STALE_AFTER_HOURS: () => DEFAULT_PROGRESS_FILES_STALE_AFTER_HOURS,
|
|
228
226
|
DEFAULT_PROGRESS_FILES_STATE_DIR: () => DEFAULT_PROGRESS_FILES_STATE_DIR,
|
|
229
|
-
DEFAULT_REQUIRE_LINKED_ISSUE: () => DEFAULT_REQUIRE_LINKED_ISSUE,
|
|
230
227
|
DEFAULT_REQUIRE_PRODUCT_CONTEXT: () => DEFAULT_REQUIRE_PRODUCT_CONTEXT,
|
|
231
228
|
DEFAULT_SAMPLE_COMPILER_OPTIONS: () => DEFAULT_SAMPLE_COMPILER_OPTIONS,
|
|
232
229
|
DEFAULT_SCHEDULED_TASKS_ROOT: () => DEFAULT_SCHEDULED_TASKS_ROOT,
|
|
@@ -258,7 +255,6 @@ __export(index_exports, {
|
|
|
258
255
|
MINIMUM_RELEASE_AGE: () => MINIMUM_RELEASE_AGE,
|
|
259
256
|
MONOREPO_LAYOUT: () => MONOREPO_LAYOUT,
|
|
260
257
|
MonorepoProject: () => MonorepoProject,
|
|
261
|
-
PREFLIGHT_MERGE_METHOD_VALUES: () => PREFLIGHT_MERGE_METHOD_VALUES,
|
|
262
258
|
PROD_DEPLOY_NAME: () => PROD_DEPLOY_NAME,
|
|
263
259
|
PROGRESS_FILES_FORMAT_VALUES: () => PROGRESS_FILES_FORMAT_VALUES,
|
|
264
260
|
PnpmWorkspace: () => PnpmWorkspace,
|
|
@@ -362,8 +358,6 @@ __export(index_exports, {
|
|
|
362
358
|
renderIssueTemplatesRuleContent: () => renderIssueTemplatesRuleContent,
|
|
363
359
|
renderIssueTemplatesStarterPage: () => renderIssueTemplatesStarterPage,
|
|
364
360
|
renderMeetingTypesSection: () => renderMeetingTypesSection,
|
|
365
|
-
renderPreflightPrSection: () => renderPreflightPrSection,
|
|
366
|
-
renderPreflightPrShellHelpers: () => renderPreflightPrShellHelpers,
|
|
367
361
|
renderPriorityRulesSection: () => renderPriorityRulesSection,
|
|
368
362
|
renderProgressFileName: () => renderProgressFileName,
|
|
369
363
|
renderProgressFilePath: () => renderProgressFilePath,
|
|
@@ -396,7 +390,6 @@ __export(index_exports, {
|
|
|
396
390
|
resolveModelAlias: () => resolveModelAlias,
|
|
397
391
|
resolveOrchestratorAssets: () => resolveOrchestratorAssets,
|
|
398
392
|
resolveOutdirFromPackageName: () => resolveOutdirFromPackageName,
|
|
399
|
-
resolvePreflightPr: () => resolvePreflightPr,
|
|
400
393
|
resolveProgressFiles: () => resolveProgressFiles,
|
|
401
394
|
resolveRunRatio: () => resolveRunRatio,
|
|
402
395
|
resolveScheduledTasks: () => resolveScheduledTasks,
|
|
@@ -417,7 +410,6 @@ __export(index_exports, {
|
|
|
417
410
|
validateAgentTierConfig: () => validateAgentTierConfig,
|
|
418
411
|
validateIssueTemplatesConfig: () => validateIssueTemplatesConfig,
|
|
419
412
|
validateMonorepoLayout: () => validateMonorepoLayout,
|
|
420
|
-
validatePreflightPrConfig: () => validatePreflightPrConfig,
|
|
421
413
|
validateProgressFilesConfig: () => validateProgressFilesConfig,
|
|
422
414
|
validateRunRatioConfig: () => validateRunRatioConfig,
|
|
423
415
|
validateScheduledTasksConfig: () => validateScheduledTasksConfig,
|
|
@@ -11169,291 +11161,6 @@ var meetingAnalysisBundle = {
|
|
|
11169
11161
|
]
|
|
11170
11162
|
};
|
|
11171
11163
|
|
|
11172
|
-
// src/agent/bundles/preflight-pr.ts
|
|
11173
|
-
var DEFAULT_DELEGATE_TO_PR_REVIEWER = true;
|
|
11174
|
-
var DEFAULT_MERGE_METHOD = "squash";
|
|
11175
|
-
var DEFAULT_REQUIRE_LINKED_ISSUE = true;
|
|
11176
|
-
var PREFLIGHT_MERGE_METHOD_VALUES = [
|
|
11177
|
-
"squash",
|
|
11178
|
-
"merge",
|
|
11179
|
-
"rebase"
|
|
11180
|
-
];
|
|
11181
|
-
function resolvePreflightPr(config) {
|
|
11182
|
-
const mergeMethod = config?.mergeMethod ?? DEFAULT_MERGE_METHOD;
|
|
11183
|
-
assertValidMergeMethod(mergeMethod);
|
|
11184
|
-
const eligibleLabels = config?.eligibleLabels ?? [];
|
|
11185
|
-
assertValidEligibleLabels(eligibleLabels);
|
|
11186
|
-
return {
|
|
11187
|
-
enabled: config?.enabled ?? true,
|
|
11188
|
-
delegateToPrReviewer: config?.delegateToPrReviewer ?? DEFAULT_DELEGATE_TO_PR_REVIEWER,
|
|
11189
|
-
mergeMethod,
|
|
11190
|
-
requireLinkedIssue: config?.requireLinkedIssue ?? DEFAULT_REQUIRE_LINKED_ISSUE,
|
|
11191
|
-
eligibleLabels
|
|
11192
|
-
};
|
|
11193
|
-
}
|
|
11194
|
-
function validatePreflightPrConfig(config) {
|
|
11195
|
-
return resolvePreflightPr(config);
|
|
11196
|
-
}
|
|
11197
|
-
function renderPreflightPrSection(pf) {
|
|
11198
|
-
const lines = [
|
|
11199
|
-
"## Pre-flight PR merge",
|
|
11200
|
-
"",
|
|
11201
|
-
"The orchestrator runs a **pre-flight PR merge sweep** before its",
|
|
11202
|
-
"triage walk so already-approved, CI-green PRs land before the",
|
|
11203
|
-
"unblock and queue-scan phases read dependency state. Without",
|
|
11204
|
-
"pre-flight, an issue whose only remaining blocker is an approved",
|
|
11205
|
-
"PR stuck behind a branch-protection delay shows up as blocked on",
|
|
11206
|
-
"every dispatch cycle \u2014 the pipeline thrashes on stale dependency",
|
|
11207
|
-
"state.",
|
|
11208
|
-
""
|
|
11209
|
-
];
|
|
11210
|
-
if (!pf.enabled) {
|
|
11211
|
-
lines.push(
|
|
11212
|
-
"**Pre-flight is disabled for this project.** The orchestrator",
|
|
11213
|
-
"skips the pre-flight sweep entirely; PR merges land via the",
|
|
11214
|
-
"existing batch PR review step on housekeeping runs or via a",
|
|
11215
|
-
"human operator. Enable pre-flight via",
|
|
11216
|
-
"`AgentConfigOptions.preflightPr.enabled = true` once the repo",
|
|
11217
|
-
"is comfortable with automated merges.",
|
|
11218
|
-
""
|
|
11219
|
-
);
|
|
11220
|
-
return lines.join("\n");
|
|
11221
|
-
}
|
|
11222
|
-
lines.push(
|
|
11223
|
-
"### When pre-flight runs",
|
|
11224
|
-
"",
|
|
11225
|
-
"Pre-flight runs on **every orchestrator invocation** \u2014",
|
|
11226
|
-
"both dispatch and housekeeping runs \u2014 immediately after Phase A",
|
|
11227
|
-
"(Startup) and before any other phase reads issue or PR state. The",
|
|
11228
|
-
"sweep is idempotent: `gh pr merge` on an already-merged PR is a",
|
|
11229
|
-
"no-op, so re-running pre-flight on back-to-back invocations is",
|
|
11230
|
-
"safe and cheap.",
|
|
11231
|
-
"",
|
|
11232
|
-
"### Eligibility",
|
|
11233
|
-
"",
|
|
11234
|
-
"A PR is eligible for a pre-flight merge when **all** of the",
|
|
11235
|
-
"following hold:",
|
|
11236
|
-
"",
|
|
11237
|
-
"- PR is not draft and not closed.",
|
|
11238
|
-
"- PR is `MERGEABLE` (no branch conflicts).",
|
|
11239
|
-
"- Every required CI check has passed (`SUCCESS` or `SKIPPED`).",
|
|
11240
|
-
"- PR carries at least one `APPROVED` review **or** auto-merge is",
|
|
11241
|
-
" already enabled on the PR.",
|
|
11242
|
-
"- PR is not carrying `status:needs-attention`."
|
|
11243
|
-
);
|
|
11244
|
-
if (pf.requireLinkedIssue) {
|
|
11245
|
-
lines.push(
|
|
11246
|
-
"- PR body contains a `Closes #<n>` / `Fixes #<n>` / `Resolves`",
|
|
11247
|
-
" `#<n>` keyword referencing an open issue."
|
|
11248
|
-
);
|
|
11249
|
-
} else {
|
|
11250
|
-
lines.push(
|
|
11251
|
-
"- Linked-issue check is **disabled** for this project \u2014 PRs",
|
|
11252
|
-
" without a `Closes/Fixes/Resolves` keyword are eligible."
|
|
11253
|
-
);
|
|
11254
|
-
}
|
|
11255
|
-
if (pf.eligibleLabels.length > 0) {
|
|
11256
|
-
lines.push(
|
|
11257
|
-
"- PR carries at least one of the following consumer-declared",
|
|
11258
|
-
" eligibility labels:",
|
|
11259
|
-
"",
|
|
11260
|
-
...pf.eligibleLabels.map((label) => ` - \`${label}\``)
|
|
11261
|
-
);
|
|
11262
|
-
}
|
|
11263
|
-
lines.push(
|
|
11264
|
-
"",
|
|
11265
|
-
"PRs that fail any criterion are skipped with a one-line",
|
|
11266
|
-
"diagnostic and left for the `pr-reviewer` or a human operator to",
|
|
11267
|
-
"handle on the normal review path.",
|
|
11268
|
-
"",
|
|
11269
|
-
"### Execution mode",
|
|
11270
|
-
""
|
|
11271
|
-
);
|
|
11272
|
-
if (pf.delegateToPrReviewer) {
|
|
11273
|
-
lines.push(
|
|
11274
|
-
"**Delegate mode (default).** The orchestrator invokes the",
|
|
11275
|
-
"`pr-reviewer` sub-agent to run the pre-flight sweep. This",
|
|
11276
|
-
"mirrors vortex's step 0b contract: the merge workflow runs on",
|
|
11277
|
-
"its own (cheaper) model rather than consuming the orchestrator's",
|
|
11278
|
-
"more expensive model budget for mechanical merges.",
|
|
11279
|
-
"",
|
|
11280
|
-
"The sub-agent returns a one-line structured summary as the last",
|
|
11281
|
-
"line of its response:",
|
|
11282
|
-
"",
|
|
11283
|
-
"```",
|
|
11284
|
-
"Merged <n> (#<list>), skipped <m> (#<pr> \u2014 <reason>), <k> eligible left.",
|
|
11285
|
-
"```",
|
|
11286
|
-
"",
|
|
11287
|
-
"If the sub-agent's final line is missing, malformed, or",
|
|
11288
|
-
"indicates an error, the orchestrator **does not retry** \u2014 it",
|
|
11289
|
-
"proceeds to the next phase anyway. PR merges are idempotent at",
|
|
11290
|
-
"GitHub, so the next orchestrator session re-runs pre-flight.",
|
|
11291
|
-
"The only cost of a skipped sub-agent pass is that dependency",
|
|
11292
|
-
"issues stay open one more cycle."
|
|
11293
|
-
);
|
|
11294
|
-
} else {
|
|
11295
|
-
lines.push(
|
|
11296
|
-
"**Inline mode.** The orchestrator performs the pre-flight merge",
|
|
11297
|
-
"itself \u2014 it does **not** delegate to the `pr-reviewer`",
|
|
11298
|
-
"sub-agent. Use this mode in repos that prefer a single-process",
|
|
11299
|
-
"pipeline or that have not wired a `pr-reviewer` sub-agent.",
|
|
11300
|
-
"",
|
|
11301
|
-
`For each eligible PR, the orchestrator runs \`gh pr merge --${pf.mergeMethod}\``,
|
|
11302
|
-
"with `--delete-branch` and re-confirms that the linked issue",
|
|
11303
|
-
"closes (applying `status:done` if the auto-close did not fire)."
|
|
11304
|
-
);
|
|
11305
|
-
}
|
|
11306
|
-
lines.push(
|
|
11307
|
-
"",
|
|
11308
|
-
"### Post-merge verification",
|
|
11309
|
-
"",
|
|
11310
|
-
"After each successful merge, the orchestrator re-reads the linked",
|
|
11311
|
-
"issue state. When the merge commit did **not** auto-close the",
|
|
11312
|
-
"issue (closing-keyword typos, linked-issue keyword dropped during",
|
|
11313
|
-
"a rebase), the orchestrator closes the issue explicitly and",
|
|
11314
|
-
"applies `status:done` so the downstream unblock loop sees the",
|
|
11315
|
-
"dependency as resolved. This is the only way pre-flight prevents",
|
|
11316
|
-
"the stale-dependency thrash \u2014 without the verification step a",
|
|
11317
|
-
"merged-but-not-closed issue still reads as blocking to",
|
|
11318
|
-
"`check-blocked.sh unblock`."
|
|
11319
|
-
);
|
|
11320
|
-
return lines.join("\n");
|
|
11321
|
-
}
|
|
11322
|
-
function renderPreflightPrShellHelpers(pf) {
|
|
11323
|
-
const requireIssueFlag = pf.requireLinkedIssue ? "1" : "0";
|
|
11324
|
-
const hasLabelFilter = pf.eligibleLabels.length > 0;
|
|
11325
|
-
const lines = [
|
|
11326
|
-
"# Scan open PRs and emit one eligibility line per PR in the",
|
|
11327
|
-
"# canonical `PREFLIGHT_MERGE PR #<n> issue:#<m> branch:<b> \u2014",
|
|
11328
|
-
'# "<title>"` / `PREFLIGHT_SKIP PR #<n> \u2014 <reason> \u2014 "<title>"` /',
|
|
11329
|
-
"# `NO_PREFLIGHT_PRS` format. Orchestrator-side loops read this",
|
|
11330
|
-
"# output and either merge the PR inline or delegate the sweep to",
|
|
11331
|
-
"# the pr-reviewer sub-agent.",
|
|
11332
|
-
"cmd_preflight() {",
|
|
11333
|
-
' if [[ "$PREFLIGHT_ENABLED" != "1" ]]; then',
|
|
11334
|
-
' echo "NO_PREFLIGHT_PRS"',
|
|
11335
|
-
" return 0",
|
|
11336
|
-
" fi",
|
|
11337
|
-
" local prs",
|
|
11338
|
-
" prs=$(gh pr list --state open --json number,title,isDraft,mergeable,headRefName,labels,body,reviewDecision,autoMergeRequest \\",
|
|
11339
|
-
' --limit 50 2>/dev/null || echo "[]")',
|
|
11340
|
-
"",
|
|
11341
|
-
" local count",
|
|
11342
|
-
` count=$(echo "$prs" | jq 'length')`,
|
|
11343
|
-
' if [[ "$count" -eq 0 ]]; then',
|
|
11344
|
-
' echo "NO_PREFLIGHT_PRS"',
|
|
11345
|
-
" return 0",
|
|
11346
|
-
" fi",
|
|
11347
|
-
"",
|
|
11348
|
-
" # Stage 1: filter in jq on purely structural fields (draft,",
|
|
11349
|
-
" # labels, linked-issue keyword). CI state lives outside the",
|
|
11350
|
-
" # list endpoint so it is checked per-PR below.",
|
|
11351
|
-
" local candidates",
|
|
11352
|
-
` candidates=$(echo "$prs" | jq -r --arg require_issue "$PREFLIGHT_REQUIRE_LINKED_ISSUE" '`,
|
|
11353
|
-
" .[] |",
|
|
11354
|
-
" select(.isDraft == false) |",
|
|
11355
|
-
' select(.labels | map(.name) | index("status:needs-attention") | not) |'
|
|
11356
|
-
];
|
|
11357
|
-
if (hasLabelFilter) {
|
|
11358
|
-
const jqArray = pf.eligibleLabels.map((label) => `"${label.replace(/"/g, '\\"')}"`).join(",");
|
|
11359
|
-
lines.push(
|
|
11360
|
-
` select((.labels | map(.name)) as $names | [${jqArray}] | any(. as $l | $names | index($l))) |`
|
|
11361
|
-
);
|
|
11362
|
-
}
|
|
11363
|
-
lines.push(
|
|
11364
|
-
' (.body | capture("(?:Closes|Fixes|Resolves) #(?<num>[0-9]+)"; "i") | .num) as $issue |',
|
|
11365
|
-
' select($require_issue == "0" or ($issue != null and $issue != "")) |',
|
|
11366
|
-
' "\\(.number)\\t\\(.title)\\t\\(.headRefName)\\t\\($issue // "")\\t\\(.mergeable // "UNKNOWN")\\t\\(.reviewDecision // "")\\t\\((.autoMergeRequest // null) != null)"',
|
|
11367
|
-
" ' 2>/dev/null)",
|
|
11368
|
-
"",
|
|
11369
|
-
' if [[ -z "$candidates" ]]; then',
|
|
11370
|
-
' echo "NO_PREFLIGHT_PRS"',
|
|
11371
|
-
" return 0",
|
|
11372
|
-
" fi",
|
|
11373
|
-
"",
|
|
11374
|
-
" local found_eligible=false",
|
|
11375
|
-
" while IFS=$'\\t' read -r pr_num title branch issue_num mergeable review_decision auto_merge; do",
|
|
11376
|
-
' [[ -z "$pr_num" ]] && continue',
|
|
11377
|
-
"",
|
|
11378
|
-
" # Mergeable gate.",
|
|
11379
|
-
' if [[ "$mergeable" != "MERGEABLE" ]]; then',
|
|
11380
|
-
' echo "PREFLIGHT_SKIP PR #${pr_num} \u2014 not mergeable (${mergeable}) \u2014 \\"${title}\\""',
|
|
11381
|
-
" continue",
|
|
11382
|
-
" fi",
|
|
11383
|
-
"",
|
|
11384
|
-
" # Approval gate: APPROVED review OR auto-merge already",
|
|
11385
|
-
" # enabled. Either signal means a human has signed off on the",
|
|
11386
|
-
" # change; pre-flight only needs to wait for CI + branch",
|
|
11387
|
-
" # protection to clear.",
|
|
11388
|
-
' if [[ "$review_decision" != "APPROVED" && "$auto_merge" != "true" ]]; then',
|
|
11389
|
-
' echo "PREFLIGHT_SKIP PR #${pr_num} \u2014 not approved and auto-merge not set \u2014 \\"${title}\\""',
|
|
11390
|
-
" continue",
|
|
11391
|
-
" fi",
|
|
11392
|
-
"",
|
|
11393
|
-
" # CI gate. `gh pr checks` returns one row per check; anything",
|
|
11394
|
-
" # that is neither SUCCESS nor SKIPPED counts as failing or",
|
|
11395
|
-
" # pending.",
|
|
11396
|
-
" local failing_checks",
|
|
11397
|
-
' failing_checks=$(gh pr checks "$pr_num" --json name,state \\',
|
|
11398
|
-
` --jq '[.[] | select(.state != "SUCCESS" and .state != "SKIPPED")] | length' 2>/dev/null || echo "-1")`,
|
|
11399
|
-
"",
|
|
11400
|
-
' if [[ "$failing_checks" == "-1" ]]; then',
|
|
11401
|
-
' echo "PREFLIGHT_SKIP PR #${pr_num} \u2014 could not read CI status \u2014 \\"${title}\\""',
|
|
11402
|
-
" continue",
|
|
11403
|
-
" fi",
|
|
11404
|
-
"",
|
|
11405
|
-
' if [[ "$failing_checks" -gt 0 ]]; then',
|
|
11406
|
-
' echo "PREFLIGHT_SKIP PR #${pr_num} \u2014 ${failing_checks} CI check(s) not passing \u2014 \\"${title}\\""',
|
|
11407
|
-
" continue",
|
|
11408
|
-
" fi",
|
|
11409
|
-
"",
|
|
11410
|
-
" # Linked-issue state gate. A PR whose linked issue is already",
|
|
11411
|
-
" # closed should not block pre-flight \u2014 skip it so the unblock",
|
|
11412
|
-
" # loop picks up the dependency. This path also fires when the",
|
|
11413
|
-
" # PR was merged but the closing keyword was dropped.",
|
|
11414
|
-
' if [[ -n "$issue_num" ]]; then',
|
|
11415
|
-
" local issue_state",
|
|
11416
|
-
` issue_state=$(gh issue view "$issue_num" --json state --jq '.state' 2>/dev/null || echo "UNKNOWN")`,
|
|
11417
|
-
' if [[ "$issue_state" == "CLOSED" ]]; then',
|
|
11418
|
-
' echo "PREFLIGHT_SKIP PR #${pr_num} \u2014 linked issue #${issue_num} already closed \u2014 \\"${title}\\""',
|
|
11419
|
-
" continue",
|
|
11420
|
-
" fi",
|
|
11421
|
-
" fi",
|
|
11422
|
-
"",
|
|
11423
|
-
" found_eligible=true",
|
|
11424
|
-
' echo "PREFLIGHT_MERGE PR #${pr_num} issue:#${issue_num:-none} branch:${branch} \u2014 \\"${title}\\""',
|
|
11425
|
-
' done <<< "$candidates"',
|
|
11426
|
-
"",
|
|
11427
|
-
" if ! $found_eligible; then",
|
|
11428
|
-
' echo "NO_PREFLIGHT_PRS"',
|
|
11429
|
-
" fi",
|
|
11430
|
-
"}"
|
|
11431
|
-
);
|
|
11432
|
-
void requireIssueFlag;
|
|
11433
|
-
return lines.join("\n");
|
|
11434
|
-
}
|
|
11435
|
-
function assertValidMergeMethod(value) {
|
|
11436
|
-
if (!PREFLIGHT_MERGE_METHOD_VALUES.includes(value)) {
|
|
11437
|
-
throw new Error(
|
|
11438
|
-
`PreflightPrConfig.mergeMethod must be one of ${PREFLIGHT_MERGE_METHOD_VALUES.join(
|
|
11439
|
-
" | "
|
|
11440
|
-
)}; got ${JSON.stringify(value)}`
|
|
11441
|
-
);
|
|
11442
|
-
}
|
|
11443
|
-
}
|
|
11444
|
-
function assertValidEligibleLabels(labels) {
|
|
11445
|
-
for (let i = 0; i < labels.length; i += 1) {
|
|
11446
|
-
const label = labels[i];
|
|
11447
|
-
if (typeof label !== "string" || label.trim().length === 0) {
|
|
11448
|
-
throw new Error(
|
|
11449
|
-
`PreflightPrConfig.eligibleLabels[${i}] must be a non-empty string; got ${JSON.stringify(
|
|
11450
|
-
label
|
|
11451
|
-
)}`
|
|
11452
|
-
);
|
|
11453
|
-
}
|
|
11454
|
-
}
|
|
11455
|
-
}
|
|
11456
|
-
|
|
11457
11164
|
// src/agent/bundles/run-ratio.ts
|
|
11458
11165
|
var DEFAULT_DISPATCH_TO_HOUSEKEEPING_RATIO = 4;
|
|
11459
11166
|
var DEFAULT_STATE_FILE_PATH = ".state/orchestrator-runs.json";
|
|
@@ -11540,23 +11247,18 @@ function renderRunRatioSection(ratio) {
|
|
|
11540
11247
|
"### Dispatch-run pipeline",
|
|
11541
11248
|
"",
|
|
11542
11249
|
"1. Phase A \u2014 startup (fetch + checkout default branch).",
|
|
11543
|
-
"2. Phase
|
|
11544
|
-
"
|
|
11545
|
-
"3. Phase C \u2014 triage unblock (resolve `Depends on:` chains).",
|
|
11546
|
-
"4. Phase E \u2014 queue scan (pick the top `PICK` line, run the scope",
|
|
11250
|
+
"2. Phase C \u2014 triage unblock (resolve `Depends on:` chains).",
|
|
11251
|
+
"3. Phase E \u2014 queue scan (pick the top `PICK` line, run the scope",
|
|
11547
11252
|
" gate, emit `NEXT_WORK_ITEM`).",
|
|
11548
|
-
"
|
|
11253
|
+
"4. Phase F \u2014 cleanup.",
|
|
11549
11254
|
"",
|
|
11550
11255
|
"### Housekeeping-run pipeline",
|
|
11551
11256
|
"",
|
|
11552
11257
|
"1. Phase A \u2014 startup.",
|
|
11553
|
-
"2. Phase
|
|
11554
|
-
"
|
|
11555
|
-
" PRs land cleanly).",
|
|
11556
|
-
"3. Phase B \u2014 batch PR review across every eligible open PR.",
|
|
11557
|
-
"4. Phase D \u2014 maintenance scan (stale detection, orphaned branches,",
|
|
11258
|
+
"2. Phase B \u2014 batch PR review across every eligible open PR.",
|
|
11259
|
+
"3. Phase D \u2014 maintenance scan (stale detection, orphaned branches,",
|
|
11558
11260
|
" needs-attention summary).",
|
|
11559
|
-
"
|
|
11261
|
+
"4. Phase F \u2014 cleanup.",
|
|
11560
11262
|
"",
|
|
11561
11263
|
"### Model recommendations",
|
|
11562
11264
|
"",
|
|
@@ -11683,7 +11385,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
|
|
|
11683
11385
|
recommendedModel: "sonnet",
|
|
11684
11386
|
enabled: false,
|
|
11685
11387
|
cron: null,
|
|
11686
|
-
description: "End-to-end pipeline manager:
|
|
11388
|
+
description: "End-to-end pipeline manager: triage, maintenance, queue scan, delegate the picked issue to the issue-worker, then cleanup."
|
|
11687
11389
|
},
|
|
11688
11390
|
// Tier 1 — research.
|
|
11689
11391
|
{
|
|
@@ -12111,10 +11813,33 @@ function renderPipelineSkillBody(task, lines) {
|
|
|
12111
11813
|
"filter issues by `type:*` or phase label. Each invocation runs the",
|
|
12112
11814
|
`target sub-agent's full end-to-end cycle exactly once.`,
|
|
12113
11815
|
"",
|
|
12114
|
-
|
|
12115
|
-
"
|
|
12116
|
-
"
|
|
12117
|
-
"
|
|
11816
|
+
"## Depth-0 execution contract",
|
|
11817
|
+
"",
|
|
11818
|
+
"**You \u2014 the scheduled-task session \u2014 are the pipeline manager.**",
|
|
11819
|
+
"Do **not** spawn the target sub-agent via the `Agent` tool. The",
|
|
11820
|
+
"Claude Code runtime forbids nested sub-agent spawning: a depth-1",
|
|
11821
|
+
"sub-agent cannot invoke `Agent` to reach depth-2, so a pipeline",
|
|
11822
|
+
"manager that delegates to other workers must run at depth-0 (this",
|
|
11823
|
+
"scheduled-task session). See",
|
|
11824
|
+
'<https://code.claude.com/docs/en/sub-agents> \u2014 *"Subagents cannot',
|
|
11825
|
+
"spawn other subagents. If your workflow requires nested delegation,",
|
|
11826
|
+
'use Skills or chain subagents from the main conversation."*',
|
|
11827
|
+
"",
|
|
11828
|
+
"Therefore:",
|
|
11829
|
+
"",
|
|
11830
|
+
`1. **Read \`.claude/agents/${task.agent}.md\` in this session** and`,
|
|
11831
|
+
" execute its phase pipeline directly. Treat the agent file as a",
|
|
11832
|
+
" workflow runbook the scheduled-task session follows step-by-step,",
|
|
11833
|
+
" not as a sub-agent to spawn.",
|
|
11834
|
+
"2. **Use the `Agent` tool (with the `subagent_type` parameter set",
|
|
11835
|
+
" to the target worker name) to delegate one tier down.** From",
|
|
11836
|
+
" depth-0, you can spawn a depth-1 sub-agent (e.g. `issue-worker`,",
|
|
11837
|
+
" `pr-reviewer`) for the implementation, review, or merge step the",
|
|
11838
|
+
" pipeline calls out.",
|
|
11839
|
+
"3. **Never spawn the pipeline manager itself as a sub-agent.** Do",
|
|
11840
|
+
` not call \`Agent(subagent_type: "${task.agent}", ...)\`. That`,
|
|
11841
|
+
" would put the pipeline manager at depth-1 and break every",
|
|
11842
|
+
" subsequent delegation step.",
|
|
12118
11843
|
"",
|
|
12119
11844
|
"## Recommended model",
|
|
12120
11845
|
"",
|
|
@@ -12755,9 +12480,6 @@ function renderUnblockDependentsSection(ud) {
|
|
|
12755
12480
|
"",
|
|
12756
12481
|
"- The `pr-reviewer` sub-agent, Phase 5 (branch cleanup), after it",
|
|
12757
12482
|
" applies `status:done` to the linked issue on a successful merge.",
|
|
12758
|
-
"- The `orchestrator` sub-agent, Phase B0 (pre-flight PR merge)",
|
|
12759
|
-
" post-merge verification, after it force-closes an issue whose",
|
|
12760
|
-
" merge commit dropped its closing keyword.",
|
|
12761
12483
|
"",
|
|
12762
12484
|
"Any other agent that manually applies `status:done` should call",
|
|
12763
12485
|
"`unblock-dependents.sh <closed-issue>` as its last step. The",
|
|
@@ -13063,12 +12785,11 @@ function shellSingleQuote(value) {
|
|
|
13063
12785
|
}
|
|
13064
12786
|
|
|
13065
12787
|
// src/agent/bundles/orchestrator.ts
|
|
13066
|
-
function buildCheckBlockedScript(tiers, scopeGate, runRatio
|
|
12788
|
+
function buildCheckBlockedScript(tiers, scopeGate, runRatio) {
|
|
13067
12789
|
const tierCase = renderAgentTierCaseStatement(tiers);
|
|
13068
12790
|
const scopeHelper = renderScopeGateShellHelpers(scopeGate);
|
|
13069
12791
|
const scopeHelperIndented = scopeHelper.split("\n").map((line) => line.length > 0 ? line : "").join("\n");
|
|
13070
12792
|
const runRatioHelper = renderRunRatioShellHelpers(runRatio);
|
|
13071
|
-
const preflightHelper = renderPreflightPrShellHelpers(preflight);
|
|
13072
12793
|
return [
|
|
13073
12794
|
"#!/usr/bin/env bash",
|
|
13074
12795
|
"# check-blocked.sh \u2014 Token-efficient issue triage for agent loops.",
|
|
@@ -13083,7 +12804,6 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio, preflight) {
|
|
|
13083
12804
|
"# .claude/procedures/check-blocked.sh prs",
|
|
13084
12805
|
"# .claude/procedures/check-blocked.sh scope <issue-number>",
|
|
13085
12806
|
"# .claude/procedures/check-blocked.sh tick",
|
|
13086
|
-
"# .claude/procedures/check-blocked.sh preflight",
|
|
13087
12807
|
"",
|
|
13088
12808
|
"set -uo pipefail",
|
|
13089
12809
|
"",
|
|
@@ -13098,10 +12818,6 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio, preflight) {
|
|
|
13098
12818
|
`RUN_RATIO_ENABLED=${runRatio.enabled ? "1" : "0"}`,
|
|
13099
12819
|
`RUN_RATIO_DISPATCH_PER_HOUSEKEEPING=${runRatio.ratio}`,
|
|
13100
12820
|
`ORCHESTRATOR_STATE_FILE="${runRatio.stateFilePath}"`,
|
|
13101
|
-
`PREFLIGHT_ENABLED=${preflight.enabled ? "1" : "0"}`,
|
|
13102
|
-
`PREFLIGHT_REQUIRE_LINKED_ISSUE=${preflight.requireLinkedIssue ? "1" : "0"}`,
|
|
13103
|
-
`PREFLIGHT_MERGE_METHOD="${preflight.mergeMethod}"`,
|
|
13104
|
-
`PREFLIGHT_DELEGATE_TO_PR_REVIEWER=${preflight.delegateToPrReviewer ? "1" : "0"}`,
|
|
13105
12821
|
"",
|
|
13106
12822
|
"# \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",
|
|
13107
12823
|
"",
|
|
@@ -13134,8 +12850,6 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio, preflight) {
|
|
|
13134
12850
|
"",
|
|
13135
12851
|
runRatioHelper,
|
|
13136
12852
|
"",
|
|
13137
|
-
preflightHelper,
|
|
13138
|
-
"",
|
|
13139
12853
|
"# \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",
|
|
13140
12854
|
"",
|
|
13141
12855
|
"cmd_unblock() {",
|
|
@@ -13500,26 +13214,24 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio, preflight) {
|
|
|
13500
13214
|
' prs) shift; cmd_prs "$@" ;;',
|
|
13501
13215
|
' scope) shift; cmd_scope "$@" ;;',
|
|
13502
13216
|
' tick) shift; cmd_tick "$@" ;;',
|
|
13503
|
-
' preflight) shift; cmd_preflight "$@" ;;',
|
|
13504
13217
|
" help|*)",
|
|
13505
|
-
' echo "Usage: check-blocked.sh <unblock|eligible|stale|orphaned|prs|scope|tick
|
|
13218
|
+
' echo "Usage: check-blocked.sh <unblock|eligible|stale|orphaned|prs|scope|tick>"',
|
|
13506
13219
|
" exit 1",
|
|
13507
13220
|
" ;;",
|
|
13508
13221
|
"esac"
|
|
13509
13222
|
].join("\n");
|
|
13510
13223
|
}
|
|
13511
|
-
function buildCheckBlockedProcedure(tiers, scopeGate = resolveScopeGate(), runRatio = resolveRunRatio()
|
|
13224
|
+
function buildCheckBlockedProcedure(tiers, scopeGate = resolveScopeGate(), runRatio = resolveRunRatio()) {
|
|
13512
13225
|
return {
|
|
13513
13226
|
name: "check-blocked.sh",
|
|
13514
|
-
description: "Token-efficient issue triage script with subcommands: eligible, unblock, stale, orphaned, prs, scope,
|
|
13515
|
-
content: buildCheckBlockedScript(tiers, scopeGate, runRatio
|
|
13227
|
+
description: "Token-efficient issue triage script with subcommands: eligible, unblock, stale, orphaned, prs, scope, and (deprecated) tick. 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 tick subcommand is a deprecation no-op retained for one release (the orchestrator no longer maintains a dispatch/housekeeping run counter).",
|
|
13228
|
+
content: buildCheckBlockedScript(tiers, scopeGate, runRatio)
|
|
13516
13229
|
};
|
|
13517
13230
|
}
|
|
13518
13231
|
var checkBlockedProcedure = buildCheckBlockedProcedure(
|
|
13519
13232
|
DEFAULT_AGENT_TIERS,
|
|
13520
13233
|
resolveScopeGate(),
|
|
13521
|
-
resolveRunRatio()
|
|
13522
|
-
resolvePreflightPr()
|
|
13234
|
+
resolveRunRatio()
|
|
13523
13235
|
);
|
|
13524
13236
|
function buildUnblockDependentsProcedure(unblockDependents = resolveUnblockDependents()) {
|
|
13525
13237
|
return {
|
|
@@ -13533,21 +13245,21 @@ var unblockDependentsProcedure = buildUnblockDependentsProcedure(
|
|
|
13533
13245
|
);
|
|
13534
13246
|
var orchestratorSubAgent = {
|
|
13535
13247
|
name: "orchestrator",
|
|
13536
|
-
description: "End-to-end pipeline manager that runs one full cycle every invocation:
|
|
13248
|
+
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",
|
|
13537
13249
|
model: AGENT_MODEL.POWERFUL,
|
|
13538
13250
|
maxTurns: 100,
|
|
13539
|
-
canDelegateToAgents: ["issue-worker", "pr-reviewer"],
|
|
13540
13251
|
platforms: { cursor: { exclude: true } },
|
|
13541
13252
|
prompt: [
|
|
13542
13253
|
"# Orchestrator Agent",
|
|
13543
13254
|
"",
|
|
13544
13255
|
"You are the pipeline orchestrator for the **{{repository.owner}}/{{repository.name}}** repository.",
|
|
13545
|
-
"Each invocation runs **one full end-to-end cycle**. The cycle
|
|
13546
|
-
"
|
|
13547
|
-
"
|
|
13548
|
-
"
|
|
13549
|
-
"
|
|
13550
|
-
"
|
|
13256
|
+
"Each invocation runs **one full end-to-end cycle**. The cycle triages",
|
|
13257
|
+
"blocked issues, runs maintenance scans, picks the next ready issue, and",
|
|
13258
|
+
"**delegates implementation to the `issue-worker`** sub-agent in scheduled",
|
|
13259
|
+
"mode. The orchestrator itself never implements code, creates branches, or",
|
|
13260
|
+
"pushes commits \u2014 it routes work to other agents. Approved-PR merging is",
|
|
13261
|
+
"owned by the `pr-reviewer` sub-agent (invoked via `/review-pr` /",
|
|
13262
|
+
"`/review-prs`); the orchestrator does not run a merge sweep.",
|
|
13551
13263
|
"",
|
|
13552
13264
|
"Run the phases below in order on every invocation. There is no",
|
|
13553
13265
|
"dispatch/housekeeping fork \u2014 every phase runs every time.",
|
|
@@ -13555,20 +13267,23 @@ var orchestratorSubAgent = {
|
|
|
13555
13267
|
"Phase ordering (each runs exactly once per invocation):",
|
|
13556
13268
|
"",
|
|
13557
13269
|
"1. **Phase A \u2014 Startup.** Pull the default branch.",
|
|
13558
|
-
"2. **Phase
|
|
13559
|
-
" CI-green PR before triage reads dependency state.",
|
|
13560
|
-
"3. **Phase C \u2014 Triage / Unblock.** Flip dependents that have all",
|
|
13270
|
+
"2. **Phase C \u2014 Triage / Unblock.** Flip dependents that have all",
|
|
13561
13271
|
" their dependencies closed back to `status:ready`.",
|
|
13562
|
-
"
|
|
13272
|
+
"3. **Phase D \u2014 Maintenance.** Stale-issue and orphaned-resource scan",
|
|
13563
13273
|
" plus a needs-attention summary.",
|
|
13564
|
-
"
|
|
13274
|
+
"4. **Phase E \u2014 Queue Scan.** Pick the highest-priority `PICK` line",
|
|
13565
13275
|
" and run the scope gate. If the result is `large`, flag and stop.",
|
|
13566
|
-
"
|
|
13276
|
+
"5. **Phase G \u2014 Delegate Implementation.** Hand the picked issue off",
|
|
13567
13277
|
" to the `issue-worker` sub-agent in scheduled mode. The worker",
|
|
13568
13278
|
" handles claim \u2192 branch \u2192 implement \u2192 commit \u2192 PR autonomously.",
|
|
13569
|
-
"
|
|
13279
|
+
"6. **Phase F \u2014 Cleanup.** Return to the default branch and log the",
|
|
13570
13280
|
" run summary.",
|
|
13571
13281
|
"",
|
|
13282
|
+
"Phase letters are stable identifiers \u2014 letters skipped in the list",
|
|
13283
|
+
"above were used by earlier revisions of this pipeline and the gap",
|
|
13284
|
+
"is left intentionally so existing references in commit history and",
|
|
13285
|
+
"docs remain unambiguous.",
|
|
13286
|
+
"",
|
|
13572
13287
|
"---",
|
|
13573
13288
|
"",
|
|
13574
13289
|
...PROJECT_CONTEXT_READER_SECTION,
|
|
@@ -13580,100 +13295,6 @@ var orchestratorSubAgent = {
|
|
|
13580
13295
|
"git checkout main && git pull origin main",
|
|
13581
13296
|
"```",
|
|
13582
13297
|
"",
|
|
13583
|
-
"## Phase B0: Pre-flight PR Merge",
|
|
13584
|
-
"",
|
|
13585
|
-
"Before any other phase reads dependency state, land every",
|
|
13586
|
-
"eligible PR. The sweep is idempotent \u2014 `gh pr merge` on an",
|
|
13587
|
-
"already-merged PR is a no-op \u2014 so re-running on back-to-back",
|
|
13588
|
-
"invocations is safe.",
|
|
13589
|
-
"",
|
|
13590
|
-
"List eligibility:",
|
|
13591
|
-
"",
|
|
13592
|
-
"```bash",
|
|
13593
|
-
".claude/procedures/check-blocked.sh preflight",
|
|
13594
|
-
"```",
|
|
13595
|
-
"",
|
|
13596
|
-
"Expect one line per open PR:",
|
|
13597
|
-
"",
|
|
13598
|
-
"```",
|
|
13599
|
-
'PREFLIGHT_MERGE PR #<n> issue:#<m> branch:<b> \u2014 "<title>"',
|
|
13600
|
-
'PREFLIGHT_SKIP PR #<n> \u2014 <reason> \u2014 "<title>"',
|
|
13601
|
-
"NO_PREFLIGHT_PRS",
|
|
13602
|
-
"```",
|
|
13603
|
-
"",
|
|
13604
|
-
"If the output is `NO_PREFLIGHT_PRS`, continue to Phase B / C.",
|
|
13605
|
-
"",
|
|
13606
|
-
"For each `PREFLIGHT_MERGE` line, either **delegate** to the",
|
|
13607
|
-
"`pr-reviewer` sub-agent (default) or **merge inline** depending",
|
|
13608
|
-
"on the rendered pre-flight config. See the **Pre-flight PR",
|
|
13609
|
-
"merge** section in `CLAUDE.md` for the project's mode.",
|
|
13610
|
-
"",
|
|
13611
|
-
"**Delegate mode (default).** Invoke the `pr-reviewer` sub-agent",
|
|
13612
|
-
"with a single-pass brief covering every `PREFLIGHT_MERGE` line:",
|
|
13613
|
-
"",
|
|
13614
|
-
"> Run your merge pipeline once across these PRs: <list of",
|
|
13615
|
-
"> `#<n>` numbers>. Merge every eligible PR (linked issue still",
|
|
13616
|
-
"> open, AC satisfied, CI green, approval present) and comment on",
|
|
13617
|
-
"> any PR you skip. Return a one-line summary as the final line of",
|
|
13618
|
-
"> your response, e.g. `Merged 2 (#123, #124), skipped 1 (#125 \u2014",
|
|
13619
|
-
"> AC not met), 0 eligible left.` or `No eligible PRs.`",
|
|
13620
|
-
"",
|
|
13621
|
-
"If the sub-agent's final line is missing, malformed, or indicates",
|
|
13622
|
-
"an error, **do not retry** \u2014 proceed to the next phase anyway.",
|
|
13623
|
-
"The next orchestrator session will re-run pre-flight and pick up",
|
|
13624
|
-
"anything left behind.",
|
|
13625
|
-
"",
|
|
13626
|
-
"**Inline mode.** For each `PREFLIGHT_MERGE PR #<n> issue:#<m>`",
|
|
13627
|
-
"line, merge the PR with the configured method (default",
|
|
13628
|
-
"`--squash`) and `--delete-branch`:",
|
|
13629
|
-
"",
|
|
13630
|
-
"```bash",
|
|
13631
|
-
'gh pr merge <n> --squash --delete-branch --subject "<conventional-commit-title>" --body "<extended-description>"',
|
|
13632
|
-
"```",
|
|
13633
|
-
"",
|
|
13634
|
-
"After every successful merge \u2014 whether delegated or inline \u2014 run",
|
|
13635
|
-
"the post-merge verification step to close the stale-dependency",
|
|
13636
|
-
"loop:",
|
|
13637
|
-
"",
|
|
13638
|
-
"```bash",
|
|
13639
|
-
"gh issue view <m> --json state --jq '.state'",
|
|
13640
|
-
"```",
|
|
13641
|
-
"",
|
|
13642
|
-
"If the linked issue's state is still `OPEN`, close it explicitly",
|
|
13643
|
-
"and flip its status label to `status:done`:",
|
|
13644
|
-
"",
|
|
13645
|
-
"```bash",
|
|
13646
|
-
"gh issue close <m>",
|
|
13647
|
-
'gh issue edit <m> --remove-label "status:ready-for-review" --add-label "status:done"',
|
|
13648
|
-
"```",
|
|
13649
|
-
"",
|
|
13650
|
-
"After applying `status:done` \u2014 whether the auto-close fired or",
|
|
13651
|
-
"you force-closed above \u2014 run the targeted unblock sweep so any",
|
|
13652
|
-
"dependents that were only waiting on issue `<m>` flip to",
|
|
13653
|
-
"`status:ready` immediately:",
|
|
13654
|
-
"",
|
|
13655
|
-
"```bash",
|
|
13656
|
-
".claude/procedures/unblock-dependents.sh <m>",
|
|
13657
|
-
"```",
|
|
13658
|
-
"",
|
|
13659
|
-
"The script emits one line per processed dependent",
|
|
13660
|
-
"(`UNBLOCKED #<n>` / `STILL_BLOCKED #<n>` / `NO_DEPENDENTS #<m>`)",
|
|
13661
|
-
"so the run summary records what transitioned. See the",
|
|
13662
|
-
"**Agent-driven unblocking** section in `CLAUDE.md` for the full",
|
|
13663
|
-
"contract.",
|
|
13664
|
-
"",
|
|
13665
|
-
"This step is the reason pre-flight exists: it prevents the",
|
|
13666
|
-
"orchestrator from reading a merged-but-not-auto-closed issue as",
|
|
13667
|
-
"still blocking on the next unblock sweep.",
|
|
13668
|
-
"",
|
|
13669
|
-
"Log the pre-flight outcome (number merged, PRs skipped with",
|
|
13670
|
-
"reasons, and any issues force-closed) so the run summary records",
|
|
13671
|
-
"what landed.",
|
|
13672
|
-
"",
|
|
13673
|
-
"Skip lines starting with `PREFLIGHT_SKIP` \u2014 those PRs failed one",
|
|
13674
|
-
"or more eligibility checks. The `pr-reviewer` or a human",
|
|
13675
|
-
"operator picks them up on the normal review path.",
|
|
13676
|
-
"",
|
|
13677
13298
|
"## Phase C: Triage \u2014 Unblock",
|
|
13678
13299
|
"",
|
|
13679
13300
|
"Check for blocked issues whose dependencies have resolved:",
|
|
@@ -13869,40 +13490,31 @@ var orchestratorSubAgent = {
|
|
|
13869
13490
|
"git fetch --prune origin",
|
|
13870
13491
|
"```",
|
|
13871
13492
|
"",
|
|
13872
|
-
"Log completion: phases executed,
|
|
13873
|
-
"
|
|
13874
|
-
"
|
|
13875
|
-
"
|
|
13493
|
+
"Log completion: phases executed, issues unblocked, stale issues",
|
|
13494
|
+
"flagged, the next work item picked, and the outcome of Phase G's",
|
|
13495
|
+
"delegation (worker success / failure / skipped because the queue",
|
|
13496
|
+
"was empty).",
|
|
13876
13497
|
"",
|
|
13877
13498
|
"---",
|
|
13878
13499
|
"",
|
|
13879
13500
|
"## Rules",
|
|
13880
13501
|
"",
|
|
13881
|
-
"1. **Never implement code.** You
|
|
13502
|
+
"1. **Never implement code.** You triage, scan, and delegate \u2014 you do not code.",
|
|
13882
13503
|
"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.",
|
|
13883
|
-
"3. **
|
|
13884
|
-
"4. **
|
|
13885
|
-
"5. **
|
|
13886
|
-
"6. **
|
|
13504
|
+
"3. **Never merge PRs.** Approved-PR merging is owned by the `pr-reviewer` sub-agent (invoked via `/review-pr` / `/review-prs`). The orchestrator does not run a merge sweep, does not call `gh pr merge`, and does not enable auto-merge.",
|
|
13505
|
+
"4. **Always use check-blocked.sh.** All triage queries go through the shell script for token efficiency.",
|
|
13506
|
+
"5. **Follow CLAUDE.md conventions** for all git and gh operations.",
|
|
13507
|
+
"6. **Priority order:** critical > high > medium > low > trivial, then **funnel tier asc** (lower tier wins ties), then FIFO by issue number.",
|
|
13508
|
+
"7. **Never dispatch a `large` issue.** Always run the scope check",
|
|
13887
13509
|
" on the top `PICK` line before reporting `NEXT_WORK_ITEM`. A",
|
|
13888
13510
|
" `large` issue must be flagged with `status:needs-attention` and",
|
|
13889
13511
|
" handed a decomposition proposal \u2014 never claimed, never branched,",
|
|
13890
13512
|
" never delegated to the `issue-worker`.",
|
|
13891
|
-
"7. **Always run pre-flight before reading dependency state.**",
|
|
13892
|
-
" Phase B0 (Pre-flight PR Merge) runs on every invocation,",
|
|
13893
|
-
" immediately after Phase A. Never skip Phase B0: without it, an",
|
|
13894
|
-
" issue whose only remaining blocker is an approved-but-not-yet-",
|
|
13895
|
-
" merged PR reads as blocked on every cycle and the pipeline",
|
|
13896
|
-
" thrashes. See the **Pre-flight PR merge** section in",
|
|
13897
|
-
" `CLAUDE.md` for eligibility rules and the delegate-vs-inline",
|
|
13898
|
-
" modes.",
|
|
13899
13513
|
"8. **Sweep dependents whenever you apply `status:done`.** Every",
|
|
13900
13514
|
" `status:done` transition must be immediately followed by",
|
|
13901
13515
|
" `.claude/procedures/unblock-dependents.sh <n>` so downstream",
|
|
13902
13516
|
" `Depends on: #<n>` issues flip to `status:ready` without",
|
|
13903
|
-
" waiting for the next cycle.
|
|
13904
|
-
" verification (and any inline-mode merge) already calls the",
|
|
13905
|
-
" sweep; don't skip it. See the **Agent-driven unblocking**",
|
|
13517
|
+
" waiting for the next cycle. See the **Agent-driven unblocking**",
|
|
13906
13518
|
" section in `CLAUDE.md` for the contract.",
|
|
13907
13519
|
"9. **Always invoke `issue-worker` in scheduled mode.** Phase G's",
|
|
13908
13520
|
" delegation prompt must contain the literal phrase",
|
|
@@ -13916,8 +13528,7 @@ var issueWorkerSubAgent = {
|
|
|
13916
13528
|
name: "issue-worker",
|
|
13917
13529
|
description: "Selects the next ready issue from the queue, claims it, and implements the change end-to-end following repository conventions",
|
|
13918
13530
|
model: AGENT_MODEL.POWERFUL,
|
|
13919
|
-
maxTurns:
|
|
13920
|
-
canDelegateToAgents: [],
|
|
13531
|
+
maxTurns: 150,
|
|
13921
13532
|
platforms: { cursor: { exclude: true } },
|
|
13922
13533
|
prompt: [
|
|
13923
13534
|
"# Issue Worker",
|
|
@@ -14146,6 +13757,35 @@ var issueWorkerSubAgent = {
|
|
|
14146
13757
|
" `file` (and optional `line`). Track `comment_id` per item so you can",
|
|
14147
13758
|
" report which items were handled and which (if any) failed.",
|
|
14148
13759
|
"",
|
|
13760
|
+
" **Synthetic rebase items.** A `comment_id` of",
|
|
13761
|
+
" `synthetic:rebase-behind-main` is the reviewer's signal that the",
|
|
13762
|
+
" PR's head branch is BEHIND the default branch with merge conflicts",
|
|
13763
|
+
" that `gh pr update-branch` could not resolve. For this item only,",
|
|
13764
|
+
" the work is **not** an editorial change \u2014 it is a rebase plus",
|
|
13765
|
+
" conflict resolution. Run the following sequence:",
|
|
13766
|
+
"",
|
|
13767
|
+
" ```bash",
|
|
13768
|
+
" git fetch origin",
|
|
13769
|
+
" git pull --rebase origin {{repository.defaultBranch}}",
|
|
13770
|
+
" ```",
|
|
13771
|
+
"",
|
|
13772
|
+
" When the rebase produces conflicts, resolve each conflicting file",
|
|
13773
|
+
" in turn (read both sides, reconcile, stage), then run",
|
|
13774
|
+
" `git rebase --continue` until the rebase completes. Never run",
|
|
13775
|
+
" `git rebase --abort` on a synthetic-rebase item \u2014 aborting drops",
|
|
13776
|
+
" the work the reviewer delegated. If you cannot resolve a conflict",
|
|
13777
|
+
" (the change is editorial enough that it requires human judgement,",
|
|
13778
|
+
" or the conflict touches a generated file you should not hand-edit),",
|
|
13779
|
+
" record the item as `failed` with a clear reason, run",
|
|
13780
|
+
" `git rebase --abort`, and proceed to the report step. Do not",
|
|
13781
|
+
" force-push.",
|
|
13782
|
+
"",
|
|
13783
|
+
" When the rebase completes cleanly, treat the rebased commits",
|
|
13784
|
+
" themselves as the deliverable. Skip the conventional commit step",
|
|
13785
|
+
" in Phase 6 for this item \u2014 the rebase already produced the commit",
|
|
13786
|
+
" history. Push with a regular non-force `git push origin <branch>`",
|
|
13787
|
+
" and report the rebased head SHA as the worker's commit.",
|
|
13788
|
+
"",
|
|
14149
13789
|
"4. When complete, prepare a short structured report (PR number, commit",
|
|
14150
13790
|
" SHAs you will push, items handled by `comment_id`, items that failed",
|
|
14151
13791
|
" to apply) \u2014 you will return this after Phase 6.",
|
|
@@ -14207,6 +13847,22 @@ var issueWorkerSubAgent = {
|
|
|
14207
13847
|
"git push origin <branch-name>",
|
|
14208
13848
|
"```",
|
|
14209
13849
|
"",
|
|
13850
|
+
"**Synthetic-rebase items skip the `fix(review)` commit.** When the",
|
|
13851
|
+
"fix-list contained a `comment_id` of `synthetic:rebase-behind-main`",
|
|
13852
|
+
"and you completed the rebase in Phase 4, the rebased commit history",
|
|
13853
|
+
"is itself the deliverable \u2014 there is no per-item editorial change to",
|
|
13854
|
+
"wrap in a `fix(review)` commit. Skip `git add` / `git commit` /",
|
|
13855
|
+
"`git pull --rebase` for that item and push the rebased branch",
|
|
13856
|
+
"directly:",
|
|
13857
|
+
"",
|
|
13858
|
+
"```bash",
|
|
13859
|
+
"git push origin <branch-name>",
|
|
13860
|
+
"```",
|
|
13861
|
+
"",
|
|
13862
|
+
"If the fix-list mixed a synthetic-rebase item with editorial items,",
|
|
13863
|
+
"perform the editorial commit first (the rebase already preceded it",
|
|
13864
|
+
"in Phase 4), then push once at the end.",
|
|
13865
|
+
"",
|
|
14210
13866
|
"**Normal mode:** Use conventional commit messages and push with `-u`",
|
|
14211
13867
|
"to set up branch tracking:",
|
|
14212
13868
|
"",
|
|
@@ -14340,15 +13996,21 @@ var ORCHESTRATOR_CONVENTIONS_PREAMBLE = [
|
|
|
14340
13996
|
"",
|
|
14341
13997
|
"When running the orchestrator agent (`.claude/agents/orchestrator.md`):",
|
|
14342
13998
|
"",
|
|
14343
|
-
"- The orchestrator runs **one full end-to-end cycle every invocation**:
|
|
14344
|
-
"- The orchestrator **never** implements code, creates branches,
|
|
13999
|
+
"- 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",
|
|
14000
|
+
"- The orchestrator **never** implements code, creates branches, pushes commits, **or merges PRs** \u2014 it triages issues, picks the next work item, and delegates implementation to other sub-agents. Approved-PR merging is owned by the `pr-reviewer` sub-agent (invoked via `/review-pr` / `/review-prs`).",
|
|
14345
14001
|
"- All triage queries use `.claude/procedures/check-blocked.sh` for token efficiency",
|
|
14346
14002
|
"- 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.",
|
|
14347
14003
|
"- Priority order: critical > high > medium > low > trivial, then **funnel tier asc** (lower tier wins ties), then FIFO by issue number",
|
|
14348
14004
|
"- Stale thresholds: 72h for in-progress, 168h for blocked",
|
|
14349
|
-
"- Flagged issues get `status:needs-attention` \u2014 they are not auto-reset"
|
|
14005
|
+
"- Flagged issues get `status:needs-attention` \u2014 they are not auto-reset",
|
|
14006
|
+
"",
|
|
14007
|
+
"## Depth-0 invocation requirement",
|
|
14008
|
+
"",
|
|
14009
|
+
'The orchestrator agent **must run as the top-level (depth-0) session** when its Phase G needs to delegate work to the `issue-worker` sub-agent. 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 the `issue-worker` at depth-2 would not be available and Phase G would silently abort.',
|
|
14010
|
+
"",
|
|
14011
|
+
'Practical implication for scheduled-task wiring: the `worker-orchestrator` scheduled task\'s `SKILL.md` instructs the **scheduled-task session itself** to read `.claude/agents/orchestrator.md` and execute its phase pipeline in-session, then use the `Agent` tool to delegate the picked work item to `issue-worker` (depth-1). The scheduled task does **not** call `Agent(subagent_type: "orchestrator")` \u2014 that would put the orchestrator at depth-1 and break the chain.'
|
|
14350
14012
|
].join("\n");
|
|
14351
|
-
function buildOrchestratorConventionsContent(tiers, scopeGate = resolveScopeGate(), runRatio = resolveRunRatio(),
|
|
14013
|
+
function buildOrchestratorConventionsContent(tiers, scopeGate = resolveScopeGate(), runRatio = resolveRunRatio(), scheduledTasks = resolveScheduledTasks(), unblockDependents = resolveUnblockDependents()) {
|
|
14352
14014
|
return [
|
|
14353
14015
|
ORCHESTRATOR_CONVENTIONS_PREAMBLE,
|
|
14354
14016
|
"",
|
|
@@ -14358,18 +14020,15 @@ function buildOrchestratorConventionsContent(tiers, scopeGate = resolveScopeGate
|
|
|
14358
14020
|
"",
|
|
14359
14021
|
renderRunRatioSection(runRatio),
|
|
14360
14022
|
"",
|
|
14361
|
-
renderPreflightPrSection(preflight),
|
|
14362
|
-
"",
|
|
14363
14023
|
renderScheduledTasksSection(scheduledTasks),
|
|
14364
14024
|
"",
|
|
14365
14025
|
renderUnblockDependentsSection(unblockDependents)
|
|
14366
14026
|
].join("\n");
|
|
14367
14027
|
}
|
|
14368
|
-
function resolveOrchestratorAssets(tierConfig, scopeGateConfig, runRatioConfig,
|
|
14028
|
+
function resolveOrchestratorAssets(tierConfig, scopeGateConfig, runRatioConfig, scheduledTasksConfig, unblockDependentsConfig) {
|
|
14369
14029
|
const tiers = resolveAgentTiers(tierConfig);
|
|
14370
14030
|
const scopeGate = resolveScopeGate(scopeGateConfig);
|
|
14371
14031
|
const runRatio = resolveRunRatio(runRatioConfig);
|
|
14372
|
-
const preflight = resolvePreflightPr(preflightPrConfig);
|
|
14373
14032
|
const scheduledTasks = resolveScheduledTasks(scheduledTasksConfig);
|
|
14374
14033
|
const unblockDependentsResolved = resolveUnblockDependents(
|
|
14375
14034
|
unblockDependentsConfig
|
|
@@ -14378,23 +14037,16 @@ function resolveOrchestratorAssets(tierConfig, scopeGateConfig, runRatioConfig,
|
|
|
14378
14037
|
tiers,
|
|
14379
14038
|
scopeGate,
|
|
14380
14039
|
runRatio,
|
|
14381
|
-
preflight,
|
|
14382
14040
|
scheduledTasks,
|
|
14383
14041
|
unblockDependents: unblockDependentsResolved,
|
|
14384
14042
|
conventionsContent: buildOrchestratorConventionsContent(
|
|
14385
14043
|
tiers,
|
|
14386
14044
|
scopeGate,
|
|
14387
14045
|
runRatio,
|
|
14388
|
-
preflight,
|
|
14389
14046
|
scheduledTasks,
|
|
14390
14047
|
unblockDependentsResolved
|
|
14391
14048
|
),
|
|
14392
|
-
procedure: buildCheckBlockedProcedure(
|
|
14393
|
-
tiers,
|
|
14394
|
-
scopeGate,
|
|
14395
|
-
runRatio,
|
|
14396
|
-
preflight
|
|
14397
|
-
),
|
|
14049
|
+
procedure: buildCheckBlockedProcedure(tiers, scopeGate, runRatio),
|
|
14398
14050
|
unblockDependentsProcedure: buildUnblockDependentsProcedure(
|
|
14399
14051
|
unblockDependentsResolved
|
|
14400
14052
|
)
|
|
@@ -14408,13 +14060,12 @@ var orchestratorBundle = {
|
|
|
14408
14060
|
rules: [
|
|
14409
14061
|
{
|
|
14410
14062
|
name: "orchestrator-conventions",
|
|
14411
|
-
description: "Guidelines for orchestrator agent behavior and pipeline management, including the funnel-tier dispatch sort, scope gate,
|
|
14063
|
+
description: "Guidelines for orchestrator agent behavior and pipeline management, including the funnel-tier dispatch sort, scope gate, and per-agent scheduled-task layout",
|
|
14412
14064
|
scope: AGENT_RULE_SCOPE.ALWAYS,
|
|
14413
14065
|
content: buildOrchestratorConventionsContent(
|
|
14414
14066
|
DEFAULT_AGENT_TIERS,
|
|
14415
14067
|
resolveScopeGate(),
|
|
14416
14068
|
resolveRunRatio(),
|
|
14417
|
-
resolvePreflightPr(),
|
|
14418
14069
|
resolveScheduledTasks(),
|
|
14419
14070
|
resolveUnblockDependents()
|
|
14420
14071
|
),
|
|
@@ -16151,6 +15802,162 @@ var prReviewerSubAgent = {
|
|
|
16151
15802
|
"`feat(scope): description`). The body should bullet the changes and end",
|
|
16152
15803
|
"with `Closes #<issue-number>`.",
|
|
16153
15804
|
"",
|
|
15805
|
+
"##### Update the branch when `mergeStateStatus` is `BEHIND`",
|
|
15806
|
+
"",
|
|
15807
|
+
"After enabling auto-merge, re-read the PR's `mergeStateStatus` so a",
|
|
15808
|
+
"branch that fell behind the default branch lands on the next CI tick",
|
|
15809
|
+
"instead of sitting in the auto-merge queue indefinitely:",
|
|
15810
|
+
"",
|
|
15811
|
+
"```bash",
|
|
15812
|
+
"gh pr view <pr-number> --json mergeStateStatus --jq '.mergeStateStatus'",
|
|
15813
|
+
"```",
|
|
15814
|
+
"",
|
|
15815
|
+
"When the value is `BEHIND`, attempt to bring the head branch current with",
|
|
15816
|
+
"the default branch via `gh pr update-branch` (default merge strategy \u2014",
|
|
15817
|
+
"**never** `--rebase`, which would rewrite commits on a published branch):",
|
|
15818
|
+
"",
|
|
15819
|
+
"```bash",
|
|
15820
|
+
"gh pr update-branch <pr-number>",
|
|
15821
|
+
"```",
|
|
15822
|
+
"",
|
|
15823
|
+
"Branch on the outcome:",
|
|
15824
|
+
"",
|
|
15825
|
+
"- **Success** \u2014 record `Branch updated: yes` for the per-PR report and",
|
|
15826
|
+
" stop. Auto-merge will fire when required checks pass on the new head",
|
|
15827
|
+
" SHA. Do **not** poll for the merge here \u2014 Phase 5 owns polling.",
|
|
15828
|
+
"- **Failure for reasons other than a merge conflict** (permission",
|
|
15829
|
+
" denied, branch protection refusing the merge commit, transient",
|
|
15830
|
+
" network error) \u2014 record `Branch updated: failed (<reason>)`, post a",
|
|
15831
|
+
" short comment explaining the failure, and stop. Do not retry.",
|
|
15832
|
+
"- **Failure because the merge would conflict** \u2014 proceed to the",
|
|
15833
|
+
" conflict-resolution delegation flow below.",
|
|
15834
|
+
"",
|
|
15835
|
+
"When `mergeStateStatus` is **not** `BEHIND` (`CLEAN`, `BLOCKED`,",
|
|
15836
|
+
"`UNSTABLE`, `HAS_HOOKS`, `UNKNOWN`), record `Branch updated: not needed`",
|
|
15837
|
+
"and skip the rest of this sub-section. Only the `BEHIND` state triggers",
|
|
15838
|
+
"an `update-branch` attempt \u2014 every other state either has nothing to do",
|
|
15839
|
+
"or is already gated on a different signal that Phase 5 picks up.",
|
|
15840
|
+
"",
|
|
15841
|
+
"Never run `gh pr update-branch` on a PR whose review mode is",
|
|
15842
|
+
"`human-required`. Pushing main into a human-required PR expands the",
|
|
15843
|
+
"scope of the diff the human is reviewing without their consent. The",
|
|
15844
|
+
"`update-branch` step lives **only** under the `Mode auto-merge` branch",
|
|
15845
|
+
"of this phase \u2014 `human-required` skips straight to its hand-off block",
|
|
15846
|
+
"below.",
|
|
15847
|
+
"",
|
|
15848
|
+
"##### Conflict-resolution delegation (BEHIND + conflicts)",
|
|
15849
|
+
"",
|
|
15850
|
+
"When `gh pr update-branch <pr-number>` fails because the merge would",
|
|
15851
|
+
"produce conflicts, the reviewer **may** delegate conflict resolution to",
|
|
15852
|
+
"`issue-worker` via the existing feedback-mode delegation contract (the",
|
|
15853
|
+
"same path Phase 4's in-scope-fix delegation uses). The reviewer never",
|
|
15854
|
+
"hand-resolves conflicts itself \u2014 branch mutations always belong to",
|
|
15855
|
+
"`issue-worker`.",
|
|
15856
|
+
"",
|
|
15857
|
+
"Delegate **only when all** of the following hold. If any guard fails,",
|
|
15858
|
+
"fall through to the fallback at the end of this sub-section instead.",
|
|
15859
|
+
"",
|
|
15860
|
+
"1. **Review mode is `auto-merge`.** Never delegate conflict",
|
|
15861
|
+
" resolution on `human-required` PRs \u2014 pushing main resolutions into",
|
|
15862
|
+
" them expands the diff the human is reviewing. (This is the same",
|
|
15863
|
+
" reason the `update-branch` step itself is auto-merge-only.)",
|
|
15864
|
+
"2. **Delegation invocation guard permits the hand-off** \u2014 the PR",
|
|
15865
|
+
" carries the `origin:issue-worker` label, **or** the reviewer was",
|
|
15866
|
+
" invoked with `--allow-human-author`. The same guard used for the",
|
|
15867
|
+
" in-scope-fix delegation flow above applies here unchanged.",
|
|
15868
|
+
"3. **The `review:fixing` lease is currently free.** If",
|
|
15869
|
+
" `review:fixing` is already on the PR, another delegation is",
|
|
15870
|
+
" in-flight; skip conflict-resolution delegation, log the contention",
|
|
15871
|
+
" to the sticky summary, and fall through to the fallback.",
|
|
15872
|
+
"4. **No conflicting file is generated or projen-managed.** Run",
|
|
15873
|
+
" `gh pr view <pr-number> --json files --jq '.files[].path'` and",
|
|
15874
|
+
" inspect the conflicting paths reported by the failed",
|
|
15875
|
+
" `update-branch`. If **any** conflicting path matches one of the",
|
|
15876
|
+
" following globs, the conflict is unsafe to resolve mechanically",
|
|
15877
|
+
" and the reviewer must skip delegation:",
|
|
15878
|
+
" - `**/*.lock` and `pnpm-lock.yaml` / `yarn.lock` / `package-lock.json`",
|
|
15879
|
+
" - `**/.projen/**`",
|
|
15880
|
+
" - any file whose first 5 lines contain the marker",
|
|
15881
|
+
" `~~ Generated by projen` or `// Generated by`.",
|
|
15882
|
+
" The lockfile guard exists because lockfile conflicts often need a",
|
|
15883
|
+
" regen (`pnpm i`) rather than a textual merge; the projen / generated",
|
|
15884
|
+
" guard exists because those files are derived from `.projenrc.ts`",
|
|
15885
|
+
" and conflicts there should be resolved by re-running synth, not by",
|
|
15886
|
+
" merging the conflict markers.",
|
|
15887
|
+
"",
|
|
15888
|
+
"When every guard above passes, hand off to `issue-worker` with a",
|
|
15889
|
+
"**single synthetic fix-list item** that describes the rebase work:",
|
|
15890
|
+
"",
|
|
15891
|
+
"1. **Disable auto-merge** so a fast CI pass cannot land the PR",
|
|
15892
|
+
" mid-delegation (idempotent \u2014 safe no-op when auto-merge was never",
|
|
15893
|
+
" enabled). This mirrors step (b) of the in-scope-fix flow:",
|
|
15894
|
+
"",
|
|
15895
|
+
" ```bash",
|
|
15896
|
+
" gh pr merge <pr-number> --disable-auto",
|
|
15897
|
+
" ```",
|
|
15898
|
+
"",
|
|
15899
|
+
"2. **Acquire the `review:fixing` lease** by adding the label",
|
|
15900
|
+
" (mirrors step (c) of the in-scope-fix flow). On contention, abort",
|
|
15901
|
+
" the delegation and fall through to the fallback:",
|
|
15902
|
+
"",
|
|
15903
|
+
" ```bash",
|
|
15904
|
+
" gh pr edit <pr-number> --add-label 'review:fixing'",
|
|
15905
|
+
" ```",
|
|
15906
|
+
"",
|
|
15907
|
+
"3. **Post a fix-list comment** containing exactly one synthetic item",
|
|
15908
|
+
" describing the rebase. The `comment_id` is the literal string",
|
|
15909
|
+
" `synthetic:rebase-behind-main` so the worker recognises the",
|
|
15910
|
+
" special case and the next reviewer pass can identify the item:",
|
|
15911
|
+
"",
|
|
15912
|
+
" ```markdown",
|
|
15913
|
+
" ## Reviewer: fix list for @issue-worker",
|
|
15914
|
+
"",
|
|
15915
|
+
" - [ ] @reviewer \u2014 rebase onto origin/<default-branch> and resolve conflicts in: <space-separated list of conflicting files>",
|
|
15916
|
+
"",
|
|
15917
|
+
" ```json fix-list",
|
|
15918
|
+
" {",
|
|
15919
|
+
' "pr": <pr-number>,',
|
|
15920
|
+
' "branch": "<head-ref-name>",',
|
|
15921
|
+
' "generated_at": "<ISO-8601 timestamp>",',
|
|
15922
|
+
' "items": [',
|
|
15923
|
+
' {"comment_id": "synthetic:rebase-behind-main", "author": "reviewer", "file": "<first-conflicting-file>", "instruction": "Branch is BEHIND default-branch with merge conflicts. Pull and rebase onto origin/<default-branch>, resolve conflicts in <conflicting-files>, push the resolved branch (no force-push), and report success."}',
|
|
15924
|
+
" ]",
|
|
15925
|
+
" }",
|
|
15926
|
+
" ```",
|
|
15927
|
+
" ```",
|
|
15928
|
+
"",
|
|
15929
|
+
"4. **Invoke `issue-worker` in feedback mode** with the same prompt",
|
|
15930
|
+
" shape used by the in-scope-fix flow: include the literal phrase",
|
|
15931
|
+
" `feedback mode: PR #<n>` plus the repository identifier",
|
|
15932
|
+
" (`{{repository.owner}}/{{repository.name}}`).",
|
|
15933
|
+
"",
|
|
15934
|
+
"5. **Process the worker's report** for the synthetic item using the",
|
|
15935
|
+
" same logic as step (f) of the in-scope-fix flow \u2014 `handled` reacts",
|
|
15936
|
+
" `rocket` on the fix-list comment; `failed` reacts `thinking_face`",
|
|
15937
|
+
" and posts a reply citing the worker's failure reason.",
|
|
15938
|
+
"",
|
|
15939
|
+
"6. **Release the `review:fixing` lease** with",
|
|
15940
|
+
" `gh pr edit <pr-number> --remove-label 'review:fixing'`. Always",
|
|
15941
|
+
" run this step.",
|
|
15942
|
+
"",
|
|
15943
|
+
"7. **Do not re-enable auto-merge in the same pass.** After delegation,",
|
|
15944
|
+
" exit and let a human re-invoke the reviewer. The next pass will",
|
|
15945
|
+
" re-evaluate `mergeStateStatus` against the rebased branch and",
|
|
15946
|
+
" re-enable auto-merge through the normal flow above.",
|
|
15947
|
+
"",
|
|
15948
|
+
"Record `Branch updated: delegated (PR #<n>)` for the per-PR report",
|
|
15949
|
+
"when delegation completes (regardless of the worker's outcome \u2014 the",
|
|
15950
|
+
"delegation itself is the action taken).",
|
|
15951
|
+
"",
|
|
15952
|
+
"**Fallback when delegation is not permitted or guards fail.** Post a",
|
|
15953
|
+
"short comment explaining why the branch could not be updated",
|
|
15954
|
+
"automatically and stop. Do not push commits, do not force, do not",
|
|
15955
|
+
"retry. Record `Branch updated: failed (conflicts; <short reason>)`.",
|
|
15956
|
+
"",
|
|
15957
|
+
"```bash",
|
|
15958
|
+
"gh pr comment <pr-number> --body 'Auto-merge queued; branch is BEHIND <default-branch> with conflicts. <short reason delegation was skipped \u2014 e.g. human-required mode, generated-file conflicts, or in-flight review:fixing lease>. A human (or the next reviewer pass after rebase) will need to resolve.'",
|
|
15959
|
+
"```",
|
|
15960
|
+
"",
|
|
16154
15961
|
"#### Mode `human-required`",
|
|
16155
15962
|
"",
|
|
16156
15963
|
"Do **not** run `gh pr merge --auto`. Instead, hand the PR off to a",
|
|
@@ -16341,6 +16148,7 @@ var prReviewerSubAgent = {
|
|
|
16341
16148
|
" - Nitpick: <items>",
|
|
16342
16149
|
"",
|
|
16343
16150
|
"Action taken: <enable-auto-merge | label-awaiting-human | commented-on-the-pr | none>",
|
|
16151
|
+
"Branch updated: <yes | not needed | failed (<reason>) | delegated (PR #<n>) | n/a>",
|
|
16344
16152
|
"Branch state: <merged | open | closed>",
|
|
16345
16153
|
"Issue state: <closed | open>",
|
|
16346
16154
|
"```",
|
|
@@ -16406,7 +16214,23 @@ var prReviewerSubAgent = {
|
|
|
16406
16214
|
" `review:awaiting-human` label is **not** present on the PR. Any",
|
|
16407
16215
|
" AC-drift pushback, any failed-fix pushback, and any human-required",
|
|
16408
16216
|
" hand-off all keep auto-merge disabled until the human resolves",
|
|
16409
|
-
" the underlying state."
|
|
16217
|
+
" the underlying state.",
|
|
16218
|
+
"15. **Never run `gh pr update-branch` on a `human-required` PR.**",
|
|
16219
|
+
" Pushing main into a human-required PR expands the scope of the",
|
|
16220
|
+
" diff the human is reviewing without their consent. The",
|
|
16221
|
+
" `update-branch` step is gated to the `Mode auto-merge` branch of",
|
|
16222
|
+
" Phase 4 only. The same restriction applies to delegating",
|
|
16223
|
+
" conflict resolution to `issue-worker`: never delegate a rebase",
|
|
16224
|
+
" on a `human-required` PR.",
|
|
16225
|
+
"16. **Never delegate conflict resolution involving generated or",
|
|
16226
|
+
" projen-managed files.** When `gh pr update-branch` fails on a",
|
|
16227
|
+
" BEHIND PR with conflicts and any conflicting path is a lockfile,",
|
|
16228
|
+
" a `**/.projen/**` file, or a file marked",
|
|
16229
|
+
" `~~ Generated by projen` / `// Generated by`, the reviewer must",
|
|
16230
|
+
" skip the `issue-worker` delegation and fall back to the comment",
|
|
16231
|
+
" pathway. Mechanical merge of generated content is unsafe \u2014 those",
|
|
16232
|
+
" files are derived from `.projenrc.ts` and must be regenerated,",
|
|
16233
|
+
" not merged."
|
|
16410
16234
|
].join("\n")
|
|
16411
16235
|
};
|
|
16412
16236
|
var reviewPrSkill = {
|
|
@@ -27518,12 +27342,6 @@ var ClaudeRenderer = class _ClaudeRenderer {
|
|
|
27518
27342
|
if (agent.platforms?.claude?.memory) {
|
|
27519
27343
|
lines.push(`memory: ${agent.platforms.claude.memory}`);
|
|
27520
27344
|
}
|
|
27521
|
-
if (agent.canDelegateToAgents && agent.canDelegateToAgents.length > 0) {
|
|
27522
|
-
lines.push(`canDelegateToAgents:`);
|
|
27523
|
-
for (const delegateName of agent.canDelegateToAgents) {
|
|
27524
|
-
lines.push(` - "${delegateName}"`);
|
|
27525
|
-
}
|
|
27526
|
-
}
|
|
27527
27345
|
lines.push("---");
|
|
27528
27346
|
lines.push("");
|
|
27529
27347
|
lines.push(...agent.prompt.split("\n"));
|
|
@@ -27987,7 +27805,6 @@ var AgentConfig = class _AgentConfig extends import_projen8.Component {
|
|
|
27987
27805
|
if (resolvedRunRatio.enabled) {
|
|
27988
27806
|
this.project.gitignore.addPatterns(`/${resolvedRunRatio.stateFilePath}`);
|
|
27989
27807
|
}
|
|
27990
|
-
validatePreflightPrConfig(this.options.preflightPr);
|
|
27991
27808
|
validateUnblockDependentsConfig(this.options.unblockDependents);
|
|
27992
27809
|
const resolvedProgressFiles = validateProgressFilesConfig(
|
|
27993
27810
|
this.options.progressFiles
|
|
@@ -28204,14 +28021,13 @@ ${section}`
|
|
|
28204
28021
|
}
|
|
28205
28022
|
}
|
|
28206
28023
|
}
|
|
28207
|
-
if (this.options.tiers || this.options.scopeGate || this.options.runRatio || this.options.
|
|
28024
|
+
if (this.options.tiers || this.options.scopeGate || this.options.runRatio || this.options.scheduledTasks || this.options.unblockDependents) {
|
|
28208
28025
|
const orchestratorRule = ruleMap.get("orchestrator-conventions");
|
|
28209
28026
|
if (orchestratorRule) {
|
|
28210
28027
|
const { conventionsContent } = resolveOrchestratorAssets(
|
|
28211
28028
|
this.options.tiers,
|
|
28212
28029
|
this.options.scopeGate,
|
|
28213
28030
|
this.options.runRatio,
|
|
28214
|
-
this.options.preflightPr,
|
|
28215
28031
|
this.options.scheduledTasks,
|
|
28216
28032
|
this.options.unblockDependents
|
|
28217
28033
|
);
|
|
@@ -28526,14 +28342,13 @@ ${hook}`
|
|
|
28526
28342
|
procMap.set(proc.name, proc);
|
|
28527
28343
|
}
|
|
28528
28344
|
}
|
|
28529
|
-
if (this.options.tiers || this.options.scopeGate || this.options.runRatio
|
|
28345
|
+
if (this.options.tiers || this.options.scopeGate || this.options.runRatio) {
|
|
28530
28346
|
const existing = procMap.get("check-blocked.sh");
|
|
28531
28347
|
if (existing) {
|
|
28532
28348
|
const { procedure } = resolveOrchestratorAssets(
|
|
28533
28349
|
this.options.tiers,
|
|
28534
28350
|
this.options.scopeGate,
|
|
28535
|
-
this.options.runRatio
|
|
28536
|
-
this.options.preflightPr
|
|
28351
|
+
this.options.runRatio
|
|
28537
28352
|
);
|
|
28538
28353
|
if (procedure.content !== existing.content) {
|
|
28539
28354
|
procMap.set("check-blocked.sh", procedure);
|
|
@@ -28548,7 +28363,6 @@ ${hook}`
|
|
|
28548
28363
|
void 0,
|
|
28549
28364
|
void 0,
|
|
28550
28365
|
void 0,
|
|
28551
|
-
void 0,
|
|
28552
28366
|
this.options.unblockDependents
|
|
28553
28367
|
);
|
|
28554
28368
|
if (unblockDependentsProcedure2.content !== existing.content) {
|
|
@@ -30976,7 +30790,7 @@ var DEFAULT_AUTO_APPROVE_LABEL = "auto-approve";
|
|
|
30976
30790
|
var DEFAULT_HEAD_BRANCH = "github-actions/upgrade";
|
|
30977
30791
|
var DEFAULT_APPROVAL_APP_ID_SECRET = "APPROVAL_APP_ID";
|
|
30978
30792
|
var DEFAULT_APPROVAL_APP_PRIVATE_KEY_SECRET = "APPROVAL_APP_PRIVATE_KEY";
|
|
30979
|
-
var
|
|
30793
|
+
var DEFAULT_MERGE_METHOD = MERGE_METHODS.SQUASH;
|
|
30980
30794
|
var PULL_REQUEST_TARGET_TYPES = [
|
|
30981
30795
|
"labeled",
|
|
30982
30796
|
"synchronize",
|
|
@@ -30990,7 +30804,7 @@ function addApproveMergeUpgradeWorkflow(project, options) {
|
|
|
30990
30804
|
const allowedUsernames = options.allowedUsernames;
|
|
30991
30805
|
const appIdSecret = options.approvalAppIdSecret ?? DEFAULT_APPROVAL_APP_ID_SECRET;
|
|
30992
30806
|
const privateKeySecret = options.approvalAppPrivateKeySecret ?? DEFAULT_APPROVAL_APP_PRIVATE_KEY_SECRET;
|
|
30993
|
-
const mergeMethod = options.mergeMethod ??
|
|
30807
|
+
const mergeMethod = options.mergeMethod ?? DEFAULT_MERGE_METHOD;
|
|
30994
30808
|
const workflow = project.github?.addWorkflow(workflowName);
|
|
30995
30809
|
if (!workflow) return;
|
|
30996
30810
|
workflow.on({
|
|
@@ -32863,7 +32677,6 @@ var TypeScriptConfig = class extends import_projen23.Component {
|
|
|
32863
32677
|
DEFAULT_API_EXTRACTOR_REPORT_FOLDER,
|
|
32864
32678
|
DEFAULT_AUDIT_REPORT_DIR,
|
|
32865
32679
|
DEFAULT_DECOMPOSITION_TEMPLATE,
|
|
32866
|
-
DEFAULT_DELEGATE_TO_PR_REVIEWER,
|
|
32867
32680
|
DEFAULT_DISPATCH_MODEL,
|
|
32868
32681
|
DEFAULT_DISPATCH_TO_HOUSEKEEPING_RATIO,
|
|
32869
32682
|
DEFAULT_HOUSEKEEPING_MODEL,
|
|
@@ -32873,7 +32686,6 @@ var TypeScriptConfig = class extends import_projen23.Component {
|
|
|
32873
32686
|
DEFAULT_ISSUE_TEMPLATES_ENABLED,
|
|
32874
32687
|
DEFAULT_ISSUE_TEMPLATES_PATH,
|
|
32875
32688
|
DEFAULT_ISSUE_TEMPLATES_REQUIRE_REFERENCE,
|
|
32876
|
-
DEFAULT_MERGE_METHOD,
|
|
32877
32689
|
DEFAULT_OFF_PEAK_CRON_EXAMPLE,
|
|
32878
32690
|
DEFAULT_PARTIAL_UNBLOCK_COMMENT_TEMPLATE,
|
|
32879
32691
|
DEFAULT_PRIORITY_LABELS,
|
|
@@ -32883,7 +32695,6 @@ var TypeScriptConfig = class extends import_projen23.Component {
|
|
|
32883
32695
|
DEFAULT_PROGRESS_FILES_FORMAT,
|
|
32884
32696
|
DEFAULT_PROGRESS_FILES_STALE_AFTER_HOURS,
|
|
32885
32697
|
DEFAULT_PROGRESS_FILES_STATE_DIR,
|
|
32886
|
-
DEFAULT_REQUIRE_LINKED_ISSUE,
|
|
32887
32698
|
DEFAULT_REQUIRE_PRODUCT_CONTEXT,
|
|
32888
32699
|
DEFAULT_SAMPLE_COMPILER_OPTIONS,
|
|
32889
32700
|
DEFAULT_SCHEDULED_TASKS_ROOT,
|
|
@@ -32915,7 +32726,6 @@ var TypeScriptConfig = class extends import_projen23.Component {
|
|
|
32915
32726
|
MINIMUM_RELEASE_AGE,
|
|
32916
32727
|
MONOREPO_LAYOUT,
|
|
32917
32728
|
MonorepoProject,
|
|
32918
|
-
PREFLIGHT_MERGE_METHOD_VALUES,
|
|
32919
32729
|
PROD_DEPLOY_NAME,
|
|
32920
32730
|
PROGRESS_FILES_FORMAT_VALUES,
|
|
32921
32731
|
PnpmWorkspace,
|
|
@@ -33019,8 +32829,6 @@ var TypeScriptConfig = class extends import_projen23.Component {
|
|
|
33019
32829
|
renderIssueTemplatesRuleContent,
|
|
33020
32830
|
renderIssueTemplatesStarterPage,
|
|
33021
32831
|
renderMeetingTypesSection,
|
|
33022
|
-
renderPreflightPrSection,
|
|
33023
|
-
renderPreflightPrShellHelpers,
|
|
33024
32832
|
renderPriorityRulesSection,
|
|
33025
32833
|
renderProgressFileName,
|
|
33026
32834
|
renderProgressFilePath,
|
|
@@ -33053,7 +32861,6 @@ var TypeScriptConfig = class extends import_projen23.Component {
|
|
|
33053
32861
|
resolveModelAlias,
|
|
33054
32862
|
resolveOrchestratorAssets,
|
|
33055
32863
|
resolveOutdirFromPackageName,
|
|
33056
|
-
resolvePreflightPr,
|
|
33057
32864
|
resolveProgressFiles,
|
|
33058
32865
|
resolveRunRatio,
|
|
33059
32866
|
resolveScheduledTasks,
|
|
@@ -33074,7 +32881,6 @@ var TypeScriptConfig = class extends import_projen23.Component {
|
|
|
33074
32881
|
validateAgentTierConfig,
|
|
33075
32882
|
validateIssueTemplatesConfig,
|
|
33076
32883
|
validateMonorepoLayout,
|
|
33077
|
-
validatePreflightPrConfig,
|
|
33078
32884
|
validateProgressFilesConfig,
|
|
33079
32885
|
validateRunRatioConfig,
|
|
33080
32886
|
validateScheduledTasksConfig,
|