@codedrifters/configulator 0.0.280 → 0.0.282

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.js CHANGED
@@ -11643,6 +11643,8 @@ function assertValidStateFilePath(stateFilePath) {
11643
11643
 
11644
11644
  // src/agent/bundles/scheduled-tasks.ts
11645
11645
  var SCHEDULED_TASK_MODEL_VALUES = ["opus", "sonnet", "haiku"];
11646
+ var SCHEDULED_TASK_KIND_VALUES = ["issue-worker", "pipeline"];
11647
+ var DEFAULT_SCHEDULED_TASK_KIND = "issue-worker";
11646
11648
  var DEFAULT_SCHEDULED_TASKS_ROOT = ".claude/scheduled-tasks";
11647
11649
  var DEFAULT_OFF_PEAK_CRON_EXAMPLE = "3,23,43 0-7,14-23 * * *";
11648
11650
  var DEFAULT_SCHEDULED_TASK_ENTRIES = [
@@ -11661,6 +11663,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11661
11663
  "release",
11662
11664
  "hotfix"
11663
11665
  ],
11666
+ kind: "issue-worker",
11664
11667
  recommendedModel: "sonnet",
11665
11668
  enabled: false,
11666
11669
  cron: null,
@@ -11670,11 +11673,17 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11670
11673
  taskId: "worker-orchestrator",
11671
11674
  agent: "orchestrator",
11672
11675
  agentLabel: "Orchestrator",
11673
- typeLabel: "plan",
11676
+ // Pipeline tasks do not filter on a `type:*` label — the
11677
+ // orchestrator runs an end-to-end cycle every invocation. The
11678
+ // `typeLabel` field is required by the registry shape so we
11679
+ // store the routing-bucket sentinel `feat`; rendered output
11680
+ // uses the `_(none — pipeline manager)_` cell instead.
11681
+ typeLabel: "feat",
11682
+ kind: "pipeline",
11674
11683
  recommendedModel: "sonnet",
11675
11684
  enabled: false,
11676
11685
  cron: null,
11677
- description: "Dispatcher that triages the backlog, runs pre-flight PR merges, and reports the next work item."
11686
+ description: "End-to-end pipeline manager: pre-flight PR merge, triage, maintenance, queue scan, delegate the picked issue to the issue-worker, then cleanup."
11678
11687
  },
11679
11688
  // Tier 1 — research.
11680
11689
  {
@@ -11683,6 +11692,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11683
11692
  agentLabel: "Research",
11684
11693
  typeLabel: "research",
11685
11694
  phasePrefix: "research:",
11695
+ kind: "issue-worker",
11686
11696
  recommendedModel: "opus",
11687
11697
  enabled: false,
11688
11698
  cron: null,
@@ -11694,6 +11704,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11694
11704
  agentLabel: "Industry Discovery",
11695
11705
  typeLabel: "industry-discovery",
11696
11706
  phasePrefix: "industry:",
11707
+ kind: "issue-worker",
11697
11708
  recommendedModel: "opus",
11698
11709
  enabled: false,
11699
11710
  cron: null,
@@ -11705,6 +11716,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11705
11716
  agentLabel: "Standards Research",
11706
11717
  typeLabel: "standards-research",
11707
11718
  phasePrefix: "standards:",
11719
+ kind: "issue-worker",
11708
11720
  recommendedModel: "opus",
11709
11721
  enabled: false,
11710
11722
  cron: null,
@@ -11716,6 +11728,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11716
11728
  agentLabel: "Regulatory Research",
11717
11729
  typeLabel: "regulatory-research",
11718
11730
  phasePrefix: "regulatory:",
11731
+ kind: "issue-worker",
11719
11732
  recommendedModel: "opus",
11720
11733
  enabled: false,
11721
11734
  cron: null,
@@ -11728,6 +11741,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11728
11741
  agentLabel: "Company Profile",
11729
11742
  typeLabel: "company-profile",
11730
11743
  phasePrefix: "company:",
11744
+ kind: "issue-worker",
11731
11745
  recommendedModel: "sonnet",
11732
11746
  enabled: false,
11733
11747
  cron: null,
@@ -11739,6 +11753,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11739
11753
  agentLabel: "People Profile",
11740
11754
  typeLabel: "people-profile",
11741
11755
  phasePrefix: "people:",
11756
+ kind: "issue-worker",
11742
11757
  recommendedModel: "sonnet",
11743
11758
  enabled: false,
11744
11759
  cron: null,
@@ -11750,6 +11765,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11750
11765
  agentLabel: "Software Profile",
11751
11766
  typeLabel: "software-profile",
11752
11767
  phasePrefix: "software:",
11768
+ kind: "issue-worker",
11753
11769
  recommendedModel: "sonnet",
11754
11770
  enabled: false,
11755
11771
  cron: null,
@@ -11761,6 +11777,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11761
11777
  agentLabel: "Customer Profile",
11762
11778
  typeLabel: "customer-profile",
11763
11779
  phasePrefix: "customer:",
11780
+ kind: "issue-worker",
11764
11781
  recommendedModel: "sonnet",
11765
11782
  enabled: false,
11766
11783
  cron: null,
@@ -11773,6 +11790,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11773
11790
  agentLabel: "Business Models",
11774
11791
  typeLabel: "business-model",
11775
11792
  phasePrefix: "business-models:",
11793
+ kind: "issue-worker",
11776
11794
  recommendedModel: "opus",
11777
11795
  enabled: false,
11778
11796
  cron: null,
@@ -11784,6 +11802,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11784
11802
  agentLabel: "BCM Writer",
11785
11803
  typeLabel: "bcm-document",
11786
11804
  phasePrefix: "bcm:",
11805
+ kind: "issue-worker",
11787
11806
  recommendedModel: "sonnet",
11788
11807
  enabled: false,
11789
11808
  cron: null,
@@ -11795,6 +11814,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11795
11814
  agentLabel: "Requirements Analyst",
11796
11815
  typeLabel: "requirement",
11797
11816
  phasePrefix: "req:",
11817
+ kind: "issue-worker",
11798
11818
  recommendedModel: "opus",
11799
11819
  enabled: false,
11800
11820
  cron: null,
@@ -11806,6 +11826,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11806
11826
  agentLabel: "Requirements Writer",
11807
11827
  typeLabel: "requirement",
11808
11828
  phaseLabels: ["req:write"],
11829
+ kind: "issue-worker",
11809
11830
  recommendedModel: "sonnet",
11810
11831
  enabled: false,
11811
11832
  cron: null,
@@ -11817,6 +11838,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11817
11838
  agentLabel: "Requirements Reviewer",
11818
11839
  typeLabel: "requirement",
11819
11840
  phaseLabels: ["req:review", "req:deprecate"],
11841
+ kind: "issue-worker",
11820
11842
  recommendedModel: "opus",
11821
11843
  enabled: false,
11822
11844
  cron: null,
@@ -11829,6 +11851,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11829
11851
  agentLabel: "Meeting Analysis",
11830
11852
  typeLabel: "meeting-processing",
11831
11853
  phasePrefix: "meeting:",
11854
+ kind: "issue-worker",
11832
11855
  recommendedModel: "sonnet",
11833
11856
  enabled: false,
11834
11857
  cron: null,
@@ -11840,6 +11863,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11840
11863
  agentLabel: "Agenda",
11841
11864
  typeLabel: "agenda",
11842
11865
  phasePrefix: "agenda:",
11866
+ kind: "issue-worker",
11843
11867
  recommendedModel: "sonnet",
11844
11868
  enabled: false,
11845
11869
  cron: null,
@@ -11851,6 +11875,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11851
11875
  agentLabel: "Maintenance",
11852
11876
  typeLabel: "maintenance",
11853
11877
  phasePrefix: "maint:",
11878
+ kind: "issue-worker",
11854
11879
  recommendedModel: "haiku",
11855
11880
  enabled: false,
11856
11881
  cron: null,
@@ -11861,6 +11886,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11861
11886
  agent: "pr-reviewer",
11862
11887
  agentLabel: "PR Review",
11863
11888
  typeLabel: "pr-review",
11889
+ kind: "issue-worker",
11864
11890
  recommendedModel: "haiku",
11865
11891
  enabled: false,
11866
11892
  cron: null,
@@ -11872,6 +11898,7 @@ var DEFAULT_SCHEDULED_TASK_ENTRIES = [
11872
11898
  agentLabel: "Docs Sync",
11873
11899
  typeLabel: "docs-sync",
11874
11900
  phasePrefix: "docs-sync:",
11901
+ kind: "issue-worker",
11875
11902
  recommendedModel: "sonnet",
11876
11903
  enabled: false,
11877
11904
  cron: null,
@@ -11984,14 +12011,20 @@ function renderScheduledTasksSection(resolved) {
11984
12011
  "|---------|--------------|-----------------|--------------|-------|---------|------|"
11985
12012
  );
11986
12013
  for (const task of resolved.tasks) {
11987
- const typeCell = task.typeLabels && task.typeLabels.length > 1 ? task.typeLabels.map((l) => `\`type:${l}\``).join(", ") : `\`type:${task.typeLabel}\``;
12014
+ let typeCell;
11988
12015
  let phaseCell;
11989
- if (task.phaseLabels && task.phaseLabels.length > 0) {
11990
- phaseCell = task.phaseLabels.map((l) => `\`${l}\``).join(", ");
11991
- } else if (task.phasePrefix) {
11992
- phaseCell = `\`${task.phasePrefix}*\``;
12016
+ if (task.kind === "pipeline") {
12017
+ typeCell = "_(none \u2014 pipeline manager)_";
12018
+ phaseCell = "_(none \u2014 pipeline manager)_";
11993
12019
  } else {
11994
- phaseCell = "_(any)_";
12020
+ typeCell = task.typeLabels && task.typeLabels.length > 1 ? task.typeLabels.map((l) => `\`type:${l}\``).join(", ") : `\`type:${task.typeLabel}\``;
12021
+ if (task.phaseLabels && task.phaseLabels.length > 0) {
12022
+ phaseCell = task.phaseLabels.map((l) => `\`${l}\``).join(", ");
12023
+ } else if (task.phasePrefix) {
12024
+ phaseCell = `\`${task.phasePrefix}*\``;
12025
+ } else {
12026
+ phaseCell = "_(any)_";
12027
+ }
11995
12028
  }
11996
12029
  const cronCell = task.cron ? `\`${task.cron}\`` : "_manual-only_";
11997
12030
  lines.push(
@@ -12011,6 +12044,12 @@ function renderScheduledTaskSkillFile(task) {
12011
12044
  lines.push(`cron: "${task.cron}"`);
12012
12045
  }
12013
12046
  lines.push("---", "");
12047
+ if (task.kind === "pipeline") {
12048
+ return renderPipelineSkillBody(task, lines);
12049
+ }
12050
+ return renderIssueWorkerSkillBody(task, lines);
12051
+ }
12052
+ function renderIssueWorkerSkillBody(task, lines) {
12014
12053
  lines.push(
12015
12054
  `# ${task.agentLabel} Scheduled Worker`,
12016
12055
  "",
@@ -12063,6 +12102,36 @@ function renderScheduledTaskSkillFile(task) {
12063
12102
  );
12064
12103
  return lines.join("\n");
12065
12104
  }
12105
+ function renderPipelineSkillBody(task, lines) {
12106
+ lines.push(
12107
+ `# ${task.agentLabel} Pipeline Worker`,
12108
+ "",
12109
+ `You are the **${task.agentLabel}** pipeline worker. This task is a`,
12110
+ "**pipeline manager**, not an issue-worker delegator \u2014 it does not",
12111
+ "filter issues by `type:*` or phase label. Each invocation runs the",
12112
+ `target sub-agent's full end-to-end cycle exactly once.`,
12113
+ "",
12114
+ `Run \`.claude/agents/${task.agent}.md\` and follow its workflow`,
12115
+ "from start to finish. The sub-agent is responsible for picking the",
12116
+ "next unit of work, delegating implementation to other workers as",
12117
+ "needed, and exiting cleanly.",
12118
+ "",
12119
+ "## Recommended model",
12120
+ "",
12121
+ `**${capitalize(task.recommendedModel)}** \u2014 see`,
12122
+ `\`.claude/agents/${task.agent}.md\` for the agent's full model`,
12123
+ "rationale. The operator launches the scheduler instance on the",
12124
+ "recommended model; this task does not pin a model at the runtime",
12125
+ "level.",
12126
+ "",
12127
+ "## Exit conditions",
12128
+ "",
12129
+ "Exit cleanly after one full cycle of the target pipeline (or",
12130
+ "immediately if the pipeline reports there is no eligible work).",
12131
+ "Do not loop \u2014 the next scheduled invocation runs another cycle."
12132
+ );
12133
+ return lines.join("\n");
12134
+ }
12066
12135
  var SAMPLE_PHASE = "phase1";
12067
12136
  function capitalize(value) {
12068
12137
  if (value.length === 0) {
@@ -12083,6 +12152,9 @@ function applyOverride(base, override, taskId) {
12083
12152
  if (override.phaseLabels !== void 0) {
12084
12153
  assertNonEmptyLabelList(override.phaseLabels, taskId, "phaseLabels");
12085
12154
  }
12155
+ if (override.kind !== void 0) {
12156
+ assertValidKind(override.kind, taskId);
12157
+ }
12086
12158
  const resolvedTypeLabels = override.typeLabels !== void 0 ? normalizeLabelList(override.typeLabels) : base.typeLabels;
12087
12159
  const primaryTypeLabel = resolvedTypeLabels?.[0] ?? base.typeLabel;
12088
12160
  return {
@@ -12093,7 +12165,8 @@ function applyOverride(base, override, taskId) {
12093
12165
  description: override.description ?? base.description,
12094
12166
  typeLabel: primaryTypeLabel,
12095
12167
  typeLabels: resolvedTypeLabels,
12096
- phaseLabels: override.phaseLabels !== void 0 ? normalizeLabelList(override.phaseLabels) : base.phaseLabels
12168
+ phaseLabels: override.phaseLabels !== void 0 ? normalizeLabelList(override.phaseLabels) : base.phaseLabels,
12169
+ kind: override.kind ?? base.kind
12097
12170
  };
12098
12171
  }
12099
12172
  function validateFullEntry(entry) {
@@ -12125,6 +12198,9 @@ function validateFullEntry(entry) {
12125
12198
  if (entry.phaseLabels !== void 0) {
12126
12199
  assertNonEmptyLabelList(entry.phaseLabels, taskId, "phaseLabels");
12127
12200
  }
12201
+ if (entry.kind !== void 0) {
12202
+ assertValidKind(entry.kind, taskId);
12203
+ }
12128
12204
  const typeLabels = entry.typeLabels !== void 0 ? normalizeLabelList(entry.typeLabels) : void 0;
12129
12205
  const primaryTypeLabel = typeLabels?.[0] ?? typeLabel;
12130
12206
  return {
@@ -12138,9 +12214,19 @@ function validateFullEntry(entry) {
12138
12214
  recommendedModel: entry.recommendedModel,
12139
12215
  enabled: entry.enabled ?? false,
12140
12216
  cron: entry.cron ?? null,
12141
- description: entry.description ?? `${agent} scheduled worker.`
12217
+ description: entry.description ?? `${agent} scheduled worker.`,
12218
+ kind: entry.kind ?? DEFAULT_SCHEDULED_TASK_KIND
12142
12219
  };
12143
12220
  }
12221
+ function assertValidKind(value, taskId) {
12222
+ if (!SCHEDULED_TASK_KIND_VALUES.includes(value)) {
12223
+ throw new Error(
12224
+ `ScheduledTasksConfig entry for taskId ${JSON.stringify(taskId)} has kind ${JSON.stringify(
12225
+ value
12226
+ )}; must be one of ${SCHEDULED_TASK_KIND_VALUES.join(" | ")}.`
12227
+ );
12228
+ }
12229
+ }
12144
12230
  function assertValidModel(value, taskId) {
12145
12231
  if (!SCHEDULED_TASK_MODEL_VALUES.includes(value)) {
12146
12232
  throw new Error(
@@ -12484,9 +12570,6 @@ var DEFAULT_AGENT_TIERS = [
12484
12570
  { type: "docs", tier: 0, role: AGENT_TIER_ROLES[0] },
12485
12571
  { type: "release", tier: 0, role: AGENT_TIER_ROLES[0] },
12486
12572
  { type: "hotfix", tier: 0, role: AGENT_TIER_ROLES[0] },
12487
- { type: "plan", tier: 0, role: AGENT_TIER_ROLES[0] },
12488
- { type: "review", tier: 0, role: AGENT_TIER_ROLES[0] },
12489
- { type: "adr", tier: 0, role: AGENT_TIER_ROLES[0] },
12490
12573
  // Tier 1 — research.
12491
12574
  { type: "research", tier: 1, role: AGENT_TIER_ROLES[1] },
12492
12575
  { type: "industry-discovery", tier: 1, role: AGENT_TIER_ROLES[1] },
@@ -13395,16 +13478,16 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio, preflight) {
13395
13478
  "}",
13396
13479
  "",
13397
13480
  "cmd_tick() {",
13398
- ' if [[ "$RUN_RATIO_ENABLED" != "1" ]]; then',
13399
- " # Ratio disabled: every run dispatches, and we don't advance the",
13400
- " # persistent counter. Echo a stable sentinel so callers can still",
13401
- " # branch on the output.",
13402
- ' echo "run=0 type=dispatch (ratio disabled)"',
13403
- " return 0",
13404
- " fi",
13405
- " local result",
13406
- " result=$(run_counter_tick)",
13407
- ' echo "$result"',
13481
+ " # DEPRECATED: the orchestrator no longer maintains a dispatch /",
13482
+ " # housekeeping run-counter \u2014 every invocation runs the full",
13483
+ " # end-to-end cycle. This subcommand is retained as a no-op for one",
13484
+ " # release so any consumer mid-flight does not error out, then will",
13485
+ " # be removed entirely. Existing state files at",
13486
+ ' # "$ORCHESTRATOR_STATE_FILE" can be left alone (they will become',
13487
+ " # orphaned).",
13488
+ ' echo "tick: deprecated no-op (orchestrator runs a single linear cycle every invocation)" >&2',
13489
+ ' echo "run=0 type=dispatch (deprecated)"',
13490
+ " return 0",
13408
13491
  "}",
13409
13492
  "",
13410
13493
  "# \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",
@@ -13428,7 +13511,7 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio, preflight) {
13428
13511
  function buildCheckBlockedProcedure(tiers, scopeGate = resolveScopeGate(), runRatio = resolveRunRatio(), preflight = resolvePreflightPr()) {
13429
13512
  return {
13430
13513
  name: "check-blocked.sh",
13431
- description: "Token-efficient issue triage script with subcommands: eligible, unblock, stale, orphaned, prs, scope, tick, preflight. 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 advances the orchestrator run counter and classifies the run as dispatch or housekeeping; the preflight subcommand emits one eligibility line per open PR that is mergeable, CI-green, approved (or auto-merge already enabled), and linked to an open issue.",
13514
+ description: "Token-efficient issue triage script with subcommands: eligible, unblock, stale, orphaned, prs, scope, preflight, 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 preflight subcommand emits one eligibility line per open PR that is mergeable, CI-green, approved (or auto-merge already enabled), and linked to an open issue. The tick subcommand is a deprecation no-op retained for one release (the orchestrator no longer maintains a dispatch/housekeeping run counter).",
13432
13515
  content: buildCheckBlockedScript(tiers, scopeGate, runRatio, preflight)
13433
13516
  };
13434
13517
  }
@@ -13450,62 +13533,55 @@ var unblockDependentsProcedure = buildUnblockDependentsProcedure(
13450
13533
  );
13451
13534
  var orchestratorSubAgent = {
13452
13535
  name: "orchestrator",
13453
- description: "Pipeline manager that reviews PRs, triages issues, and identifies the next work item \u2014 never implements code",
13536
+ description: "End-to-end pipeline manager that runs one full cycle every invocation: pre-flight PR merge \u2192 triage \u2192 maintenance \u2192 queue scan \u2192 delegate the picked issue to the issue-worker \u2192 cleanup",
13454
13537
  model: AGENT_MODEL.POWERFUL,
13455
13538
  maxTurns: 100,
13539
+ canDelegateToAgents: ["issue-worker", "pr-reviewer"],
13456
13540
  platforms: { cursor: { exclude: true } },
13457
13541
  prompt: [
13458
13542
  "# Orchestrator Agent",
13459
13543
  "",
13460
- "You are a pipeline manager for the **{{repository.owner}}/{{repository.name}}** repository.",
13461
- "You review PRs, triage issues, and identify the next work item. You **never**",
13462
- "implement code, create branches for issues, or claim issues.",
13463
- "",
13464
- "Each invocation is either a **dispatch run** or a **housekeeping run**;",
13465
- "the run type is decided by the persistent run counter managed in Phase A",
13466
- "below. Execute only the phases listed for the classified run type \u2014",
13467
- "the run ratio keeps the pipeline balanced without human scheduling.",
13544
+ "You are the pipeline orchestrator for the **{{repository.owner}}/{{repository.name}}** repository.",
13545
+ "Each invocation runs **one full end-to-end cycle**. The cycle merges",
13546
+ "approved PRs, triages blocked issues, runs maintenance scans, picks the",
13547
+ "next ready issue, and **delegates implementation to the `issue-worker`**",
13548
+ "sub-agent in scheduled mode. The orchestrator itself never implements",
13549
+ "code, creates branches, or pushes commits \u2014 it routes work to other",
13550
+ "agents.",
13551
+ "",
13552
+ "Run the phases below in order on every invocation. There is no",
13553
+ "dispatch/housekeeping fork \u2014 every phase runs every time.",
13554
+ "",
13555
+ "Phase ordering (each runs exactly once per invocation):",
13556
+ "",
13557
+ "1. **Phase A \u2014 Startup.** Pull the default branch.",
13558
+ "2. **Phase B0 \u2014 Pre-flight PR Merge.** Land every eligible approved /",
13559
+ " CI-green PR before triage reads dependency state.",
13560
+ "3. **Phase C \u2014 Triage / Unblock.** Flip dependents that have all",
13561
+ " their dependencies closed back to `status:ready`.",
13562
+ "4. **Phase D \u2014 Maintenance.** Stale-issue and orphaned-resource scan",
13563
+ " plus a needs-attention summary.",
13564
+ "5. **Phase E \u2014 Queue Scan.** Pick the highest-priority `PICK` line",
13565
+ " and run the scope gate. If the result is `large`, flag and stop.",
13566
+ "6. **Phase G \u2014 Delegate Implementation.** Hand the picked issue off",
13567
+ " to the `issue-worker` sub-agent in scheduled mode. The worker",
13568
+ " handles claim \u2192 branch \u2192 implement \u2192 commit \u2192 PR autonomously.",
13569
+ "7. **Phase F \u2014 Cleanup.** Return to the default branch and log the",
13570
+ " run summary.",
13468
13571
  "",
13469
13572
  "---",
13470
13573
  "",
13471
13574
  ...PROJECT_CONTEXT_READER_SECTION,
13472
13575
  "## Phase A: Startup",
13473
13576
  "",
13474
- "Pull the default branch and tick the run counter:",
13577
+ "Pull the default branch:",
13475
13578
  "",
13476
13579
  "```bash",
13477
13580
  "git checkout main && git pull origin main",
13478
- ".claude/procedures/check-blocked.sh tick",
13479
- "```",
13480
- "",
13481
- "The `tick` subcommand advances the persistent run counter and",
13482
- "classifies the run. Expect one of:",
13483
- "",
13484
- "```",
13485
- "run=<n> type=dispatch",
13486
- "run=<n> type=housekeeping",
13487
- "run=0 type=dispatch (ratio disabled)",
13488
13581
  "```",
13489
13582
  "",
13490
- "Branch on the emitted `type`:",
13491
- "",
13492
- "- `dispatch` \u2014 execute **Phase C** (Triage \u2014 Unblock) and",
13493
- " **Phase E** (Queue Scan). Skip Phase B (Batch PR Review) and",
13494
- " Phase D (Maintenance).",
13495
- "- `housekeeping` \u2014 execute **Phase B** (Batch PR Review) and",
13496
- " **Phase D** (Maintenance). Skip Phase C (Unblock) and Phase E",
13497
- " (Queue Scan).",
13498
- "",
13499
- "Phase F (Cleanup) always runs. **Phase B0 (Pre-flight PR Merge)**",
13500
- "also always runs \u2014 it sits between Phase A and the per-run-type",
13501
- "split so eligible PRs land before dependency state is read.",
13502
- "See the **Run ratio (dispatch vs housekeeping)** and **Pre-flight",
13503
- "PR merge** sections in `CLAUDE.md` for the full contracts.",
13504
- "",
13505
13583
  "## Phase B0: Pre-flight PR Merge",
13506
13584
  "",
13507
- "_Runs on every invocation (dispatch and housekeeping)._",
13508
- "",
13509
13585
  "Before any other phase reads dependency state, land every",
13510
13586
  "eligible PR. The sweep is idempotent \u2014 `gh pr merge` on an",
13511
13587
  "already-merged PR is a no-op \u2014 so re-running on back-to-back",
@@ -13598,41 +13674,8 @@ var orchestratorSubAgent = {
13598
13674
  "or more eligibility checks. The `pr-reviewer` or a human",
13599
13675
  "operator picks them up on the normal review path.",
13600
13676
  "",
13601
- "## Phase B: Batch PR Review",
13602
- "",
13603
- "_Housekeeping runs only \u2014 skip on dispatch runs._",
13604
- "",
13605
- "Find all PRs eligible for review:",
13606
- "",
13607
- "```bash",
13608
- ".claude/procedures/check-blocked.sh prs",
13609
- "```",
13610
- "",
13611
- "For each `REVIEW PR #N issue:#M branch:<branch>` line:",
13612
- "",
13613
- "1. Check out the PR branch: `gh pr checkout N`",
13614
- "2. Review the PR:",
13615
- " - Read the PR description and linked issue: `gh pr view N`",
13616
- " - Review the diff: `gh pr diff N`",
13617
- " - Check all changed files for correctness, conventions, and test coverage",
13618
- " - Verify PR conventions: conventional commit title, closing keyword, summary present",
13619
- " - Check CI status: `gh pr checks N`",
13620
- "3. If the PR passes review:",
13621
- " - Enable squash auto-merge: `gh pr merge N --auto --squash --subject '<conventional-commit-title>' --body '<extended-description>'`",
13622
- "4. If the PR fails review:",
13623
- " - Request changes: `gh pr review N --request-changes --body '<findings>'`",
13624
- "5. After each PR (whether merged or not):",
13625
- " ```bash",
13626
- " git checkout main && git pull origin main",
13627
- " ```",
13628
- "",
13629
- "Skip lines starting with `SKIP` \u2014 those PRs are not eligible.",
13630
- "If output is `NO_OPEN_PRS` or `NO_ELIGIBLE_PRS`, skip to Phase C.",
13631
- "",
13632
13677
  "## Phase C: Triage \u2014 Unblock",
13633
13678
  "",
13634
- "_Dispatch runs only \u2014 skip on housekeeping runs._",
13635
- "",
13636
13679
  "Check for blocked issues whose dependencies have resolved:",
13637
13680
  "",
13638
13681
  "```bash",
@@ -13644,9 +13687,9 @@ var orchestratorSubAgent = {
13644
13687
  "`.claude/procedures/unblock-dependents.sh <n>` as part of that",
13645
13688
  "transition, so in steady state Phase C should usually report",
13646
13689
  "`NO_BLOCKED_ISSUES` or leave dependents untouched. Phase C still",
13647
- "runs on every dispatch so issues that slipped through \u2014 human",
13690
+ "runs on every cycle so issues that slipped through \u2014 human",
13648
13691
  "closures, manual `status:done` edits, or crashes mid-sweep \u2014 get",
13649
- "picked up within one dispatch cycle. See the **Agent-driven",
13692
+ "picked up within one cycle. See the **Agent-driven",
13650
13693
  "unblocking** section in `CLAUDE.md` for the per-agent contract.",
13651
13694
  "",
13652
13695
  "For each `UNBLOCK #N` line:",
@@ -13658,12 +13701,10 @@ var orchestratorSubAgent = {
13658
13701
  "For `BLOCKED #N \u2014 no Depends on field found`: leave as-is (Phase D will",
13659
13702
  "catch it if it's been blocked too long).",
13660
13703
  "",
13661
- "If output is `NO_BLOCKED_ISSUES`, skip to Phase D.",
13704
+ "If output is `NO_BLOCKED_ISSUES`, continue to Phase D.",
13662
13705
  "",
13663
13706
  "## Phase D: Maintenance",
13664
13707
  "",
13665
- "_Housekeeping runs only \u2014 skip on dispatch runs._",
13666
- "",
13667
13708
  "### D1: Stale Detection",
13668
13709
  "",
13669
13710
  "```bash",
@@ -13706,8 +13747,6 @@ var orchestratorSubAgent = {
13706
13747
  "",
13707
13748
  "## Phase E: Queue Scan",
13708
13749
  "",
13709
- "_Dispatch runs only \u2014 skip on housekeeping runs._",
13710
- "",
13711
13750
  "Find the highest-priority ready issue:",
13712
13751
  "",
13713
13752
  "```bash",
@@ -13737,7 +13776,8 @@ var orchestratorSubAgent = {
13737
13776
  "```",
13738
13777
  "",
13739
13778
  "If the scope is `small` or `medium`, continue \u2014 the issue is",
13740
- "dispatchable. Report the first `PICK` line as:",
13779
+ "dispatchable. Record the first `PICK` line as the next work item",
13780
+ "and proceed to Phase G:",
13741
13781
  "",
13742
13782
  "```",
13743
13783
  'NEXT_WORK_ITEM #<number> priority:<level> tier:<n> type:<label> scope:<small|medium> "<title>"',
@@ -13775,10 +13815,52 @@ var orchestratorSubAgent = {
13775
13815
  "",
13776
13816
  `Unknown \`type:*\` labels fall through to tier ${UNKNOWN_TYPE_FALLBACK_TIER} (${AGENT_TIER_ROLES[UNKNOWN_TYPE_FALLBACK_TIER]}) so an unclassified issue never blocks the queue. See the **Funnel-tier dispatch ordering** and **Scope gate** sections in \`CLAUDE.md\` for the full tier table and decomposition template.`,
13777
13817
  "",
13778
- "If output is `NO_READY_ISSUES`, report that the queue is empty.",
13779
- "",
13780
- "**Do NOT claim the issue, create a branch, or start implementation.**",
13781
- "The worker agent handles that.",
13818
+ "If output is `NO_READY_ISSUES`, report that the queue is empty,",
13819
+ "skip Phase G, and proceed directly to Phase F.",
13820
+ "",
13821
+ "**Do NOT claim the issue, create a branch, or start implementation",
13822
+ "yourself.** Phase G hands the issue off to the `issue-worker`",
13823
+ "sub-agent in scheduled mode; the worker performs the actual",
13824
+ "claim \u2192 branch \u2192 implement \u2192 commit \u2192 PR cycle.",
13825
+ "",
13826
+ "## Phase G: Delegate Implementation",
13827
+ "",
13828
+ "_Skip when Phase E reported `NO_READY_ISSUES`, the queue is empty,",
13829
+ "or Phase E flagged the top `PICK` as `large` \u2014 there is nothing to",
13830
+ "delegate._",
13831
+ "",
13832
+ "Hand the picked issue off to the `issue-worker` sub-agent in",
13833
+ "**scheduled mode** so it runs the full claim \u2192 branch \u2192 implement",
13834
+ "\u2192 commit \u2192 PR cycle autonomously, without pausing for an",
13835
+ "interactive approval. The worker reads the literal phrase",
13836
+ "`scheduled mode` in its invocation prompt and skips the Phase 6",
13837
+ "approval pause; see the **Invocation Mode** section in",
13838
+ "`.claude/agents/issue-worker.md` for the full contract.",
13839
+ "",
13840
+ "Invoke the sub-agent with a single-message brief:",
13841
+ "",
13842
+ "> `scheduled mode`: work issue #<number>. Pick this issue from the",
13843
+ "> queue, claim it, route to the appropriate typed agent if one",
13844
+ "> applies, implement the change, run the verification commands,",
13845
+ "> commit, push, and open a PR labeled `origin:issue-worker` that",
13846
+ "> closes the issue. Do not pause for approval. Return a one-line",
13847
+ "> summary as the final line of your response in the form",
13848
+ "> `WORKER_DONE issue:#<n> pr:#<m>` on success or",
13849
+ "> `WORKER_FAILED issue:#<n> reason:<short reason>` on failure.",
13850
+ "",
13851
+ "Substitute `<number>` with the issue number from the",
13852
+ "`NEXT_WORK_ITEM` line in Phase E. The orchestrator is **read-only**",
13853
+ "with respect to the issue and its branch \u2014 never claim the issue,",
13854
+ "create a branch, or push commits in this phase. Implementation is",
13855
+ "the worker's job.",
13856
+ "",
13857
+ "If the worker's final line is missing, malformed, or indicates an",
13858
+ "error, **do not retry** in the same orchestrator session \u2014 log the",
13859
+ "outcome and proceed to Phase F. The next orchestrator invocation",
13860
+ "will re-scan the queue and pick the issue up again if it is still",
13861
+ "ready (it may have been left as `status:in-progress` by a partial",
13862
+ "worker run, in which case the orchestrator's stale-detection in",
13863
+ "Phase D will surface it for human triage on a future cycle).",
13782
13864
  "",
13783
13865
  "## Phase F: Cleanup",
13784
13866
  "",
@@ -13787,44 +13869,47 @@ var orchestratorSubAgent = {
13787
13869
  "git fetch --prune origin",
13788
13870
  "```",
13789
13871
  "",
13790
- "Log completion: phases executed, PRs reviewed, issues unblocked,",
13791
- "stale issues flagged, and next work item (if any).",
13872
+ "Log completion: phases executed, PRs merged in pre-flight, issues",
13873
+ "unblocked, stale issues flagged, the next work item picked, and",
13874
+ "the outcome of Phase G's delegation (worker success / failure /",
13875
+ "skipped because the queue was empty).",
13792
13876
  "",
13793
13877
  "---",
13794
13878
  "",
13795
13879
  "## Rules",
13796
13880
  "",
13797
- "1. **Never implement code.** You triage, review, and report \u2014 you do not code.",
13798
- "2. **Never claim issues.** Do not add `status:in-progress` or create branches for issues.",
13881
+ "1. **Never implement code.** You merge, triage, scan, and delegate \u2014 you do not code.",
13882
+ "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.",
13799
13883
  "3. **Always use check-blocked.sh.** All triage queries go through the shell script for token efficiency.",
13800
13884
  "4. **Follow CLAUDE.md conventions** for all git and gh operations.",
13801
13885
  "5. **Priority order:** critical > high > medium > low > trivial, then **funnel tier asc** (lower tier wins ties), then FIFO by issue number.",
13802
13886
  "6. **Never dispatch a `large` issue.** Always run the scope check",
13803
13887
  " on the top `PICK` line before reporting `NEXT_WORK_ITEM`. A",
13804
13888
  " `large` issue must be flagged with `status:needs-attention` and",
13805
- " handed a decomposition proposal \u2014 never claimed, never branched.",
13806
- "7. **Respect the run-ratio branching.** Every invocation must begin",
13807
- " with `.claude/procedures/check-blocked.sh tick`. Execute only",
13808
- " the phases listed for the classified run type \u2014",
13809
- " `type=dispatch` runs Phases C + E, `type=housekeeping` runs",
13810
- " Phases B + D. Phase F always runs. See the **Run ratio** section",
13811
- " in `CLAUDE.md` for the full contract.",
13812
- "8. **Always run pre-flight before reading dependency state.**",
13813
- " Phase B0 (Pre-flight PR Merge) runs on every invocation \u2014",
13814
- " dispatch and housekeeping \u2014 immediately after Phase A. Never",
13815
- " skip Phase B0: without it, an issue whose only remaining",
13816
- " blocker is an approved-but-not-yet-merged PR reads as blocked",
13817
- " on every cycle and the pipeline thrashes. See the **Pre-flight",
13818
- " PR merge** section in `CLAUDE.md` for eligibility rules and",
13819
- " the delegate-vs-inline modes.",
13820
- "9. **Sweep dependents whenever you apply `status:done`.** Every",
13889
+ " handed a decomposition proposal \u2014 never claimed, never branched,",
13890
+ " 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
+ "8. **Sweep dependents whenever you apply `status:done`.** Every",
13821
13900
  " `status:done` transition must be immediately followed by",
13822
13901
  " `.claude/procedures/unblock-dependents.sh <n>` so downstream",
13823
13902
  " `Depends on: #<n>` issues flip to `status:ready` without",
13824
- " waiting for the next dispatch. Phase B0's post-merge",
13903
+ " waiting for the next cycle. Phase B0's post-merge",
13825
13904
  " verification (and any inline-mode merge) already calls the",
13826
13905
  " sweep; don't skip it. See the **Agent-driven unblocking**",
13827
- " section in `CLAUDE.md` for the contract."
13906
+ " section in `CLAUDE.md` for the contract.",
13907
+ "9. **Always invoke `issue-worker` in scheduled mode.** Phase G's",
13908
+ " delegation prompt must contain the literal phrase",
13909
+ " `scheduled mode` so the worker skips its interactive approval",
13910
+ " pause and runs the implementation cycle autonomously. Without",
13911
+ " the phrase the worker pauses for human approval and the",
13912
+ " delegation stalls."
13828
13913
  ].join("\n")
13829
13914
  };
13830
13915
  var issueWorkerSubAgent = {
@@ -14255,9 +14340,10 @@ var ORCHESTRATOR_CONVENTIONS_PREAMBLE = [
14255
14340
  "",
14256
14341
  "When running the orchestrator agent (`.claude/agents/orchestrator.md`):",
14257
14342
  "",
14258
- "- The orchestrator **never** implements code or creates branches for issues",
14259
- "- It reviews PRs, triages issues, and reports the next work item",
14343
+ "- The orchestrator runs **one full end-to-end cycle every invocation**: pre-flight PR merge \u2192 triage / unblock \u2192 maintenance \u2192 queue scan \u2192 delegate to `issue-worker` \u2192 cleanup",
14344
+ "- The orchestrator **never** implements code, creates branches, or pushes commits \u2014 it merges PRs, triages issues, picks the next work item, and delegates implementation to other sub-agents",
14260
14345
  "- All triage queries use `.claude/procedures/check-blocked.sh` for token efficiency",
14346
+ "- 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.",
14261
14347
  "- Priority order: critical > high > medium > low > trivial, then **funnel tier asc** (lower tier wins ties), then FIFO by issue number",
14262
14348
  "- Stale thresholds: 72h for in-progress, 168h for blocked",
14263
14349
  "- Flagged issues get `status:needs-attention` \u2014 they are not auto-reset"
@@ -14322,7 +14408,7 @@ var orchestratorBundle = {
14322
14408
  rules: [
14323
14409
  {
14324
14410
  name: "orchestrator-conventions",
14325
- description: "Guidelines for orchestrator agent behavior and pipeline management, including the funnel-tier dispatch sort, scope gate, and dispatch-to-housekeeping run ratio",
14411
+ description: "Guidelines for orchestrator agent behavior and pipeline management, including the funnel-tier dispatch sort, scope gate, pre-flight PR merge contract, and per-agent scheduled-task layout",
14326
14412
  scope: AGENT_RULE_SCOPE.ALWAYS,
14327
14413
  content: buildOrchestratorConventionsContent(
14328
14414
  DEFAULT_AGENT_TIERS,
@@ -26408,7 +26494,7 @@ var VERSION = {
26408
26494
  /**
26409
26495
  * Version of Astro to pin for AstroProject scaffolding.
26410
26496
  */
26411
- ASTRO_VERSION: "6.1.9",
26497
+ ASTRO_VERSION: "6.1.10",
26412
26498
  /**
26413
26499
  * CDK CLI for workflows and command line operations.
26414
26500
  *