opencode-swarm 7.127.1 → 7.128.0

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.
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  createCuratorLLMDelegate
4
- } from "./index-bn3w6ym4.js";
4
+ } from "./index-npycj2tr.js";
5
5
  import"./index-v4n224r1.js";
6
6
  import"./index-cpssctv1.js";
7
7
  import"./index-kk1scggc.js";
@@ -14,7 +14,7 @@ import {
14
14
  runCuratorInit,
15
15
  runCuratorPhase,
16
16
  writeCuratorSummary
17
- } from "./index-bn3w6ym4.js";
17
+ } from "./index-npycj2tr.js";
18
18
  import"./index-v4n224r1.js";
19
19
  import"./index-cpssctv1.js";
20
20
  import"./index-kk1scggc.js";
@@ -1,8 +1,8 @@
1
1
  // @bun
2
2
  import {
3
3
  handleGuardrailExplain
4
- } from "./index-8cnpsbk5.js";
5
- import"./index-bn3w6ym4.js";
4
+ } from "./index-rczj39pc.js";
5
+ import"./index-npycj2tr.js";
6
6
  import"./index-v4n224r1.js";
7
7
  import"./index-cpssctv1.js";
8
8
  import"./index-kk1scggc.js";
@@ -7,7 +7,7 @@ import {
7
7
  isHiveEligible,
8
8
  promoteFromSwarm,
9
9
  promoteToHive
10
- } from "./index-bn3w6ym4.js";
10
+ } from "./index-npycj2tr.js";
11
11
  import"./index-v4n224r1.js";
12
12
  import"./index-cpssctv1.js";
13
13
  import"./index-kk1scggc.js";
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  handleGuardrailExplain
4
- } from "./index-8cnpsbk5.js";
4
+ } from "./index-rczj39pc.js";
5
5
  import {
6
6
  handleGuardrailLog
7
7
  } from "./index-8etcyr9r.js";
@@ -83,7 +83,7 @@ import {
83
83
  handleWriteRetroCommand,
84
84
  normalizeSwarmCommandInput,
85
85
  resolveCommand
86
- } from "./index-bn3w6ym4.js";
86
+ } from "./index-npycj2tr.js";
87
87
  import"./index-v4n224r1.js";
88
88
  import"./index-cpssctv1.js";
89
89
  import"./index-kk1scggc.js";
@@ -12305,11 +12305,11 @@ var _internals15 = {
12305
12305
  }
12306
12306
  },
12307
12307
  applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig, generation) => {
12308
- const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-qqd1fvvg.js");
12308
+ const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-x5dzf1p7.js");
12309
12309
  return applyCuratorKnowledgeUpdates2(directory, recommendations, knowledgeConfig, generation);
12310
12310
  },
12311
12311
  checkHivePromotions: async (entries, knowledgeConfig, directory) => {
12312
- const { checkHivePromotions } = await import("./hive-promoter-14jh86kj.js");
12312
+ const { checkHivePromotions } = await import("./hive-promoter-z8gc80zq.js");
12313
12313
  return checkHivePromotions(entries, knowledgeConfig, directory);
12314
12314
  },
12315
12315
  applyProposalTriage: async (directory, triage) => {
@@ -20176,8 +20176,8 @@ var _internals28 = {
20176
20176
  loadCuratorDeps: async () => {
20177
20177
  const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate: createCuratorLLMDelegate2 }] = await Promise.all([
20178
20178
  import("./schema-2x7wsb0n.js"),
20179
- import("./curator-qqd1fvvg.js"),
20180
- import("./curator-llm-factory-4t2h2p60.js")
20179
+ import("./curator-x5dzf1p7.js"),
20180
+ import("./curator-llm-factory-rz4cbq28.js")
20181
20181
  ]);
20182
20182
  return { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 };
20183
20183
  }
@@ -20676,7 +20676,7 @@ import { fileURLToPath } from "url";
20676
20676
  // package.json
20677
20677
  var package_default = {
20678
20678
  name: "opencode-swarm",
20679
- version: "7.127.1",
20679
+ version: "7.128.0",
20680
20680
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
20681
20681
  main: "dist/index.js",
20682
20682
  types: "dist/index.d.ts",
@@ -41238,7 +41238,7 @@ function buildDetailedHelp(commandName, entry) {
41238
41238
  async function handleHelpCommand(ctx) {
41239
41239
  const targetCommand = ctx.args.join(" ");
41240
41240
  if (!targetCommand) {
41241
- const { buildHelpText } = await import("./index-pbw1ncre.js");
41241
+ const { buildHelpText } = await import("./index-nmedh7bw.js");
41242
41242
  return buildHelpText();
41243
41243
  }
41244
41244
  const tokens = targetCommand.split(/\s+/);
@@ -41247,7 +41247,7 @@ async function handleHelpCommand(ctx) {
41247
41247
  return _internals63.buildDetailedHelp(resolved.key, resolved.entry);
41248
41248
  }
41249
41249
  const similar = _internals63.findSimilarCommands(targetCommand);
41250
- const { buildHelpText: fullHelp } = await import("./index-pbw1ncre.js");
41250
+ const { buildHelpText: fullHelp } = await import("./index-nmedh7bw.js");
41251
41251
  if (similar.length > 0) {
41252
41252
  return `Command '/swarm ${targetCommand}' not found.
41253
41253
 
@@ -41386,7 +41386,7 @@ var COMMAND_REGISTRY = {
41386
41386
  },
41387
41387
  "guardrail explain": {
41388
41388
  handler: async (ctx) => {
41389
- const { handleGuardrailExplain } = await import("./guardrail-explain-4yg67c3t.js");
41389
+ const { handleGuardrailExplain } = await import("./guardrail-explain-fwvxteqe.js");
41390
41390
  return handleGuardrailExplain(ctx.directory, ctx.args);
41391
41391
  },
41392
41392
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -41396,7 +41396,7 @@ var COMMAND_REGISTRY = {
41396
41396
  },
41397
41397
  "guardrail-explain": {
41398
41398
  handler: async (ctx) => {
41399
- const { handleGuardrailExplain } = await import("./guardrail-explain-4yg67c3t.js");
41399
+ const { handleGuardrailExplain } = await import("./guardrail-explain-fwvxteqe.js");
41400
41400
  return handleGuardrailExplain(ctx.directory, ctx.args);
41401
41401
  },
41402
41402
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -12,7 +12,7 @@ import {
12
12
  detectPosixWrites,
13
13
  detectWindowsWrites,
14
14
  resolveWriteTargets
15
- } from "./index-bn3w6ym4.js";
15
+ } from "./index-npycj2tr.js";
16
16
  import {
17
17
  checkFileAuthority,
18
18
  classifyFile,
package/dist/cli/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  getPluginLockFilePaths,
8
8
  package_default,
9
9
  resolveCommand
10
- } from "./index-bn3w6ym4.js";
10
+ } from "./index-npycj2tr.js";
11
11
  import"./index-v4n224r1.js";
12
12
  import"./index-cpssctv1.js";
13
13
  import"./index-kk1scggc.js";
@@ -21,8 +21,16 @@
21
21
  * Bounds (AGENTS.md invariants 3 and 8): the diff subprocess uses execFile
22
22
  * with cwd/timeout/maxBuffer and ignored stdin; dispatches are guarded by a
23
23
  * per-session in-flight set plus a 60s cooldown in a bounded FIFO map.
24
+ *
25
+ * #1896 / #1905: on a transient/quota dispatch error the reviewer fails over to
26
+ * a configured `fallback_models` entry via the shared `dispatchWithModelFallback`
27
+ * helper, instead of immediately writing a `verdict: 'error'` event (a quota
28
+ * blip previously dropped the review pass with no recovery). The SDK error
29
+ * envelope is preserved in the thrown message so the classifier sees the quota
30
+ * token on the dominant SDK error shape.
24
31
  */
25
32
  import { type AutoReviewConfig } from '../config/schema.js';
33
+ import { type ModelOverride } from '../utils/model-dispatch-fallback.js';
26
34
  /** Test-only: clear module-level dispatch tracking. */
27
35
  export declare function resetAutoReviewTracking(): void;
28
36
  export type ExecutionDiffResult = {
@@ -42,7 +50,7 @@ export type ExecutionDiffResult = {
42
50
  * `maxBytes`.
43
51
  */
44
52
  declare function computeExecutionDiff(directory: string, maxBytes: number): Promise<ExecutionDiffResult>;
45
- declare function dispatchReviewer(directory: string, prompt: string, agentName: string, timeoutMs: number, parentSessionId: string): Promise<string>;
53
+ declare function dispatchReviewer(directory: string, prompt: string, agentName: string, timeoutMs: number, parentSessionId: string, model?: ModelOverride): Promise<string>;
46
54
  export interface AutoReviewRunInput {
47
55
  directory: string;
48
56
  sessionID: string;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import{createRequire}from"node:module";var __create=Object.create;var{getPrototypeOf:__getProtoOf,defineProperty:__defProp,getOwnPropertyNames:__getOwnPropNames,getOwnPropertyDescriptor:__getOwnPropDesc}=Object,__hasOwnProp=Object.prototype.hasOwnProperty;function __accessProp(key){return this[key]}var __toESMCache_node,__toESMCache_esm,__toESM=(mod,isNodeMode,target)=>{var canCache=mod!=null&&typeof mod==="object";if(canCache){var cache=isNodeMode?__toESMCache_node??=new WeakMap:__toESMCache_esm??=new WeakMap,cached=cache.get(mod);if(cached)return cached}target=mod!=null?__create(__getProtoOf(mod)):{};let to=isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:!0}):target;for(let key of __getOwnPropNames(mod))if(!__hasOwnProp.call(to,key))__defProp(to,key,{get:__accessProp.bind(mod,key),enumerable:!0});if(canCache)cache.set(mod,to);return to},__toCommonJS=(from)=>{var entry=(__moduleCache??=new WeakMap).get(from),desc;if(entry)return entry;if(entry=__defProp({},"__esModule",{value:!0}),from&&typeof from==="object"||typeof from==="function"){for(var key of __getOwnPropNames(from))if(!__hasOwnProp.call(entry,key))__defProp(entry,key,{get:__accessProp.bind(from,key),enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return __moduleCache.set(from,entry),entry},__moduleCache,__commonJS=(cb,mod)=>()=>(mod||cb((mod={exports:{}}).exports,mod),mod.exports);var __returnValue=(v)=>v;function __exportSetter(name,newValue){this[name]=__returnValue.bind(null,newValue)}var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0,configurable:!0,set:__exportSetter.bind(all,name)})};var __esm=(fn2,res)=>()=>(fn2&&(res=fn2(fn2=0)),res);var __require=createRequire(import.meta.url);var package_default;var init_package=__esm(()=>{package_default={name:"opencode-swarm",version:"7.127.1",description:"Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",main:"dist/index.js",types:"dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",default:"./dist/index.js"},"./package.json":"./package.json"},bin:{"opencode-swarm":"./dist/cli/index.js"},type:"module",engines:{bun:">=1.3.13"},license:"MIT",repository:{type:"git",url:"https://github.com/ZaxbyHub/opencode-swarm.git"},publishConfig:{access:"public",registry:"https://registry.npmjs.org/"},keywords:["opencode","opencode-plugin","ai","agents","orchestration","swarm","multi-agent","llm"],files:["dist","dist/lang/grammars","binaries","evaluation-fixtures",".opencode/skills/brainstorm",".opencode/skills/specify",".opencode/skills/clarify-spec",".opencode/skills/resume",".opencode/skills/clarify",".opencode/skills/discover",".opencode/skills/consult",".opencode/skills/pre-phase-briefing",".opencode/skills/council",".opencode/skills/deep-dive",".opencode/skills/deep-research",".opencode/skills/codebase-review-swarm",".opencode/skills/swarm-implement",".opencode/skills/design-docs",".opencode/skills/swarm-pr-review",".opencode/skills/swarm",".opencode/skills/swarm-pr-feedback",".opencode/skills/swarm-pr-subscribe",".opencode/skills/swarm-ci-monitor",".opencode/skills/issue-ingest",".opencode/skills/plan",".opencode/skills/critic-gate",".opencode/skills/execute",".opencode/skills/phase-wrap",".opencode/skills/loop",".opencode/skills/writing-tests",".opencode/skills/running-tests",".opencode/skills/engineering-conventions",".opencode/skills/commit-pr",".opencode/skills/ci-failure-batching",".opencode/skills/gate-attribution",".opencode/skills/merge-queue-readiness",".opencode/skills/skill-edit-validation",".opencode/skills/worktree-retry-cleanup",".opencode/skills/test-file-split",".opencode/skills/fork-pr-operations",".opencode/skills/parallel-work-check",".opencode/skills/ci-fix-monitor",".opencode/skills/issue-tracer","tests/fixtures/memory-recall","README.md","LICENSE"],scripts:{clean:`bun -e "require('fs').rmSync('dist',{recursive:true,force:true})"`,build:"bun run clean && bun run scripts/copy-grammars.ts && bun build src/index.ts --outdir dist --target node --format esm --external web-tree-sitter --minify-whitespace --minify-syntax && bun build src/cli/index.ts --outdir dist/cli --target bun --format esm --external bash-parser --splitting && bun run scripts/copy-grammars.ts --to-dist && tsc --emitDeclarationOnly",typecheck:"tsc --noEmit",test:"bun test",lint:"biome lint .","lint:ci":"biome ci .","test:unit:ci":"bun scripts/ci/run-unit-tests-local.ts","drift:check":"bun run scripts/drift-check.ts","drift:fix":"bun run scripts/drift-check.ts --fix --confirm","skills:sync":"bun run scripts/sync-qa-gate-skills.ts",format:"biome format . --write",check:"biome check --write .",dev:"bun run build && opencode","package:smoke":"node scripts/package-smoke.mjs",prepare:"bun run build","repro:704":"node scripts/repro-704.mjs","repro:1144":"bun scripts/repro-1144.mjs","repro:1873":"bun build scripts/repro-1873-entry.ts --outdir dist-build-test/repro-1873 --target node --format esm && node scripts/repro-1873.mjs"},dependencies:{"@opencode-ai/plugin":"^1.18.3","@opencode-ai/sdk":"^1.18.3","@vscode/tree-sitter-wasm":"^0.3.0","bash-parser":"^0.5.0","p-limit":"^7.3.0",picomatch:"^4.0.4","proper-lockfile":"^4.1.2","quick-lru":"^7.3.0","web-tree-sitter":"^0.25.0",zod:"^4.1.8"},devDependencies:{"@biomejs/biome":"2.3.14","@types/picomatch":"^4.0.3","bun-types":"1.3.8","js-yaml":"^4.1.1",typescript:"^5.7.3"}}});var QA_AGENTS,PIPELINE_AGENTS,ORCHESTRATOR_NAME="architect",ALL_SUBAGENT_NAMES,ALL_AGENT_NAMES;var init_agent_names=__esm(()=>{QA_AGENTS=["reviewer","critic","critic_oversight"],PIPELINE_AGENTS=["explorer","coder","test_engineer"],ALL_SUBAGENT_NAMES=["sme","researcher","docs","docs_design","designer","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic_architecture_supervisor","curator_init","curator_phase","curator_postmortem","curator_consolidation","council_generalist","council_skeptic","council_domain_expert","skill_improver","spec_writer",...QA_AGENTS,...PIPELINE_AGENTS],ALL_AGENT_NAMES=["architect",...ALL_SUBAGENT_NAMES]});function getPrWorkflowToolCapability(toolName,mode){let metadata=TOOL_METADATA[toolName];if(!metadata?.prWorkflow?.modes.includes(mode))return null;return metadata.prWorkflow.capability}var TOOL_METADATA,TOOL_NAMES,TOOL_NAME_SET,TOOL_DESCRIPTIONS,AGENT_TOOL_MAP;var init_tool_metadata=__esm(()=>{init_agent_names();TOOL_METADATA={diff:{description:"structured git diff with contract change detection",agents:["architect","reviewer","critic_oversight","coder","test_engineer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},diff_summary:{description:"filter classified AST changes by category, risk level, or file for reviewer drill-down",agents:["architect","reviewer","critic_oversight"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},syntax_check:{description:"check syntax of source files using tree-sitter parsers across multiple languages, returning per-file errors",agents:["architect","coder","test_engineer"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},placeholder_scan:{description:"todo and FIXME comment detection",agents:["architect","reviewer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},imports:{description:"find all consumers that import from a given file — use before refactoring shared modules to avoid breaking unseen dependents",agents:["architect","sme","researcher","docs","docs_design","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","reviewer","critic","coder","test_engineer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},lint:{description:"run project linter in check or fix mode; supports biome, eslint, ruff, clippy, and more, returns structured results",agents:["architect","reviewer","coder"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},secretscan:{description:"scan for secrets (API keys, tokens, passwords) via regex and entropy; returns redacted previews, excludes common dirs",agents:["architect","reviewer","critic_oversight"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},sast_scan:{description:"static analysis security scan",agents:["architect","reviewer","critic_oversight"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},build_check:{description:"discover and run build, typecheck, and test commands for various project ecosystems in the working directory",agents:["architect","coder","test_engineer"]},pre_check_batch:{description:"parallel verification: lint:check + secretscan + sast_scan + quality_budget",agents:["architect","reviewer"]},quality_budget:{description:"code quality budget check",agents:["architect"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},symbols:{description:"extract exported symbols (functions, classes, interfaces, types) from source files; supports TypeScript, JavaScript, and Python",agents:["architect","sme","researcher","docs","docs_design","designer","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","spec_writer","reviewer","critic","coder","test_engineer"]},complexity_hotspots:{description:"git churn × complexity risk map",agents:["architect","sme","researcher","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","reviewer","critic","critic_oversight","explorer","test_engineer"]},schema_drift:{description:"OpenAPI spec vs route drift",agents:["architect","sme","researcher","docs","explorer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},todo_extract:{description:"structured TODO/FIXME extraction",agents:["architect","researcher","docs","explorer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},evidence_check:{description:"verify task evidence completeness",agents:["architect","critic_oversight"]},check_gate_status:{description:"check the gate status of a specific task",agents:["architect","critic_oversight"]},completion_verify:{description:"verify completed tasks have required evidence",agents:["architect","critic_oversight"]},complete_pr_workflow:{description:"validate terminal PR workflow evidence and clear its durable session gate",agents:["architect"]},abort_pr_workflow:{description:"abort an unrecoverable PR_REVIEW/PR_FEEDBACK mechanical gate and clear its durable session state",agents:["architect"]},prepare_pr_workflow_checkout:{description:"preserve explicit dirty tracked files before an unbound PR workflow checkout with an auditable recovery receipt",agents:["architect"]},run_pr_feedback_stage_a:{description:"execute and persist mandatory PR-feedback Stage A checks on a content-bound revision",agents:["architect"]},submit_council_verdicts:{description:"submit pre-collected council member verdicts for synthesis (architect MUST dispatch critic/reviewer/sme/test_engineer/explorer as Agent tasks first; this tool synthesizes only, it does not contact members)",agents:[]},submit_phase_council_verdicts:{description:"submit pre-collected phase-level council member verdicts for holistic phase synthesis (architect MUST dispatch all 5 council members with phase-scoped context first; this tool synthesizes only, it does not contact members)",agents:[]},declare_council_criteria:{description:"pre-declare acceptance criteria for a task before the coder starts work; criteria are read back during council evaluation",agents:[]},sbom_generate:{description:"SBOM generation for dependency inventory",agents:["architect"]},checkpoint:{description:"create named git checkpoints for save, restore, and delete — use before risky operations to enable rollback",agents:["architect"]},pkg_audit:{description:"dependency vulnerability scan — npm/pip/cargo",agents:["architect","critic_hallucination_verifier","reviewer","critic_oversight","test_engineer"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},parse_lane_candidates:{description:"Parse [CANDIDATE] rows from a dispatch_lanes or collect_lane_results artifact (by output_ref), produce structured records with provenance, optionally persist to a per-batch sidecar JSONL. Pure-parser variant exists as internal module.",agents:["architect"]},write_pr_review_trigger_eval:{description:"persist the complete PR-review trigger evaluation with exact-set validation, dispatch provenance, and live merge-base verification",agents:["architect"]},write_pr_review_artifact:{description:"persist schema-validated PR-review findings checkpoints and exact actionable feedback handoffs under the active run",agents:["architect"]},prepare_pr_feedback_scope:{description:"prepare an exact file scope for one PR-feedback coder Task after immutable feedback verification settles",agents:["architect"]},test_runner:{description:"auto-detect and run tests",agents:["architect","reviewer","test_engineer"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},test_impact:{description:"identify test files impacted by changed source files via import analysis",agents:["architect","reviewer","critic_oversight","test_engineer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},mutation_test:{description:"executes pre-generated mutation patches against tests, evaluates kill rate against quality gate thresholds",agents:["architect","test_engineer"]},generate_mutants:{description:"generate LLM-based mutation testing patches for source files; returns MutationPatch[] for direct consumption by the mutation_test tool",agents:["architect"]},detect_domains:{description:"detect which SME domains are relevant for a given text",agents:["architect","sme","docs","docs_design","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic","critic_oversight","explorer"]},git_blame:{description:"per-line git blame metadata: sha, author, date, summary for each line in a file",agents:["reviewer","explorer","architect"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},gitingest:{description:"fetch a GitHub repository full content via gitingest.com",agents:["architect","docs","explorer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},retrieve_summary:{description:"retrieve the full content of a stored tool output summary",agents:["architect","sme","docs","docs_design","designer","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic_architecture_supervisor","spec_writer","reviewer","critic","coder","test_engineer"]},retrieve_lane_output:{description:"retrieve paged full dispatch lane output by output_ref; use before consuming truncated lane previews or routing candidates from lane results",agents:["architect"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},extract_code_blocks:{description:"extract code blocks from text content and save them to files",agents:["docs","docs_design","designer","spec_writer","coder","test_engineer"]},phase_complete:{description:"mark a phase as complete and track dispatched agents",agents:["architect"]},save_plan:{description:"save a structured implementation plan",agents:["architect"]},update_task_status:{description:"mark tasks complete, track phase progress",agents:["architect"]},lint_spec:{description:"validate .swarm/spec.md format and required fields",agents:["architect","spec_writer"]},write_retro:{description:"document phase retrospectives via phase_complete workflow, capture lessons learned",agents:["architect"]},write_drift_evidence:{description:"write drift verification evidence for a completed phase",agents:["architect"]},write_hallucination_evidence:{description:"write hallucination verification evidence for a completed phase",agents:["architect"]},write_mutation_evidence:{description:"write mutation gate evidence for a completed phase; normalizes PASS/WARN/FAIL/SKIP verdicts and writes .swarm/evidence/{phase}/mutation-gate.json",agents:["architect"]},declare_scope:{description:"declare file scope for next coder delegation",agents:["architect"]},knowledge_query:{description:"query swarm or hive knowledge with optional filters",agents:["architect","skill_improver","spec_writer"]},doc_scan:{description:"scan project documentation files and build an index manifest",agents:["architect","docs_design","skill_improver","spec_writer","explorer"]},doc_extract:{description:"extract actionable constraints from project documentation",agents:["architect","docs_design","skill_improver","spec_writer"]},curator_analyze:{description:"run curator phase analysis and optionally apply knowledge recommendations",agents:["architect"]},knowledge_add:{description:"store a new lesson in the knowledge base",agents:["architect","coder"]},knowledge_recall:{description:"search the knowledge base for relevant past decisions",agents:["architect","sme","docs","docs_design","designer","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic_architecture_supervisor","curator_init","curator_phase","skill_improver","spec_writer","reviewer","critic","critic_oversight","explorer","coder","test_engineer"]},knowledge_remove:{description:"delete an outdated swarm knowledge entry by ID (swarm tier only)",agents:["architect"]},co_change_analyzer:{description:"detect hidden couplings by analyzing git history",agents:["architect"]},context_status:{description:"report current context-window headroom for the active session — returns tokens-used, model-limit, usage-percent, threshold-state (none/warn/critical), model name, and provider. Pure read-only: no state mutation, no warning injection. Works whether context_budget.enabled is true or false.",agents:["architect"]},search:{description:"Workspace-scoped ripgrep-style text search with structured JSON output. Supports literal and regex modes, glob filtering, and result limits. NOTE: This is text search, not structural AST search — use symbols and imports tools for structural queries.",agents:["architect","sme","docs","docs_design","designer","critic_hallucination_verifier","skill_improver","spec_writer","reviewer","critic_oversight","explorer","coder","test_engineer","researcher"]},ast_grep:{description:"Read-only structural AST search using ast-grep patterns with optional language and glob filters. Use for syntax-aware code pattern searches; does not rewrite files.",agents:["architect","sme","docs","docs_design","critic_hallucination_verifier","spec_writer","explorer","coder","test_engineer","researcher"]},actionlint_scan:{description:"Run actionlint against GitHub Actions workflow YAML files with structured findings. Resolves actionlint lazily and does not modify files.",agents:["architect","test_engineer"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},osv_scan:{description:"Run OSV-Scanner against a workspace path and return structured dependency vulnerability findings. Resolves osv-scanner lazily and does not modify files.",agents:["architect","test_engineer"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},gh_evidence:{description:"Fetch bounded GitHub pull request or issue metadata through gh for review and CI evidence. Resolves gh lazily and is read-only.",agents:["architect","researcher"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},batch_symbols:{description:"Batched symbol extraction across multiple files. Returns per-file symbol summaries with isolated error handling.",agents:["architect","critic_hallucination_verifier","reviewer","critic_oversight","explorer"]},suggest_patch:{description:"Reviewer-safe structured patch suggestion tool. Produces context-anchored patch artifacts without file modification. Returns structured diagnostics on context mismatch.",agents:["architect","reviewer"]},req_coverage:{description:"query requirement coverage status for tracked functional requirements",agents:["critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","spec_writer","critic","critic_oversight"]},get_approved_plan:{description:"retrieve the last critic-approved immutable plan snapshot for baseline drift comparison",agents:["critic_drift_verifier","critic","critic_oversight"]},repo_map:{description:"query the repo code graph: importers, dependencies, blast radius, localization, ontology facts, package boundaries, and heuristic preflight packets before refactoring; ontology findings are advisory, not formal proofs",agents:["architect","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic_architecture_supervisor","reviewer","critic","critic_oversight","explorer","coder"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},get_qa_gate_profile:{description:"retrieve the QA gate profile for the current plan: gates (reviewer, test_engineer, sme_enabled, critic_pre_plan, sast_enabled, council_mode, hallucination_guard, mutation_test, phase_council, drift_check, final_council), lock state, and profile hash. Read-only.",agents:["architect"]},set_qa_gates:{description:"configure the QA gate profile for the current plan. Architect-only. Ratchet-tighter only — rejected once the profile is locked after critic approval. Supports: reviewer, test_engineer, sme_enabled, critic_pre_plan, sast_enabled, council_mode, hallucination_guard, mutation_test, phase_council, drift_check, final_council.",agents:["architect"]},web_search:{description:"External web search (Tavily or Brave) for architect-driven council research, SME domain research, researcher auto-research, and skill-improver research. Returns titled results with snippets, URLs, normalized query metadata, temporal intent, freshness, and removed stale years. Config-gated on council.general.enabled in the resolved config: global ~/.config/opencode/opencode-swarm.json, then project .opencode/opencode-swarm.json overrides. Requires a search API key. Used by the architect in MODE: COUNCIL to gather a RESEARCH CONTEXT before dispatching council agents, by SME for opt-in external skill/source evaluation, and by the researcher agent for multi-source auto-research.",agents:["sme","researcher","skill_improver"]},web_fetch:{description:"Fetch the readable text of a single http(s) URL (architect-only). Returns decoded page text, document title, final URL after redirects, and an evidence reference. Reads primary sources that web_search only surfaces as snippets. Config-gated on council.general.enabled. Blocks private/loopback/link-local/metadata addresses (re-validated and re-pinned across redirects); enforces timeout and body size cap.",agents:[]},convene_general_council:{description:"Synthesize responses from a multi-model General Council. Accepts parallel member responses (Round 1, optionally Round 2), detects disagreements, and returns consensus points, persisting disagreements, and a structured synthesis. Architect-only. Config-gated on council.general.enabled in the resolved config: global ~/.config/opencode/opencode-swarm.json, then project .opencode/opencode-swarm.json overrides.",agents:[]},write_final_council_evidence:{description:"Persist project-scoped final council evidence to .swarm/evidence/final-council.json. PREREQUISITE: dispatch critic, reviewer, sme, test_engineer, and explorer as project-scoped Agent tasks and collect their CouncilMemberVerdict JSON — this tool synthesizes only. Rejects on insufficient quorum or CONCERNS with unresolved requiredFixes; normalizes verdicts to approved/concerns/rejected. Architect-only.",agents:[]},skill_generate:{description:"compile knowledge entries into a structured SKILL.md draft",agents:["skill_improver"]},skill_list:{description:"list generated skill files and their status",agents:["skill_improver"]},skill_apply:{description:"activate a draft skill proposal",agents:[]},skill_inspect:{description:"inspect the content and source entries of a skill file",agents:["skill_improver"]},run_stale_reconciliation:{description:"reconcile skills against the knowledge store: mark skills stale when source knowledge is archived or deleted, or clear stale markers",agents:["architect"]},skill_regenerate:{description:"regenerate an active skill by re-clustering its source knowledge entries and updating the SKILL.md in place",agents:[]},skill_retire:{description:"retire a generated skill by adding a retired.marker file; retired skills are excluded from scoring and injection",agents:[]},skill_improve:{description:"run the skill_improver agent to review and refine skills",agents:["skill_improver"]},spec_write:{description:"author or update .swarm/spec.md for the current project",agents:["spec_writer"]},knowledge_receipt:{description:"file a receipt for retrieved knowledge (applied/ignored/contradicted + new lessons), recorded as immutable knowledge events",agents:["architect","sme","docs","docs_design","designer","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic_architecture_supervisor","curator_init","curator_phase","skill_improver","spec_writer","reviewer","critic","coder","test_engineer"]},knowledge_archive:{description:"archive (default), quarantine, or purge a swarm or hive knowledge entry by ID with an immutable audit tombstone; purge requires an admin flag",agents:["architect"]},swarm_memory_recall:{description:"recall scoped Swarm memory for the current repository as untrusted background",agents:[]},swarm_memory_propose:{description:"create a pending Swarm memory proposal; does not write durable memory directly",agents:[]},swarm_command:{description:"run supported /swarm commands through the canonical command registry",agents:["architect","sme","researcher","docs","docs_design","designer","reviewer","critic","explorer","coder","test_engineer"]},dispatch_lanes:{description:"dispatch read-only exploration/review lanes concurrently and BLOCK until all finish; prefer dispatch_lanes_async for non-blocking dispatch, use this only when promptAsync is unavailable",agents:["architect"]},dispatch_lanes_async:{description:"launch read-only advisory lanes non-blockingly and return a batch id plus lane session handles immediately so you can keep working; launch_timeout_ms is only a promptAsync acceptance budget, not a lane runtime timeout; poll incrementally with collect_lane_results (wait omitted or false) while doing independent investigation, or join with wait: true when you need all results",agents:["architect"]},collect_lane_results:{description:"collect or poll results for a dispatch_lanes_async batch; supports both non-blocking polling (wait omitted or false) and blocking join (wait: true). Non-blocking polls include pending lane identities by default and process settled lanes incrementally while continuing independent work; busy/retry lanes are not timed out just because they run for a long time. Does not advance workflow gates.",agents:["architect"]},summarize_work:{description:"emit a short structured summary of completed work (key decisions, assumptions, risks, constraints) at task completion; rolls up per phase for architecture-supervisor review. Advisory, never blocks.",agents:["architect","sme","researcher","docs","docs_design","designer","explorer","coder","test_engineer"]},write_architecture_supervisor_evidence:{description:"persist the architecture supervisor verdict for a phase (architect MUST dispatch critic_architecture_supervisor first and collect its JSON verdict; this tool persists only, it does not contact the supervisor)",agents:["architect"]},lean_turbo_plan_lanes:{description:"partition phase tasks into parallel lanes based on file-scope conflicts for Lean Turbo execution",agents:[]},lean_turbo_acquire_locks:{description:"acquire file locks for all files in a lane (all-or-nothing) before lane execution",agents:[]},lean_turbo_runner_status:{description:"read Lean Turbo run state from .swarm/turbo-state.json",agents:[]},lean_turbo_review:{description:"dispatch a read-only reviewer agent to evaluate a completed Lean Turbo phase",agents:[]},lean_turbo_run_phase:{description:"Execute a phase using Lean Turbo parallel lane execution. Plans lanes, acquires file locks, and dispatches coder agents concurrently. Use when Lean Turbo is active and you want to execute all tasks in a phase in parallel lanes.",agents:[]},lean_turbo_status:{description:"returns Lean Turbo configuration and active status for the current session",agents:[]},swarm_apply_patch:{description:"Apply a unified diff patch to workspace files with exact context matching, atomic writes, and path validation. Use standard unified diff format only — does NOT support *** Begin Patch / *** Update File payloads (use native apply_patch for those).",agents:["coder","test_engineer"]},external_skill_discover:{description:"Discover external skill candidates from configured sources. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},external_skill_list:{description:"List external skill candidates in the quarantine store. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},external_skill_inspect:{description:"Inspect a specific external skill candidate by ID. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},external_skill_promote:{description:"Promote a validated external skill candidate to an active generated skill. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},external_skill_reject:{description:"Reject an external skill candidate after evaluation. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},external_skill_delete:{description:"Delete an external skill candidate from the quarantine store. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},external_skill_revoke:{description:"Revoke a previously promoted external skill. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},epic_decide_phase:{description:"Compute the Epic Mode verdict for a phase WITHOUT dispatching coders. Runs preflight + calibration + the three gates (p-threshold, hot-module, greenfield), persists the decision, and returns the verdict so the architect can dispatch waves via the visible Task tool (promote) or fall back to per-task serial (demote). Pair with `epic_plan_waves` to get the wave plan when promoted. Use when /swarm epic is on for the session.",agents:["architect"]},epic_plan_waves:{description:"Partition a phase's pending tasks into ordered concurrent waves for Epic Mode dispatch. A wave is a set of tasks with mutually disjoint declared scopes and all dependencies satisfied by prior waves. Returns `{ waves: [{ waveId, taskIds, files }, ...], serializedTasks, degradedTasks }`. "+'For each wave in order, the architect dispatches one `Task(subagent_type="coder", ...)` per `taskId` — all in one assistant message — so the wave runs concurrently and each coder appears as a visible subagent. '+"Wait for the wave to finish before dispatching the next. Pair with `epic_decide_phase` (called first; this tool is only relevant on a `promote` verdict). "+"Preflight reject reasons: `no-plan`, `no-phase`, `phase-empty`, `phase-already-complete`, `scopes-missing` (call `declare_scope` for `missingScopes`), `git-failed` (transient — retry), `planner-error`.",agents:["architect"]},epic_record_divergence:{description:"After every `update_task_status(completed)`, record the task's declared-vs-actual divergence to .swarm/epic/divergence.jsonl. Feeds Epic Mode's self-calibration loop (Capability D). Best-effort: never blocks.",agents:["architect"]}},TOOL_NAMES=Object.keys(TOOL_METADATA),TOOL_NAME_SET=new Set(TOOL_NAMES);TOOL_DESCRIPTIONS=Object.fromEntries(Object.entries(TOOL_METADATA).map(([name,meta])=>[name,meta.description])),AGENT_TOOL_MAP=(()=>{let map=Object.fromEntries(ALL_AGENT_NAMES.map((agent)=>[agent,[]]));for(let[name,meta]of Object.entries(TOOL_METADATA))for(let agent of meta.agents)map[agent].push(name);return map})()});function deepMergeInternal(base,override,depth){if(depth>=10)throw Error("deepMerge exceeded maximum depth of 10");let result={...base};for(let key of Object.keys(override)){let baseVal=base[key],overrideVal=override[key];if(typeof baseVal==="object"&&baseVal!==null&&typeof overrideVal==="object"&&overrideVal!==null&&!Array.isArray(baseVal)&&!Array.isArray(overrideVal))result[key]=deepMergeInternal(baseVal,overrideVal,depth+1);else result[key]=overrideVal}return result}function deepMerge(base,override){if(!base)return override;if(!override)return base;return deepMergeInternal(base,override,0)}var MAX_MERGE_DEPTH=10;function freezeSet(items){let set=new Set(items),proxy=new Proxy(set,{get(target,prop){if(prop==="add"||prop==="delete"||prop==="clear")return()=>{throw TypeError("CLAUDE_CODE_NATIVE_COMMANDS is readonly")};if(prop==="forEach")return(callback,thisArg)=>{let wrapped=(v,k)=>callback.call(thisArg??void 0,v,k,proxy);return set.forEach(wrapped)};let value=Reflect.get(target,prop);return typeof value==="function"?value.bind(target):value},set(){throw TypeError("CLAUDE_CODE_NATIVE_COMMANDS is readonly")},deleteProperty(){throw TypeError("CLAUDE_CODE_NATIVE_COMMANDS is readonly")},defineProperty(){throw TypeError("CLAUDE_CODE_NATIVE_COMMANDS is readonly")},setPrototypeOf(){throw TypeError("CLAUDE_CODE_NATIVE_COMMANDS is readonly")}});return proxy}function isQAAgent(name){return QA_AGENTS.includes(name)}function isSubagent(name){return ALL_SUBAGENT_NAMES.includes(name)}function isLowCapabilityModel(modelId){let lower=(modelId||"").toLowerCase();return LOW_CAPABILITY_MODELS.some((substr)=>lower.includes(substr))}var OPENCODE_NATIVE_AGENTS,CLAUDE_CODE_NATIVE_COMMANDS,MEMORY_AGENT_TOOL_MAP,EXTERNAL_SKILL_TOOL_NAMES,EXTERNAL_SKILL_AGENT_TOOL_MAP,COUNCIL_TOOL_NAMES,COUNCIL_AGENT_TOOL_MAP,GENERAL_COUNCIL_TOOL_NAMES,GENERAL_COUNCIL_AGENT_TOOL_MAP,TURBO_TOOL_NAMES,TURBO_AGENT_TOOL_MAP,SKILL_TOOL_NAMES,SKILL_AGENT_TOOL_MAP,WRITE_TOOL_NAMES,DEFAULT_MODELS,DEFAULT_SCORING_CONFIG,LOW_CAPABILITY_MODELS,TURBO_MODE_BANNER=`## \uD83D\uDE80 TURBO MODE ACTIVE
1
+ import{createRequire}from"node:module";var __create=Object.create;var{getPrototypeOf:__getProtoOf,defineProperty:__defProp,getOwnPropertyNames:__getOwnPropNames,getOwnPropertyDescriptor:__getOwnPropDesc}=Object,__hasOwnProp=Object.prototype.hasOwnProperty;function __accessProp(key){return this[key]}var __toESMCache_node,__toESMCache_esm,__toESM=(mod,isNodeMode,target)=>{var canCache=mod!=null&&typeof mod==="object";if(canCache){var cache=isNodeMode?__toESMCache_node??=new WeakMap:__toESMCache_esm??=new WeakMap,cached=cache.get(mod);if(cached)return cached}target=mod!=null?__create(__getProtoOf(mod)):{};let to=isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:!0}):target;for(let key of __getOwnPropNames(mod))if(!__hasOwnProp.call(to,key))__defProp(to,key,{get:__accessProp.bind(mod,key),enumerable:!0});if(canCache)cache.set(mod,to);return to},__toCommonJS=(from)=>{var entry=(__moduleCache??=new WeakMap).get(from),desc;if(entry)return entry;if(entry=__defProp({},"__esModule",{value:!0}),from&&typeof from==="object"||typeof from==="function"){for(var key of __getOwnPropNames(from))if(!__hasOwnProp.call(entry,key))__defProp(entry,key,{get:__accessProp.bind(from,key),enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return __moduleCache.set(from,entry),entry},__moduleCache,__commonJS=(cb,mod)=>()=>(mod||cb((mod={exports:{}}).exports,mod),mod.exports);var __returnValue=(v)=>v;function __exportSetter(name,newValue){this[name]=__returnValue.bind(null,newValue)}var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0,configurable:!0,set:__exportSetter.bind(all,name)})};var __esm=(fn2,res)=>()=>(fn2&&(res=fn2(fn2=0)),res);var __require=createRequire(import.meta.url);var package_default;var init_package=__esm(()=>{package_default={name:"opencode-swarm",version:"7.128.0",description:"Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",main:"dist/index.js",types:"dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",default:"./dist/index.js"},"./package.json":"./package.json"},bin:{"opencode-swarm":"./dist/cli/index.js"},type:"module",engines:{bun:">=1.3.13"},license:"MIT",repository:{type:"git",url:"https://github.com/ZaxbyHub/opencode-swarm.git"},publishConfig:{access:"public",registry:"https://registry.npmjs.org/"},keywords:["opencode","opencode-plugin","ai","agents","orchestration","swarm","multi-agent","llm"],files:["dist","dist/lang/grammars","binaries","evaluation-fixtures",".opencode/skills/brainstorm",".opencode/skills/specify",".opencode/skills/clarify-spec",".opencode/skills/resume",".opencode/skills/clarify",".opencode/skills/discover",".opencode/skills/consult",".opencode/skills/pre-phase-briefing",".opencode/skills/council",".opencode/skills/deep-dive",".opencode/skills/deep-research",".opencode/skills/codebase-review-swarm",".opencode/skills/swarm-implement",".opencode/skills/design-docs",".opencode/skills/swarm-pr-review",".opencode/skills/swarm",".opencode/skills/swarm-pr-feedback",".opencode/skills/swarm-pr-subscribe",".opencode/skills/swarm-ci-monitor",".opencode/skills/issue-ingest",".opencode/skills/plan",".opencode/skills/critic-gate",".opencode/skills/execute",".opencode/skills/phase-wrap",".opencode/skills/loop",".opencode/skills/writing-tests",".opencode/skills/running-tests",".opencode/skills/engineering-conventions",".opencode/skills/commit-pr",".opencode/skills/ci-failure-batching",".opencode/skills/gate-attribution",".opencode/skills/merge-queue-readiness",".opencode/skills/skill-edit-validation",".opencode/skills/worktree-retry-cleanup",".opencode/skills/test-file-split",".opencode/skills/fork-pr-operations",".opencode/skills/parallel-work-check",".opencode/skills/ci-fix-monitor",".opencode/skills/issue-tracer","tests/fixtures/memory-recall","README.md","LICENSE"],scripts:{clean:`bun -e "require('fs').rmSync('dist',{recursive:true,force:true})"`,build:"bun run clean && bun run scripts/copy-grammars.ts && bun build src/index.ts --outdir dist --target node --format esm --external web-tree-sitter --minify-whitespace --minify-syntax && bun build src/cli/index.ts --outdir dist/cli --target bun --format esm --external bash-parser --splitting && bun run scripts/copy-grammars.ts --to-dist && tsc --emitDeclarationOnly",typecheck:"tsc --noEmit",test:"bun test",lint:"biome lint .","lint:ci":"biome ci .","test:unit:ci":"bun scripts/ci/run-unit-tests-local.ts","drift:check":"bun run scripts/drift-check.ts","drift:fix":"bun run scripts/drift-check.ts --fix --confirm","skills:sync":"bun run scripts/sync-qa-gate-skills.ts",format:"biome format . --write",check:"biome check --write .",dev:"bun run build && opencode","package:smoke":"node scripts/package-smoke.mjs",prepare:"bun run build","repro:704":"node scripts/repro-704.mjs","repro:1144":"bun scripts/repro-1144.mjs","repro:1873":"bun build scripts/repro-1873-entry.ts --outdir dist-build-test/repro-1873 --target node --format esm && node scripts/repro-1873.mjs"},dependencies:{"@opencode-ai/plugin":"^1.18.3","@opencode-ai/sdk":"^1.18.3","@vscode/tree-sitter-wasm":"^0.3.0","bash-parser":"^0.5.0","p-limit":"^7.3.0",picomatch:"^4.0.4","proper-lockfile":"^4.1.2","quick-lru":"^7.3.0","web-tree-sitter":"^0.25.0",zod:"^4.1.8"},devDependencies:{"@biomejs/biome":"2.3.14","@types/picomatch":"^4.0.3","bun-types":"1.3.8","js-yaml":"^4.1.1",typescript:"^5.7.3"}}});var QA_AGENTS,PIPELINE_AGENTS,ORCHESTRATOR_NAME="architect",ALL_SUBAGENT_NAMES,ALL_AGENT_NAMES;var init_agent_names=__esm(()=>{QA_AGENTS=["reviewer","critic","critic_oversight"],PIPELINE_AGENTS=["explorer","coder","test_engineer"],ALL_SUBAGENT_NAMES=["sme","researcher","docs","docs_design","designer","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic_architecture_supervisor","curator_init","curator_phase","curator_postmortem","curator_consolidation","council_generalist","council_skeptic","council_domain_expert","skill_improver","spec_writer",...QA_AGENTS,...PIPELINE_AGENTS],ALL_AGENT_NAMES=["architect",...ALL_SUBAGENT_NAMES]});function getPrWorkflowToolCapability(toolName,mode){let metadata=TOOL_METADATA[toolName];if(!metadata?.prWorkflow?.modes.includes(mode))return null;return metadata.prWorkflow.capability}var TOOL_METADATA,TOOL_NAMES,TOOL_NAME_SET,TOOL_DESCRIPTIONS,AGENT_TOOL_MAP;var init_tool_metadata=__esm(()=>{init_agent_names();TOOL_METADATA={diff:{description:"structured git diff with contract change detection",agents:["architect","reviewer","critic_oversight","coder","test_engineer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},diff_summary:{description:"filter classified AST changes by category, risk level, or file for reviewer drill-down",agents:["architect","reviewer","critic_oversight"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},syntax_check:{description:"check syntax of source files using tree-sitter parsers across multiple languages, returning per-file errors",agents:["architect","coder","test_engineer"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},placeholder_scan:{description:"todo and FIXME comment detection",agents:["architect","reviewer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},imports:{description:"find all consumers that import from a given file — use before refactoring shared modules to avoid breaking unseen dependents",agents:["architect","sme","researcher","docs","docs_design","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","reviewer","critic","coder","test_engineer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},lint:{description:"run project linter in check or fix mode; supports biome, eslint, ruff, clippy, and more, returns structured results",agents:["architect","reviewer","coder"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},secretscan:{description:"scan for secrets (API keys, tokens, passwords) via regex and entropy; returns redacted previews, excludes common dirs",agents:["architect","reviewer","critic_oversight"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},sast_scan:{description:"static analysis security scan",agents:["architect","reviewer","critic_oversight"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},build_check:{description:"discover and run build, typecheck, and test commands for various project ecosystems in the working directory",agents:["architect","coder","test_engineer"]},pre_check_batch:{description:"parallel verification: lint:check + secretscan + sast_scan + quality_budget",agents:["architect","reviewer"]},quality_budget:{description:"code quality budget check",agents:["architect"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},symbols:{description:"extract exported symbols (functions, classes, interfaces, types) from source files; supports TypeScript, JavaScript, and Python",agents:["architect","sme","researcher","docs","docs_design","designer","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","spec_writer","reviewer","critic","coder","test_engineer"]},complexity_hotspots:{description:"git churn × complexity risk map",agents:["architect","sme","researcher","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","reviewer","critic","critic_oversight","explorer","test_engineer"]},schema_drift:{description:"OpenAPI spec vs route drift",agents:["architect","sme","researcher","docs","explorer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},todo_extract:{description:"structured TODO/FIXME extraction",agents:["architect","researcher","docs","explorer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},evidence_check:{description:"verify task evidence completeness",agents:["architect","critic_oversight"]},check_gate_status:{description:"check the gate status of a specific task",agents:["architect","critic_oversight"]},completion_verify:{description:"verify completed tasks have required evidence",agents:["architect","critic_oversight"]},complete_pr_workflow:{description:"validate terminal PR workflow evidence and clear its durable session gate",agents:["architect"]},abort_pr_workflow:{description:"abort an unrecoverable PR_REVIEW/PR_FEEDBACK mechanical gate and clear its durable session state",agents:["architect"]},prepare_pr_workflow_checkout:{description:"preserve explicit dirty tracked files before an unbound PR workflow checkout with an auditable recovery receipt",agents:["architect"]},run_pr_feedback_stage_a:{description:"execute and persist mandatory PR-feedback Stage A checks on a content-bound revision",agents:["architect"]},submit_council_verdicts:{description:"submit pre-collected council member verdicts for synthesis (architect MUST dispatch critic/reviewer/sme/test_engineer/explorer as Agent tasks first; this tool synthesizes only, it does not contact members)",agents:[]},submit_phase_council_verdicts:{description:"submit pre-collected phase-level council member verdicts for holistic phase synthesis (architect MUST dispatch all 5 council members with phase-scoped context first; this tool synthesizes only, it does not contact members)",agents:[]},declare_council_criteria:{description:"pre-declare acceptance criteria for a task before the coder starts work; criteria are read back during council evaluation",agents:[]},sbom_generate:{description:"SBOM generation for dependency inventory",agents:["architect"]},checkpoint:{description:"create named git checkpoints for save, restore, and delete — use before risky operations to enable rollback",agents:["architect"]},pkg_audit:{description:"dependency vulnerability scan — npm/pip/cargo",agents:["architect","critic_hallucination_verifier","reviewer","critic_oversight","test_engineer"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},parse_lane_candidates:{description:"Parse [CANDIDATE] rows from a dispatch_lanes or collect_lane_results artifact (by output_ref), produce structured records with provenance, optionally persist to a per-batch sidecar JSONL. Pure-parser variant exists as internal module.",agents:["architect"]},write_pr_review_trigger_eval:{description:"persist the complete PR-review trigger evaluation with exact-set validation, dispatch provenance, and live merge-base verification",agents:["architect"]},write_pr_review_artifact:{description:"persist schema-validated PR-review findings checkpoints and exact actionable feedback handoffs under the active run",agents:["architect"]},prepare_pr_feedback_scope:{description:"prepare an exact file scope for one PR-feedback coder Task after immutable feedback verification settles",agents:["architect"]},test_runner:{description:"auto-detect and run tests",agents:["architect","reviewer","test_engineer"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},test_impact:{description:"identify test files impacted by changed source files via import analysis",agents:["architect","reviewer","critic_oversight","test_engineer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},mutation_test:{description:"executes pre-generated mutation patches against tests, evaluates kill rate against quality gate thresholds",agents:["architect","test_engineer"]},generate_mutants:{description:"generate LLM-based mutation testing patches for source files; returns MutationPatch[] for direct consumption by the mutation_test tool",agents:["architect"]},detect_domains:{description:"detect which SME domains are relevant for a given text",agents:["architect","sme","docs","docs_design","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic","critic_oversight","explorer"]},git_blame:{description:"per-line git blame metadata: sha, author, date, summary for each line in a file",agents:["reviewer","explorer","architect"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},gitingest:{description:"fetch a GitHub repository full content via gitingest.com",agents:["architect","docs","explorer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},retrieve_summary:{description:"retrieve the full content of a stored tool output summary",agents:["architect","sme","docs","docs_design","designer","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic_architecture_supervisor","spec_writer","reviewer","critic","coder","test_engineer"]},retrieve_lane_output:{description:"retrieve paged full dispatch lane output by output_ref; use before consuming truncated lane previews or routing candidates from lane results",agents:["architect"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},extract_code_blocks:{description:"extract code blocks from text content and save them to files",agents:["docs","docs_design","designer","spec_writer","coder","test_engineer"]},phase_complete:{description:"mark a phase as complete and track dispatched agents",agents:["architect"]},save_plan:{description:"save a structured implementation plan",agents:["architect"]},update_task_status:{description:"mark tasks complete, track phase progress",agents:["architect"]},lint_spec:{description:"validate .swarm/spec.md format and required fields",agents:["architect","spec_writer"]},write_retro:{description:"document phase retrospectives via phase_complete workflow, capture lessons learned",agents:["architect"]},write_drift_evidence:{description:"write drift verification evidence for a completed phase",agents:["architect"]},write_hallucination_evidence:{description:"write hallucination verification evidence for a completed phase",agents:["architect"]},write_mutation_evidence:{description:"write mutation gate evidence for a completed phase; normalizes PASS/WARN/FAIL/SKIP verdicts and writes .swarm/evidence/{phase}/mutation-gate.json",agents:["architect"]},declare_scope:{description:"declare file scope for next coder delegation",agents:["architect"]},knowledge_query:{description:"query swarm or hive knowledge with optional filters",agents:["architect","skill_improver","spec_writer"]},doc_scan:{description:"scan project documentation files and build an index manifest",agents:["architect","docs_design","skill_improver","spec_writer","explorer"]},doc_extract:{description:"extract actionable constraints from project documentation",agents:["architect","docs_design","skill_improver","spec_writer"]},curator_analyze:{description:"run curator phase analysis and optionally apply knowledge recommendations",agents:["architect"]},knowledge_add:{description:"store a new lesson in the knowledge base",agents:["architect","coder"]},knowledge_recall:{description:"search the knowledge base for relevant past decisions",agents:["architect","sme","docs","docs_design","designer","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic_architecture_supervisor","curator_init","curator_phase","skill_improver","spec_writer","reviewer","critic","critic_oversight","explorer","coder","test_engineer"]},knowledge_remove:{description:"delete an outdated swarm knowledge entry by ID (swarm tier only)",agents:["architect"]},co_change_analyzer:{description:"detect hidden couplings by analyzing git history",agents:["architect"]},context_status:{description:"report current context-window headroom for the active session — returns tokens-used, model-limit, usage-percent, threshold-state (none/warn/critical), model name, and provider. Pure read-only: no state mutation, no warning injection. Works whether context_budget.enabled is true or false.",agents:["architect"]},search:{description:"Workspace-scoped ripgrep-style text search with structured JSON output. Supports literal and regex modes, glob filtering, and result limits. NOTE: This is text search, not structural AST search — use symbols and imports tools for structural queries.",agents:["architect","sme","docs","docs_design","designer","critic_hallucination_verifier","skill_improver","spec_writer","reviewer","critic_oversight","explorer","coder","test_engineer","researcher"]},ast_grep:{description:"Read-only structural AST search using ast-grep patterns with optional language and glob filters. Use for syntax-aware code pattern searches; does not rewrite files.",agents:["architect","sme","docs","docs_design","critic_hallucination_verifier","spec_writer","explorer","coder","test_engineer","researcher"]},actionlint_scan:{description:"Run actionlint against GitHub Actions workflow YAML files with structured findings. Resolves actionlint lazily and does not modify files.",agents:["architect","test_engineer"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},osv_scan:{description:"Run OSV-Scanner against a workspace path and return structured dependency vulnerability findings. Resolves osv-scanner lazily and does not modify files.",agents:["architect","test_engineer"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},gh_evidence:{description:"Fetch bounded GitHub pull request or issue metadata through gh for review and CI evidence. Resolves gh lazily and is read-only.",agents:["architect","researcher"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},batch_symbols:{description:"Batched symbol extraction across multiple files. Returns per-file symbol summaries with isolated error handling.",agents:["architect","critic_hallucination_verifier","reviewer","critic_oversight","explorer"]},suggest_patch:{description:"Reviewer-safe structured patch suggestion tool. Produces context-anchored patch artifacts without file modification. Returns structured diagnostics on context mismatch.",agents:["architect","reviewer"]},req_coverage:{description:"query requirement coverage status for tracked functional requirements",agents:["critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","spec_writer","critic","critic_oversight"]},get_approved_plan:{description:"retrieve the last critic-approved immutable plan snapshot for baseline drift comparison",agents:["critic_drift_verifier","critic","critic_oversight"]},repo_map:{description:"query the repo code graph: importers, dependencies, blast radius, localization, ontology facts, package boundaries, and heuristic preflight packets before refactoring; ontology findings are advisory, not formal proofs",agents:["architect","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic_architecture_supervisor","reviewer","critic","critic_oversight","explorer","coder"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},get_qa_gate_profile:{description:"retrieve the QA gate profile for the current plan: gates (reviewer, test_engineer, sme_enabled, critic_pre_plan, sast_enabled, council_mode, hallucination_guard, mutation_test, phase_council, drift_check, final_council), lock state, and profile hash. Read-only.",agents:["architect"]},set_qa_gates:{description:"configure the QA gate profile for the current plan. Architect-only. Ratchet-tighter only — rejected once the profile is locked after critic approval. Supports: reviewer, test_engineer, sme_enabled, critic_pre_plan, sast_enabled, council_mode, hallucination_guard, mutation_test, phase_council, drift_check, final_council.",agents:["architect"]},web_search:{description:"External web search (Tavily or Brave) for architect-driven council research, SME domain research, researcher auto-research, and skill-improver research. Returns titled results with snippets, URLs, normalized query metadata, temporal intent, freshness, and removed stale years. Config-gated on council.general.enabled in the resolved config: global ~/.config/opencode/opencode-swarm.json, then project .opencode/opencode-swarm.json overrides. Requires a search API key. Used by the architect in MODE: COUNCIL to gather a RESEARCH CONTEXT before dispatching council agents, by SME for opt-in external skill/source evaluation, and by the researcher agent for multi-source auto-research.",agents:["sme","researcher","skill_improver"]},web_fetch:{description:"Fetch the readable text of a single http(s) URL (architect-only). Returns decoded page text, document title, final URL after redirects, and an evidence reference. Reads primary sources that web_search only surfaces as snippets. Config-gated on council.general.enabled. Blocks private/loopback/link-local/metadata addresses (re-validated and re-pinned across redirects); enforces timeout and body size cap.",agents:[]},convene_general_council:{description:"Synthesize responses from a multi-model General Council. Accepts parallel member responses (Round 1, optionally Round 2), detects disagreements, and returns consensus points, persisting disagreements, and a structured synthesis. Architect-only. Config-gated on council.general.enabled in the resolved config: global ~/.config/opencode/opencode-swarm.json, then project .opencode/opencode-swarm.json overrides.",agents:[]},write_final_council_evidence:{description:"Persist project-scoped final council evidence to .swarm/evidence/final-council.json. PREREQUISITE: dispatch critic, reviewer, sme, test_engineer, and explorer as project-scoped Agent tasks and collect their CouncilMemberVerdict JSON — this tool synthesizes only. Rejects on insufficient quorum or CONCERNS with unresolved requiredFixes; normalizes verdicts to approved/concerns/rejected. Architect-only.",agents:[]},skill_generate:{description:"compile knowledge entries into a structured SKILL.md draft",agents:["skill_improver"]},skill_list:{description:"list generated skill files and their status",agents:["skill_improver"]},skill_apply:{description:"activate a draft skill proposal",agents:[]},skill_inspect:{description:"inspect the content and source entries of a skill file",agents:["skill_improver"]},run_stale_reconciliation:{description:"reconcile skills against the knowledge store: mark skills stale when source knowledge is archived or deleted, or clear stale markers",agents:["architect"]},skill_regenerate:{description:"regenerate an active skill by re-clustering its source knowledge entries and updating the SKILL.md in place",agents:[]},skill_retire:{description:"retire a generated skill by adding a retired.marker file; retired skills are excluded from scoring and injection",agents:[]},skill_improve:{description:"run the skill_improver agent to review and refine skills",agents:["skill_improver"]},spec_write:{description:"author or update .swarm/spec.md for the current project",agents:["spec_writer"]},knowledge_receipt:{description:"file a receipt for retrieved knowledge (applied/ignored/contradicted + new lessons), recorded as immutable knowledge events",agents:["architect","sme","docs","docs_design","designer","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic_architecture_supervisor","curator_init","curator_phase","skill_improver","spec_writer","reviewer","critic","coder","test_engineer"]},knowledge_archive:{description:"archive (default), quarantine, or purge a swarm or hive knowledge entry by ID with an immutable audit tombstone; purge requires an admin flag",agents:["architect"]},swarm_memory_recall:{description:"recall scoped Swarm memory for the current repository as untrusted background",agents:[]},swarm_memory_propose:{description:"create a pending Swarm memory proposal; does not write durable memory directly",agents:[]},swarm_command:{description:"run supported /swarm commands through the canonical command registry",agents:["architect","sme","researcher","docs","docs_design","designer","reviewer","critic","explorer","coder","test_engineer"]},dispatch_lanes:{description:"dispatch read-only exploration/review lanes concurrently and BLOCK until all finish; prefer dispatch_lanes_async for non-blocking dispatch, use this only when promptAsync is unavailable",agents:["architect"]},dispatch_lanes_async:{description:"launch read-only advisory lanes non-blockingly and return a batch id plus lane session handles immediately so you can keep working; launch_timeout_ms is only a promptAsync acceptance budget, not a lane runtime timeout; poll incrementally with collect_lane_results (wait omitted or false) while doing independent investigation, or join with wait: true when you need all results",agents:["architect"]},collect_lane_results:{description:"collect or poll results for a dispatch_lanes_async batch; supports both non-blocking polling (wait omitted or false) and blocking join (wait: true). Non-blocking polls include pending lane identities by default and process settled lanes incrementally while continuing independent work; busy/retry lanes are not timed out just because they run for a long time. Does not advance workflow gates.",agents:["architect"]},summarize_work:{description:"emit a short structured summary of completed work (key decisions, assumptions, risks, constraints) at task completion; rolls up per phase for architecture-supervisor review. Advisory, never blocks.",agents:["architect","sme","researcher","docs","docs_design","designer","explorer","coder","test_engineer"]},write_architecture_supervisor_evidence:{description:"persist the architecture supervisor verdict for a phase (architect MUST dispatch critic_architecture_supervisor first and collect its JSON verdict; this tool persists only, it does not contact the supervisor)",agents:["architect"]},lean_turbo_plan_lanes:{description:"partition phase tasks into parallel lanes based on file-scope conflicts for Lean Turbo execution",agents:[]},lean_turbo_acquire_locks:{description:"acquire file locks for all files in a lane (all-or-nothing) before lane execution",agents:[]},lean_turbo_runner_status:{description:"read Lean Turbo run state from .swarm/turbo-state.json",agents:[]},lean_turbo_review:{description:"dispatch a read-only reviewer agent to evaluate a completed Lean Turbo phase",agents:[]},lean_turbo_run_phase:{description:"Execute a phase using Lean Turbo parallel lane execution. Plans lanes, acquires file locks, and dispatches coder agents concurrently. Use when Lean Turbo is active and you want to execute all tasks in a phase in parallel lanes.",agents:[]},lean_turbo_status:{description:"returns Lean Turbo configuration and active status for the current session",agents:[]},swarm_apply_patch:{description:"Apply a unified diff patch to workspace files with exact context matching, atomic writes, and path validation. Use standard unified diff format only — does NOT support *** Begin Patch / *** Update File payloads (use native apply_patch for those).",agents:["coder","test_engineer"]},external_skill_discover:{description:"Discover external skill candidates from configured sources. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},external_skill_list:{description:"List external skill candidates in the quarantine store. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},external_skill_inspect:{description:"Inspect a specific external skill candidate by ID. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},external_skill_promote:{description:"Promote a validated external skill candidate to an active generated skill. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},external_skill_reject:{description:"Reject an external skill candidate after evaluation. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},external_skill_delete:{description:"Delete an external skill candidate from the quarantine store. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},external_skill_revoke:{description:"Revoke a previously promoted external skill. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},epic_decide_phase:{description:"Compute the Epic Mode verdict for a phase WITHOUT dispatching coders. Runs preflight + calibration + the three gates (p-threshold, hot-module, greenfield), persists the decision, and returns the verdict so the architect can dispatch waves via the visible Task tool (promote) or fall back to per-task serial (demote). Pair with `epic_plan_waves` to get the wave plan when promoted. Use when /swarm epic is on for the session.",agents:["architect"]},epic_plan_waves:{description:"Partition a phase's pending tasks into ordered concurrent waves for Epic Mode dispatch. A wave is a set of tasks with mutually disjoint declared scopes and all dependencies satisfied by prior waves. Returns `{ waves: [{ waveId, taskIds, files }, ...], serializedTasks, degradedTasks }`. "+'For each wave in order, the architect dispatches one `Task(subagent_type="coder", ...)` per `taskId` — all in one assistant message — so the wave runs concurrently and each coder appears as a visible subagent. '+"Wait for the wave to finish before dispatching the next. Pair with `epic_decide_phase` (called first; this tool is only relevant on a `promote` verdict). "+"Preflight reject reasons: `no-plan`, `no-phase`, `phase-empty`, `phase-already-complete`, `scopes-missing` (call `declare_scope` for `missingScopes`), `git-failed` (transient — retry), `planner-error`.",agents:["architect"]},epic_record_divergence:{description:"After every `update_task_status(completed)`, record the task's declared-vs-actual divergence to .swarm/epic/divergence.jsonl. Feeds Epic Mode's self-calibration loop (Capability D). Best-effort: never blocks.",agents:["architect"]}},TOOL_NAMES=Object.keys(TOOL_METADATA),TOOL_NAME_SET=new Set(TOOL_NAMES);TOOL_DESCRIPTIONS=Object.fromEntries(Object.entries(TOOL_METADATA).map(([name,meta])=>[name,meta.description])),AGENT_TOOL_MAP=(()=>{let map=Object.fromEntries(ALL_AGENT_NAMES.map((agent)=>[agent,[]]));for(let[name,meta]of Object.entries(TOOL_METADATA))for(let agent of meta.agents)map[agent].push(name);return map})()});function deepMergeInternal(base,override,depth){if(depth>=10)throw Error("deepMerge exceeded maximum depth of 10");let result={...base};for(let key of Object.keys(override)){let baseVal=base[key],overrideVal=override[key];if(typeof baseVal==="object"&&baseVal!==null&&typeof overrideVal==="object"&&overrideVal!==null&&!Array.isArray(baseVal)&&!Array.isArray(overrideVal))result[key]=deepMergeInternal(baseVal,overrideVal,depth+1);else result[key]=overrideVal}return result}function deepMerge(base,override){if(!base)return override;if(!override)return base;return deepMergeInternal(base,override,0)}var MAX_MERGE_DEPTH=10;function freezeSet(items){let set=new Set(items),proxy=new Proxy(set,{get(target,prop){if(prop==="add"||prop==="delete"||prop==="clear")return()=>{throw TypeError("CLAUDE_CODE_NATIVE_COMMANDS is readonly")};if(prop==="forEach")return(callback,thisArg)=>{let wrapped=(v,k)=>callback.call(thisArg??void 0,v,k,proxy);return set.forEach(wrapped)};let value=Reflect.get(target,prop);return typeof value==="function"?value.bind(target):value},set(){throw TypeError("CLAUDE_CODE_NATIVE_COMMANDS is readonly")},deleteProperty(){throw TypeError("CLAUDE_CODE_NATIVE_COMMANDS is readonly")},defineProperty(){throw TypeError("CLAUDE_CODE_NATIVE_COMMANDS is readonly")},setPrototypeOf(){throw TypeError("CLAUDE_CODE_NATIVE_COMMANDS is readonly")}});return proxy}function isQAAgent(name){return QA_AGENTS.includes(name)}function isSubagent(name){return ALL_SUBAGENT_NAMES.includes(name)}function isLowCapabilityModel(modelId){let lower=(modelId||"").toLowerCase();return LOW_CAPABILITY_MODELS.some((substr)=>lower.includes(substr))}var OPENCODE_NATIVE_AGENTS,CLAUDE_CODE_NATIVE_COMMANDS,MEMORY_AGENT_TOOL_MAP,EXTERNAL_SKILL_TOOL_NAMES,EXTERNAL_SKILL_AGENT_TOOL_MAP,COUNCIL_TOOL_NAMES,COUNCIL_AGENT_TOOL_MAP,GENERAL_COUNCIL_TOOL_NAMES,GENERAL_COUNCIL_AGENT_TOOL_MAP,TURBO_TOOL_NAMES,TURBO_AGENT_TOOL_MAP,SKILL_TOOL_NAMES,SKILL_AGENT_TOOL_MAP,WRITE_TOOL_NAMES,DEFAULT_MODELS,DEFAULT_SCORING_CONFIG,LOW_CAPABILITY_MODELS,TURBO_MODE_BANNER=`## \uD83D\uDE80 TURBO MODE ACTIVE
2
2
 
3
3
  **Speed optimization enabled for this session.**
4
4
 
@@ -5391,8 +5391,8 @@ ${WAKE_INSTRUCTION}`}async function sendWakePrompt(sessionID,events,messageID){l
5391
5391
  `)}init_branch();var GIT_TIMEOUT_MS7=30000,EvidencePlanSchema=exports_external.object({phases:exports_external.array(exports_external.object({tasks:exports_external.array(exports_external.object({id:exports_external.string(),status:exports_external.string().optional()}).passthrough()).optional()}).passthrough()).optional()}).passthrough();function ghExec(args2,cwd){for(let attempt=0;attempt<MAX_TRANSIENT_RETRIES;attempt++){let result=child_process10.spawnSync("gh",args2,{cwd,encoding:"utf-8",timeout:GIT_TIMEOUT_MS7,windowsHide:!0,maxBuffer:MAX_OUTPUT_BYTES5,stdio:["ignore","pipe","pipe"]});if(result.error){if(isTransientSpawnError(result.error)&&attempt<MAX_TRANSIENT_RETRIES-1){transientBackoff(attempt);continue}if(result.error.code==="ENOENT")throw Error("gh failed to start: ENOENT — gh not installed or not on PATH");throw Error(`gh failed to start: ${result.error.code} — ${result.error.message}`)}if(result.status!==0)throw Error(result.stderr||result.stdout||`gh exited with ${result.status}`);return result.stdout}throw Error("gh exited with null")}var MAX_OUTPUT_BYTES5=5242880,__spawnSyncSeam2={spawnSync:(cmd,args2,options)=>{let mergedEnv=mergeEnvForChild(options?.env,options?.envOverrides);return child_process10.spawnSync(cmd,args2,{...options,env:mergedEnv})}};function spawnSyncWithTransientRetry(command,args2,options){for(let attempt=0;attempt<MAX_TRANSIENT_RETRIES;attempt++){let result=__spawnSyncSeam2.spawnSync(command,args2,options);if(result.error){if(isTransientSpawnError(result.error)&&attempt<MAX_TRANSIENT_RETRIES-1){transientBackoff(attempt);continue}throw Error(`${command} failed: ${result.error.code} — ${result.error.message}`)}if(result.status!==0){let reason=result.stderr||result.stdout||`${command} exited with ${result.status}`;throw Error(`${command} failed: ${reason}`)}return result}throw Error(`${command} exited with null`)}async function ghExecAsync(args2,cwd){return new Promise((resolve60,reject)=>{let proc=child_process10.spawn("gh",args2,{cwd,stdio:["ignore","pipe","pipe"]}),stdoutChunks=[],stderrChunks=[],stdoutBytes=0,stderrBytes=0,settled=!1;function cleanup(){if(clearTimeout(timer),!proc.killed)try{proc.kill()}catch{}}function settle(fn2){if(settled)return;settled=!0,cleanup(),fn2()}proc.stdout?.on("data",(chunk)=>{if(stdoutBytes+=chunk.length,stdoutBytes>MAX_OUTPUT_BYTES5){settle(()=>reject(Error(`gh ${args2[0]} stdout exceeded ${MAX_OUTPUT_BYTES5} bytes`)));return}stdoutChunks.push(chunk)}),proc.stderr?.on("data",(chunk)=>{if(stderrBytes+=chunk.length,stderrBytes>MAX_OUTPUT_BYTES5){settle(()=>reject(Error(`gh ${args2[0]} stderr exceeded ${MAX_OUTPUT_BYTES5} bytes`)));return}stderrChunks.push(chunk)});let timer=setTimeout(()=>{settle(()=>reject(Error(`gh ${args2[0]} timed out after ${GIT_TIMEOUT_MS7}ms`)))},GIT_TIMEOUT_MS7);proc.on("error",(err)=>{settle(()=>reject(err))}),proc.on("close",(code)=>{settle(()=>{if(code!==0){let stderr=Buffer.concat(stderrChunks).toString("utf-8");reject(Error(stderr||`gh exited with ${code}`))}else{let stdout=Buffer.concat(stdoutChunks).toString("utf-8");resolve60(stdout)}})})})}var _internals109={ghExec,ghExecAsync,spawnSyncWithTransientRetry,spawnSync:__spawnSyncSeam2.spawnSync,readLaneEnvFileFromDiskSync,getMergeGroupRun};async function getPRStatus(prNumber,repoFullName,cwd){let stdout;try{stdout=await _internals109.ghExecAsync(["pr","view",String(prNumber),"--repo",repoFullName,"--json","number,state,mergeable,mergeStateStatus,headRefOid,statusCheckRollup"],cwd)}catch(err){throw Error(`Failed to fetch PR status for ${repoFullName}#${prNumber}: ${err instanceof Error?err.message:String(err)}`)}return JSON.parse(stdout)}async function getPRComments(prNumber,repoFullName,cwd,since){let query=since?`?since=${since}`:"",issueCommentsPath=`repos/${repoFullName}/issues/${prNumber}/comments${query}`,reviewCommentsPath=`repos/${repoFullName}/pulls/${prNumber}/comments${query}`,issueComments,reviewComments;try{let issueRaw=await _internals109.ghExecAsync(["api",issueCommentsPath],cwd);issueComments=JSON.parse(issueRaw)}catch(err){throw Error(`Failed to fetch issue comments for ${repoFullName}#${prNumber}: ${err instanceof Error?err.message:String(err)}`)}try{let reviewRaw=await _internals109.ghExecAsync(["api",reviewCommentsPath],cwd);reviewComments=JSON.parse(reviewRaw)}catch(err){throw Error(`Failed to fetch review comments for ${repoFullName}#${prNumber}: ${err instanceof Error?err.message:String(err)}`)}let mapIssueComment=(c)=>({id:String(c.id??""),author:String(c.user?.login??""),body:neutralizeUntrustedMarkdown(String(c.body??""),"GitHub issue comment"),createdAt:String(c.created_at??""),isReviewComment:!1}),mapReviewComment=(c)=>({id:String(c.id??""),author:String(c.user?.login??""),body:neutralizeUntrustedMarkdown(String(c.body??""),"GitHub review comment"),createdAt:String(c.created_at??""),isReviewComment:!0});return[...issueComments.map(mapIssueComment),...reviewComments.map(mapReviewComment)]}async function getMergeState(prNumber,repoFullName,cwd){let stdout;try{stdout=await _internals109.ghExecAsync(["pr","view",String(prNumber),"--repo",repoFullName,"--json","mergeable,mergeStateStatus,headRefOid"],cwd)}catch(err){throw Error(`Failed to fetch merge state for ${repoFullName}#${prNumber}: ${err instanceof Error?err.message:String(err)}`)}let parsed=JSON.parse(stdout);return{mergeable:parsed.mergeable,mergeStateStatus:parsed.mergeStateStatus,headRefOid:parsed.headRefOid}}async function getPRReviewState(prNumber,repoFullName,cwd){let stdout;try{stdout=await _internals109.ghExecAsync(["pr","view",String(prNumber),"--repo",repoFullName,"--json","reviewDecision,reviewRequests"],cwd)}catch(err){throw Error(`Failed to fetch review state for ${repoFullName}#${prNumber}: ${err instanceof Error?err.message:String(err)}`)}let parsed=JSON.parse(stdout);return{reviewDecision:parsed.reviewDecision??"",reviewRequestCount:parsed.reviewRequests?.length??0}}async function getMergeGroupRun(statusCheckRollup,repoFullName,cwd){let mergeGroupCheck=statusCheckRollup.find((check3)=>check3.name==="Merge pull request"&&check3.detailsUrl);if(!mergeGroupCheck?.detailsUrl)return null;let runIdMatch=mergeGroupCheck.detailsUrl.match(/\/actions\/runs\/(\d+)/);if(!runIdMatch)return null;let runId=runIdMatch[1],stdout;try{stdout=await _internals109.ghExecAsync(["run","view",runId,"--json","status,conclusion,htmlUrl","--repo",repoFullName],cwd)}catch(err){throw Error(`Failed to fetch merge group run for ${repoFullName}: ${err instanceof Error?err.message:String(err)}`)}let parsed=JSON.parse(stdout);return{status:parsed.status??"",conclusion:parsed.conclusion??null,htmlUrl:parsed.htmlUrl??""}}init_utils();init_event_bus();init_pr_subscriptions();class PrMonitorWorker{directory;config;onEvent;status="stopped";pollTimer=null;disposed=!1;circuitBreakerMap=new Map;reviewStateMap=new Map;mergedOrClosedKeys=new Set;constructor(options){this.directory=options.directory,this.config=options.config,this.onEvent=options.onEvent}start(){if(this.disposed){log("[PrMonitorWorker] Cannot start — worker has been disposed");return}if(!this.directory){log("[PrMonitorWorker] Cannot start — no directory provided");return}if(!this.config.enabled){log("[PrMonitorWorker] Cannot start — pr_monitor.enabled is false");return}if(this.status==="running"||this.status==="starting"){log("[PrMonitorWorker] Already running or starting");return}this.status="starting",log("[PrMonitorWorker] Starting..."),this.pollTimer=setInterval(()=>{if(this.disposed||this.status!=="running")return;this.executePollCycle().catch((err)=>{log("[PrMonitorWorker] Unhandled poll cycle error",{error:err instanceof Error?err.message:String(err)})})},this.config.poll_interval_seconds*1000),this.status="running",log("[PrMonitorWorker] Started polling",{intervalSeconds:this.config.poll_interval_seconds})}stop(){if(this.status==="stopped"||this.status==="stopping")return;if(this.status="stopping",log("[PrMonitorWorker] Stopping..."),this.pollTimer)clearInterval(this.pollTimer),this.pollTimer=null;this.status="stopped",this.circuitBreakerMap.clear(),this.reviewStateMap.clear(),log("[PrMonitorWorker] Stopped")}dispose(){this.stop(),this.disposed=!0,log("[PrMonitorWorker] Disposed")}getStatus(){return this.status}isRunning(){return this.status==="running"}async pollCycle(){if(this.disposed)return;await this.executePollCycle()}async executePollCycle(){log("[PrMonitorWorker] Poll cycle starting");try{let activeSubs=await _internals110.listActive(this.directory);if(activeSubs.length===0){log("[PrMonitorWorker] No active subscriptions"),await this.runSweep();return}let toPoll=activeSubs.slice(0,this.config.max_prs_per_cycle),concurrencyLimit=this.config.max_concurrent_pr_polls;await this.processWithConcurrency(toPoll,concurrencyLimit),await this.runSweep()}catch(err){log("[PrMonitorWorker] Poll cycle error",{error:err instanceof Error?err.message:String(err)})}}async processWithConcurrency(subs,concurrencyLimit){let index=0,runNext=async()=>{while(index<subs.length){let currentIndex=index;if(index++,this.disposed)return;await this.pollWithTimeout(subs[currentIndex])}},workers=Array.from({length:Math.min(concurrencyLimit,subs.length)},()=>runNext());await Promise.all(workers)}async pollWithTimeout(sub){let timeoutMs=this.config.poll_timeout_ms,timer,timedOut=!1,timeoutPromise=new Promise((_,reject)=>{timer=setTimeout(()=>{timedOut=!0,reject(Error(`PR poll timed out after ${timeoutMs}ms for ${sub.repoFullName}#${sub.prNumber}`))},timeoutMs)});try{await Promise.race([this.pollSinglePr(sub,()=>timedOut),timeoutPromise])}catch(err){await this.handlePollError(sub,err instanceof Error?err:Error(String(err)))}finally{if(timer)clearTimeout(timer)}}async pollSinglePr(sub,isTimedOut){let correlationId=sub.correlationId;if(!this.circuitBreakerMap.has(correlationId)&&sub.errorCount>0)this.circuitBreakerMap.set(correlationId,{errorCount:sub.errorCount,suspendedUntil:0,cooldownLevel:0});let cb=this.circuitBreakerMap.get(correlationId);if(cb&&cb.suspendedUntil>Date.now()){log("[PrMonitorWorker] PR suspended by circuit breaker",{correlationId,suspendedUntil:new Date(cb.suspendedUntil).toISOString()});return}try{let[statusResult,commentsResult,mergeResult,reviewResult]=await Promise.all([_internals110.getPRStatus(sub.prNumber,sub.repoFullName,this.directory),_internals110.getPRComments(sub.prNumber,sub.repoFullName,this.directory),_internals110.getMergeState(sub.prNumber,sub.repoFullName,this.directory),_internals110.getPRReviewState(sub.prNumber,sub.repoFullName,this.directory)]);if(isTimedOut?.()){log("[PrMonitorWorker] Skipping late result — poll already timed out",{correlationId:sub.correlationId});return}let mergeGroupRunResult=null,mergeGroupRunFetchSucceeded=!1;try{mergeGroupRunResult=await _internals110.getMergeGroupRun(statusResult.statusCheckRollup,sub.repoFullName,this.directory),mergeGroupRunFetchSucceeded=!0}catch(err){log("[PrMonitorWorker] Failed to fetch merge group run",{correlationId:sub.correlationId,error:err instanceof Error?err.message:String(err)})}if(isTimedOut?.()){log("[PrMonitorWorker] Skipping late result — poll already timed out",{correlationId:sub.correlationId});return}let changes=this.computeChanges(sub,{status:statusResult,comments:commentsResult,merge:mergeResult,review:reviewResult,mergeGroupRun:mergeGroupRunResult},mergeGroupRunFetchSucceeded);if(await this.applyChanges(sub,changes,isTimedOut),!isTimedOut?.())this.circuitBreakerMap.delete(correlationId),await _internals110.updateSnapshot(this.directory,correlationId,{errorCount:0,lastCheckedAt:Date.now()})}catch(err){if(isTimedOut?.()){log("[PrMonitorWorker] Skipping late error — poll already timed out",{correlationId:sub.correlationId});return}await this.handlePollError(sub,err instanceof Error?err:Error(String(err)))}}computeChanges(sub,current,mergeGroupRunFetchSucceeded){let events=[],snapshotUpdates={headRefOid:current.status.headRefOid,mergeableState:current.merge.mergeable,lastCheckedAt:Date.now()};if(mergeGroupRunFetchSucceeded)snapshotUpdates.mergeGroupRunStatus=current.mergeGroupRun?.status,snapshotUpdates.mergeGroupRunConclusion=current.mergeGroupRun?.conclusion??void 0,snapshotUpdates.mergeGroupRunHtmlUrl=current.mergeGroupRun?.htmlUrl;let isMerged=!1,isClosed=!1,newReviewDecision="";if(current.status.headRefOid!==sub.headRefOid)events.push({type:"pr.status.updated",payload:{prNumber:sub.prNumber,repoFullName:sub.repoFullName,prUrl:sub.prUrl,previousOid:sub.headRefOid,currentOid:current.status.headRefOid}});let currentCheckSet=this.serializeChecks(current.status.statusCheckRollup);if(sub.lastCheckRunSet!==void 0&&currentCheckSet!==sub.lastCheckRunSet){let prevChecks=this.parseCheckSet(sub.lastCheckRunSet);this.computeCIEvents(sub,prevChecks,current.status.statusCheckRollup,events)}if(snapshotUpdates.lastCheckRunSet=currentCheckSet,current.comments.length>0){let sorted=[...current.comments].sort((a,b)=>a.createdAt.localeCompare(b.createdAt)),newComments;if(sub.lastCommentId===void 0)newComments=sorted;else{let lastIdx=sorted.findIndex((c)=>c.id===sub.lastCommentId);newComments=lastIdx>=0?sorted.slice(lastIdx+1):sorted}for(let comment of newComments)events.push({type:"pr.new.comment",payload:{prNumber:sub.prNumber,repoFullName:sub.repoFullName,prUrl:sub.prUrl,commentId:comment.id,author:comment.author,body:comment.body,createdAt:comment.createdAt,isReviewComment:comment.isReviewComment}});snapshotUpdates.lastCommentId=sorted[sorted.length-1].id}if(current.merge.mergeable==="CONFLICTING"&&sub.mergeableState!=="CONFLICTING")events.push({type:"pr.merge.conflict",payload:{prNumber:sub.prNumber,repoFullName:sub.repoFullName,prUrl:sub.prUrl,mergeableState:current.merge.mergeable}});else if(sub.mergeableState==="CONFLICTING"&&current.merge.mergeable!=="CONFLICTING")events.push({type:"pr.merge.conflict_resolved",payload:{prNumber:sub.prNumber,repoFullName:sub.repoFullName,prUrl:sub.prUrl,mergeableState:current.merge.mergeable}});let prevReviewDecision=this.reviewStateMap.get(sub.correlationId)??"";if(current.review.reviewDecision&&current.review.reviewDecision!==prevReviewDecision){if(current.review.reviewDecision==="CHANGES_REQUESTED"&&prevReviewDecision!=="CHANGES_REQUESTED")events.push({type:"pr.review.changes_requested",payload:{prNumber:sub.prNumber,repoFullName:sub.repoFullName,prUrl:sub.prUrl,reviewDecision:current.review.reviewDecision}});else if(current.review.reviewDecision==="APPROVED"&&prevReviewDecision!=="APPROVED")events.push({type:"pr.review.approved",payload:{prNumber:sub.prNumber,repoFullName:sub.repoFullName,prUrl:sub.prUrl,reviewDecision:current.review.reviewDecision}});newReviewDecision=current.review.reviewDecision}if(current.status.state==="MERGED")isMerged=!0,events.push({type:"pr.merged",payload:{prNumber:sub.prNumber,repoFullName:sub.repoFullName,prUrl:sub.prUrl,headRefOid:current.status.headRefOid}}),snapshotUpdates.isWatching=!1;if(current.status.state==="CLOSED")isClosed=!0,events.push({type:"pr.closed",payload:{prNumber:sub.prNumber,repoFullName:sub.repoFullName,prUrl:sub.prUrl}}),snapshotUpdates.isWatching=!1;return snapshotUpdates.hasUnaddressedEvents=events.length>0,{events,snapshotUpdates,isMerged,isClosed,newReviewDecision}}computeCIEvents(sub,prevChecks,currentChecks,events){let allPassed=!0,prevMap=new Map(prevChecks.map((c)=>[c.name,c.conclusion])),newlyFailedChecks=[];for(let check3 of currentChecks){if(check3.conclusion==="failure"||check3.conclusion==="FAILURE"){let prev=prevMap.get(check3.name);if(prev!=="failure"&&prev!=="FAILURE")newlyFailedChecks.push({name:check3.name,conclusion:check3.conclusion})}if(check3.conclusion!=="success"&&check3.conclusion!=="SUCCESS")allPassed=!1}if(newlyFailedChecks.length>0)events.push({type:"pr.ci.failed",payload:{prNumber:sub.prNumber,repoFullName:sub.repoFullName,prUrl:sub.prUrl,failedChecks:newlyFailedChecks}});if(allPassed&&currentChecks.length>0){if(prevChecks.some((c)=>c.conclusion!=="success"&&c.conclusion!=="SUCCESS")||prevChecks.length===0)events.push({type:"pr.ci.passed",payload:{prNumber:sub.prNumber,repoFullName:sub.repoFullName,prUrl:sub.prUrl,checkCount:currentChecks.length}})}}async applyChanges(sub,changes,isTimedOut){if(isTimedOut?.()){log("[PrMonitorWorker] Skipping change application — poll already timed out",{correlationId:sub.correlationId});return}for(let{type,payload}of changes.events)await this.emitEvent(type,payload);if(isTimedOut?.()){log("[PrMonitorWorker] Skipping state mutations — poll timed out during event emission",{correlationId:sub.correlationId});return}if(changes.newReviewDecision)this.reviewStateMap.set(sub.correlationId,changes.newReviewDecision);if(changes.isMerged&&this.config.auto_unsubscribe_on_merge||changes.isClosed&&this.config.auto_unsubscribe_on_close)this.mergedOrClosedKeys.add(`${sub.repoFullName}::${sub.prNumber}`);if(changes.isMerged&&this.config.auto_unsubscribe_on_merge){await _internals110.unsubscribe(this.directory,sub.correlationId),this.reviewStateMap.delete(sub.correlationId),this.circuitBreakerMap.delete(sub.correlationId),log("[PrMonitorWorker] Auto-unsubscribed merged PR",{correlationId:sub.correlationId});return}if(changes.isClosed&&this.config.auto_unsubscribe_on_close){await _internals110.unsubscribe(this.directory,sub.correlationId),this.reviewStateMap.delete(sub.correlationId),this.circuitBreakerMap.delete(sub.correlationId),log("[PrMonitorWorker] Auto-unsubscribed closed PR",{correlationId:sub.correlationId});return}if(isTimedOut?.()){log("[PrMonitorWorker] Skipping snapshot update — poll timed out before write",{correlationId:sub.correlationId});return}await _internals110.updateSnapshot(this.directory,sub.correlationId,changes.snapshotUpdates)}async handlePollError(sub,error93){let correlationId=sub.correlationId,cb=this.circuitBreakerMap.get(correlationId)??{errorCount:0,suspendedUntil:0,cooldownLevel:0};if(cb.errorCount++,await _internals110.updateSnapshot(this.directory,correlationId,{errorCount:cb.errorCount,lastCheckedAt:Date.now()}),cb.errorCount>=this.config.failure_threshold){cb.cooldownLevel++;let cooldownSeconds=Math.min(this.config.cooldown_seconds*2**(cb.cooldownLevel-1),this.config.max_cooldown_seconds);cb.suspendedUntil=Date.now()+cooldownSeconds*1000,this.circuitBreakerMap.set(correlationId,cb),error48("[PrMonitorWorker] Circuit breaker tripped for PR",{correlationId,errorCount:cb.errorCount,cooldownSeconds}),await this.emitEvent("pr.error",{prNumber:sub.prNumber,repoFullName:sub.repoFullName,prUrl:sub.prUrl,reason:"circuit_breaker",errorCount:cb.errorCount,cooldownSeconds})}else this.circuitBreakerMap.set(correlationId,cb),log("[PrMonitorWorker] Poll error for PR",{correlationId,errorCount:cb.errorCount,error:error93.message})}async emitEvent(type,payload){let event={type,timestamp:Date.now(),payload,source:"pr-monitor-worker"};try{await _internals110.getGlobalEventBus().publish(type,payload,"pr-monitor-worker")}catch(err){log("[PrMonitorWorker] Event publish failed",{type,error:err instanceof Error?err.message:String(err)})}if(this.onEvent)try{this.onEvent(event)}catch{}}async runSweep(){if(this.config.cleanup_ttl_days>0)try{let keysToPass=this.mergedOrClosedKeys.size>0?this.mergedOrClosedKeys:void 0;await _internals110.sweepStale(this.directory,this.config.cleanup_ttl_days,keysToPass)}catch(err){log("[PrMonitorWorker] Sweep failed",{error:err instanceof Error?err.message:String(err)})}finally{this.mergedOrClosedKeys.clear()}else this.mergedOrClosedKeys.clear()}serializeChecks(checks5){return JSON.stringify(checks5.map((c)=>({n:c.name,c:c.conclusion})))}parseCheckSet(serialized2){try{return JSON.parse(serialized2).map((p)=>({name:p.n,conclusion:p.c}))}catch{return[]}}}var _internals110={getPRStatus,getPRComments,getMergeState,getMergeGroupRun,getPRReviewState,listActive,updateSnapshot,unsubscribe,sweepStale,getGlobalEventBus};init_queue();init_status_artifact();init_trigger();init_worker();init_logger();init_pending_delegations();import{createHash as createHash28}from"node:crypto";init_gate_evidence();init_gate_evidence_classification();init_schema();init_logger();init_review_receipt();init_skill_propagation_gate();var SECTION_FIELDS=["VERDICT","REUSE_RE_VERIFICATION","RISK","ISSUES","ACCEPTANCE_SATISFACTION","SKILL_COMPLIANCE","DIRECTIVE_COMPLIANCE","FIXES"],LOCATION_PATTERN=/([\w./-]+\.[A-Za-z]{1,8}):(\d{1,6})/;function inferSeverity(line){let upper=line.toUpperCase();if(upper.includes("CRITICAL"))return"critical";if(upper.includes("HIGH"))return"high";return"medium"}function collectSectionLines(lines,section){let headerPattern=new RegExp(`^\\s*${section}\\s*:\\s*(.*)$`,"i"),nextSectionPattern=new RegExp(`^\\s*(${SECTION_FIELDS.join("|")})\\s*:`,"i"),collected=[],inSection=!1;for(let line of lines){if(!inSection){let m=line.match(headerPattern);if(m){inSection=!0;let inline=m[1]?.trim();if(inline&&!/^(none|n\/a)\.?$/i.test(inline))collected.push(inline)}continue}if(nextSectionPattern.test(line))break;let cleaned=line.replace(/^\s*(?:[-*•]|\d+[.)])\s*/,"").trim();if(cleaned)collected.push(cleaned)}return collected}var VERDICT_LINE_PATTERN=/^\s*(?:\*\*)?VERDICT(?:\*\*)?\s*:\s*(APPROVED|REJECTED)\s*$/gim,RISK_LINE_PATTERN=/^\s*(?:\*\*)?RISK(?:\*\*)?\s*:\s*(LOW|MEDIUM|HIGH|CRITICAL)\b/gim;function parseReviewerOutput(text){if(!text||typeof text!=="string")return null;let verdictTokens=[...text.matchAll(VERDICT_LINE_PATTERN)].map((m)=>m[1].toUpperCase());if(verdictTokens.length===0)return null;if(new Set(verdictTokens).size>1)return null;let verdict=verdictTokens[0]==="APPROVED"?"approved":"rejected",risk=[...text.matchAll(RISK_LINE_PATTERN)].map((m)=>m[1].toUpperCase()).at(-1),lines=text.split(/\r?\n/),issues=collectSectionLines(lines,"ISSUES").slice(0,50).map((line)=>{let location=line.match(LOCATION_PATTERN)?.[0];return{text:line.slice(0,500),severity:inferSeverity(line),location}}),fixes=collectSectionLines(lines,"FIXES").slice(0,50).map((line)=>line.slice(0,500));return{verdict,risk,issues,fixes}}function isTaskTool2(tool3){return tool3==="Task"||tool3==="task"}async function collectReviewerReceiptFromTranscript(directory,input){try{if(input.targetAgent&&stripKnownSwarmPrefix(input.targetAgent).toLowerCase()!=="reviewer")return null;if(!input.prompt||!input.transcript)return null;let parsed=parseReviewerOutput(input.transcript);if(!parsed)return null;let receipt=parsed.verdict==="approved"?buildApprovedReceipt({agent:"reviewer",sessionId:input.sessionID??input.sessionId,scopeContent:input.prompt,scopeDescription:"reviewer-task-prompt",checkedAspects:["code-review"],validatedClaims:[`VERDICT: APPROVED${parsed.risk?` (risk ${parsed.risk})`:""}`],caveats:parsed.issues.map((i)=>i.text)}):buildRejectedReceipt({agent:"reviewer",sessionId:input.sessionID??input.sessionId,scopeContent:input.prompt,scopeDescription:"reviewer-task-prompt",blockingFindings:parsed.issues.map((i)=>({location:i.location??"unknown",summary:i.text,severity:i.severity})),evidenceReferences:parsed.issues.map((i)=>i.location).filter((loc)=>Boolean(loc)),passConditions:parsed.fixes,summary:`Reviewer REJECTED${parsed.risk?` (risk ${parsed.risk})`:""}`});return await persistReviewReceipt(directory,receipt)}catch(err){return warn(`[review-receipt-collector] failed: ${err instanceof Error?err.message:String(err)}`),null}}async function collectReviewerReceiptAfter(directory,input,output){try{if(!isTaskTool2(input.tool))return null;let parsedArgs=parseDelegationArgs(input.args);if(!parsedArgs)return null;if(stripKnownSwarmPrefix(parsedArgs.targetAgent).toLowerCase()!=="reviewer")return null;let argsRecord=input.args&&typeof input.args==="object"?input.args:null,prompt=argsRecord&&typeof argsRecord.prompt==="string"?argsRecord.prompt:"",transcript=typeof output.output==="string"?output.output:"",sessionID=typeof input.sessionID==="string"?input.sessionID:void 0;return await collectReviewerReceiptFromTranscript(directory,{targetAgent:parsedArgs.targetAgent,prompt,transcript,sessionID})}catch(err){return warn(`[review-receipt-collector] failed: ${err instanceof Error?err.message:String(err)}`),null}}init_state2();init_logger();init_workspace_snapshot();var GATE_EVIDENCE_ROLES=new Set(["reviewer","test_engineer","docs","designer","critic","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic_architecture_supervisor","explorer","sme"]);function isBackgroundGateBearingRecord(record3){return record3.batchId===void 0&&record3.evidenceTaskId!==null&&GATE_EVIDENCE_ROLES.has(record3.normalizedAgent)}function validateStageBWorkspace(directory,record3){let actualWorkspace=captureWorkspaceSnapshot(directory,{scope:record3.workspace?.scope??null,prHeadSha:record3.workspace?.prHeadSha??null,resolveCurrentPrHeadSha:record3.workspace?.prHeadSha!==null}),check3=compareWorkspaceSnapshots(record3.workspace,actualWorkspace);return{...check3,ok:!check3.stale}}async function ingestBackgroundStageBCompletion(args2){let taskId=args2.record.evidenceTaskId??args2.record.planTaskId;if(!taskId)return{ok:!0,consumed:!1};if(args2.record.normalizedAgent==="coder"){let taskChangeContext=args2.record.taskChangeContext,observedFiles=taskChangeContext?changedFilesSinceSnapshot(taskChangeContext.baseline.directory,taskChangeContext.baseline):null;try{return await recordAgentDispatch(args2.directory,taskId,"coder",void 0,{testEngineerExempt:isMarkdownOnlyTaskChange(taskChangeContext?.declaredFiles,observedFiles)}),{ok:!0,consumed:!0}}catch(err){return{ok:!1,consumed:!1,reason:`background coder evidence ingestion failed: ${err instanceof Error?err.message:String(err)}`}}}if(!isBackgroundGateBearingRecord(args2.record))return{ok:!0,consumed:!1};let workspaceCheck=validateStageBWorkspace(args2.directory,args2.record);if(workspaceCheck.stale)return{ok:!1,consumed:!1,stale:!0,reason:workspaceCheck.reason??"workspace changed while gate was running"};try{let existingEvidence=await readTaskEvidence(args2.directory,taskId);if(existingEvidence?.test_engineer_exempt!==!0)await recordAgentDispatch(args2.directory,taskId,stageBRequiredGateAgent(args2.record.normalizedAgent),hasActiveTurboMode(args2.record.parentSessionId));if(await recordGateEvidence(args2.directory,taskId,args2.record.normalizedAgent,args2.record.subagentSessionId,hasActiveTurboMode(args2.record.parentSessionId)),args2.record.normalizedAgent==="reviewer")await collectReviewerReceiptFromTranscript(args2.directory,{targetAgent:args2.record.swarmPrefixedAgent,prompt:args2.record.prompt?.text??"",transcript:args2.result.text??"",sessionID:args2.record.subagentSessionId});if(args2.record.normalizedAgent==="reviewer"||args2.record.normalizedAgent==="test_engineer")applyStageBStateCompletion(taskId,args2.record.normalizedAgent,args2.record.parentSessionId,existingEvidence?.test_engineer_exempt===!0);return{ok:!0,consumed:!0}}catch(err){let message=err instanceof Error?err.message:String(err);return warn(`[background-stage-b] ingestion failed: ${message}`),{ok:!1,consumed:!1,reason:`stage-b ingestion failed: ${message}`}}}function stageBRequiredGateAgent(agent){return agent==="reviewer"||agent==="test_engineer"?"coder":agent}function candidateSessions(parentSessionId){let parent=swarmState.agentSessions.get(parentSessionId);return parent?[parent]:[]}function applyStageBStateCompletion(taskId,agent,parentSessionId,testEngineerExempt){for(let session of candidateSessions(parentSessionId)){recordStageBCompletion(session,taskId,agent);let state=getTaskState(session,taskId);if(state==="tests_run"||state==="complete")continue;if(hasBothStageBCompletions(session,taskId)||testEngineerExempt&&agent==="reviewer"){try{if(state==="coder_delegated"||state==="pre_check_passed")advanceTaskState(session,taskId,"reviewer_run",{telemetrySessionId:parentSessionId});if(getTaskState(session,taskId)==="reviewer_run")advanceTaskState(session,taskId,"tests_run",{telemetrySessionId:parentSessionId})}catch(err){warn(`[background-stage-b] could not advance ${taskId} after ${agent}: ${err instanceof Error?err.message:String(err)}`)}continue}if(agent==="reviewer"&&(state==="coder_delegated"||state==="pre_check_passed"))try{advanceTaskState(session,taskId,"reviewer_run",{telemetrySessionId:parentSessionId})}catch(err){warn(`[background-stage-b] could not advance ${taskId} to reviewer_run: ${err instanceof Error?err.message:String(err)}`)}else if(agent==="test_engineer"&&state==="reviewer_run")try{advanceTaskState(session,taskId,"tests_run",{telemetrySessionId:parentSessionId})}catch(err){warn(`[background-stage-b] could not advance ${taskId} to tests_run: ${err instanceof Error?err.message:String(err)}`)}}}init_task_envelope();function createBackgroundCompletionObserver(opts){let{config:config3,directory}=opts;return{event:async(input)=>{if(!config3.enabled)return;try{let evt=input?.event;if(!evt||evt.type!=="message.part.updated")return;let part=evt.properties?.part;if(!part||part.type!=="text")return;if(part.synthetic!==!0)return;if(typeof part.text!=="string")return;let envelope=parseTaskEnvelope(part.text);if(!envelope)return;if(envelope.state!=="completed"&&envelope.state!=="error")return;let pending=findByCorrelationId(directory,envelope.sessionId),parentSessionId=typeof part.sessionID==="string"?part.sessionID:"unknown";if(!pending){log(`[background] observed synthetic completion (state=${envelope.state}) for subagent ${envelope.sessionId} in parent ${parentSessionId} with NO matching pending record - ignored`);return}if(pending.parentSessionId!==parentSessionId){warn(`[background] observed synthetic completion for ${envelope.sessionId} with parent mismatch: expected=${pending.parentSessionId} observed=${parentSessionId}; ignored`);return}if(pending.status!=="pending"&&pending.status!=="running"&&pending.status!=="ingestion_error"){log(`[background] observed duplicate/late completion for ${envelope.sessionId}; current status=${pending.status}; ignored`);return}let text=envelope.state==="error"?envelope.errorText??"":envelope.resultText??"",result={...envelope.state==="error"?{error:text}:{text},chars:envelope.resultChars??text.length,truncated:envelope.resultTruncated??!1,digest:digest2(text)};if(envelope.state==="completed"&&isBackgroundGateBearingRecord(pending)){let freshness=validateStageBWorkspace(directory,pending);if(freshness.stale){let reason=freshness.reason??"workspace changed before background Stage B completion";await appendDelegationTransition(directory,envelope.sessionId,{status:"stale",result:{error:reason,chars:reason.length,truncated:!1,digest:digest2(reason)}}),warn(`[background] stale Stage B completion ignored: agent=${pending.normalizedAgent} task=${pending.evidenceTaskId??pending.planTaskId??"unknown"} reason=${reason}`);return}}let terminal=await appendDelegationTransition(directory,envelope.sessionId,{status:envelope.state==="error"?"error":"completed",result});if(envelope.state==="completed"&&terminal){let ingested=await ingestBackgroundStageBCompletion({directory,record:terminal,result:terminal.result??result});if(ingested.consumed)await appendDelegationTransition(directory,envelope.sessionId,{status:"consumed"});if(!ingested.ok)await appendDelegationTransition(directory,envelope.sessionId,{status:"ingestion_error",result:terminal.result??result}),warn(`[background] Stage B completion was not applied: agent=${terminal.normalizedAgent} task=${terminal.evidenceTaskId??terminal.planTaskId??"unknown"} reason=${ingested.reason??"unknown"}`)}log(`[background] observed trusted completion (state=${envelope.state}) correlated to pending delegation: agent=${pending.normalizedAgent} task=${pending.evidenceTaskId??pending.planTaskId??"unknown"} parent=${pending.parentSessionId} observedParent=${parentSessionId} pendingStatus=${pending.status} stageB=${isBackgroundGateBearingRecord(pending)}`)}catch(err){warn(`[background] completion observer error: ${err instanceof Error?err.message:String(err)}`)}}}}function digest2(text){return createHash28("sha256").update(text).digest("hex")}init_pr_subscriptions();init_commands();init_registry2();init_config();init_bundled_skills();init_constants();init_config();init_warning_buffer();init_constants();import*as fs85 from"node:fs";import*as path165 from"node:path";var STARTER_CONTENT=`{}
5392
5392
  `;function writeProjectConfigIfNew(directory,_quiet=!1){try{let opencodeDir=path165.join(directory,".opencode"),dest=path165.join(opencodeDir,"opencode-swarm.json"),normalizePathForCompare=(p)=>process.platform==="win32"?p.toLowerCase():p;try{if(fs85.lstatSync(opencodeDir).isSymbolicLink())return;let resolvedDir=fs85.realpathSync(opencodeDir),canonicalOpencode=path165.join(fs85.realpathSync(directory),".opencode");if(normalizePathForCompare(resolvedDir)!==normalizePathForCompare(canonicalOpencode))return}catch(err){if(err.code!=="ENOENT")return}if(!fs85.existsSync(opencodeDir))fs85.mkdirSync(opencodeDir,{recursive:!0});try{fs85.writeFileSync(dest,STARTER_CONTENT,{encoding:"utf-8",flag:"wx"}),advisoryWarn("[opencode-swarm] Created .opencode/opencode-swarm.json — "+"edit it to customize agent LLMs for this project, or commit it to share settings with your team")}catch(_writeErr){}}catch{}}function writeSwarmConfigExampleIfNew(projectDirectory){try{let swarmDir=path165.join(projectDirectory,".swarm"),dest=path165.join(swarmDir,"config.example.json");if(fs85.existsSync(dest))return;if(!fs85.existsSync(swarmDir))fs85.mkdirSync(swarmDir,{recursive:!0});let example={agents:Object.fromEntries(Object.entries(DEFAULT_MODELS).filter(([name])=>name!=="default").map(([name,model])=>[name,{model,fallback_models:["opencode/gpt-5-nano","opencode/big-pickle"]}])),max_iterations:5};fs85.writeFileSync(dest,`${JSON.stringify(example,null,2)}
5393
5393
  `,"utf-8")}catch{}}init_schema();import*as fs88 from"node:fs";import*as path168 from"node:path";import*as fs87 from"node:fs";import*as path167 from"node:path";import*as crypto13 from"node:crypto";import*as fs86 from"node:fs";import*as path166 from"node:path";var _internals111={readFileSync:fs86.readFileSync,writeFileSync:fs86.writeFileSync,mkdirSync:fs86.mkdirSync,renameSync:fs86.renameSync,existsSync:fs86.existsSync,statSync:fs86.statSync,createHash:crypto13.createHash.bind(crypto13)};function computeContentHash2(content){return _internals111.createHash("sha256").update(content,"utf-8").digest("hex")}function createEmptyContextMap(){return{schema_version:1,generated_at:new Date().toISOString(),repo_fingerprint:"",files:{},task_history:{},decisions:[]}}function loadContextMap(directory){let filePath=path166.join(directory,".swarm","context-map.json");try{if(!_internals111.existsSync(filePath))return null;let raw=_internals111.readFileSync(filePath,"utf-8"),parsed=JSON.parse(raw);if(typeof parsed!=="object"||parsed===null||parsed.schema_version!==1)return null;return parsed}catch{return null}}function saveContextMap(map3,directory){let swarmDir=path166.join(directory,".swarm"),tmpPath=path166.join(swarmDir,"context-map.tmp"),finalPath=path166.join(swarmDir,"context-map.json");_internals111.mkdirSync(swarmDir,{recursive:!0});let updated={...map3,generated_at:new Date().toISOString()},json3=JSON.stringify(updated,null,2);_internals111.writeFileSync(tmpPath,json3,"utf-8"),_internals111.renameSync(tmpPath,finalPath)}function appendTaskHistory(map3,summary){return{...map3,task_history:{...map3.task_history,[summary.task_id]:summary}}}function appendDecision(map3,decision){return{...map3,decisions:[...map3.decisions,decision]}}var EXTENSION_LANGUAGE_MAP={".ts":"typescript",".tsx":"typescript",".js":"javascript",".jsx":"javascript",".mjs":"javascript",".py":"python",".rs":"rust",".go":"go",".json":"json",".md":"markdown",".yaml":"yaml",".yml":"yaml",".css":"css",".scss":"scss",".html":"html",".sh":"shell",".bash":"shell",".ps1":"powershell"};function detectLanguage(filePath){let ext=path167.extname(filePath).toLowerCase();return EXTENSION_LANGUAGE_MAP[ext]}var RE_EXPORT_NAMED=/export\s+(?:function|class|interface|type|const|let|var|enum)\s+(\w+)/g,RE_EXPORT_BRACE=/export\s*\{\s*([\w,\s]+)\s*\}/g,RE_IMPORT_FROM=/import\s+.*?\s+from\s+['"](.+?)['"]/g,RE_IMPORT_REQUIRE=/require\(\s*['"](.+?)['"]\s*\)/g,RE_FIRST_COMMENT=/\/\*(.+?)\*\//s,MAX_KEY_SYMBOLS=10,MAX_PURPOSE_LENGTH=200;function extractFileSummary(filePath,content,absolutePath2,existingEntry){let contentHash=computeContentHash2(content),language=detectLanguage(filePath),exportsList=extractExports(content),importsList=extractImports5(content),purpose=extractPurpose(content),keySymbols=exportsList.slice(0,MAX_KEY_SYMBOLS),mtimeMs=0;if(absolutePath2)try{mtimeMs=fs87.statSync(absolutePath2).mtimeMs}catch{}let base={path:filePath,content_hash:contentHash,mtime_ms:mtimeMs,language,purpose,exports:exportsList.length>0?exportsList:void 0,imports:importsList.length>0?importsList:void 0,key_symbols:keySymbols.length>0?keySymbols:void 0,summary:purpose};if(existingEntry)return{...base,invariants:existingEntry.invariants,risks:existingEntry.risks,tests:existingEntry.tests,last_seen_task_ids:existingEntry.last_seen_task_ids};return base}function isFileStale(entry,currentContent){let currentHash=computeContentHash2(currentContent);return entry.content_hash!==currentHash}function extractExports(content){let symbols=[],namedRe=new RegExp(RE_EXPORT_NAMED.source,"g"),match;match=namedRe.exec(content);while(match!==null)symbols.push(match[1]),match=namedRe.exec(content);let braceRe=new RegExp(RE_EXPORT_BRACE.source,"g");match=braceRe.exec(content);while(match!==null){let list=match[1];for(let name of list.split(",")){let trimmed=name.trim();if(trimmed)symbols.push(trimmed)}match=braceRe.exec(content)}return symbols}function extractImports5(content){let specifiers=[],fromRe=new RegExp(RE_IMPORT_FROM.source,"g"),match;match=fromRe.exec(content);while(match!==null)specifiers.push(match[1]),match=fromRe.exec(content);let requireRe=new RegExp(RE_IMPORT_REQUIRE.source,"g");match=requireRe.exec(content);while(match!==null)specifiers.push(match[1]),match=requireRe.exec(content);return specifiers}function extractPurpose(content){let match=RE_FIRST_COMMENT.exec(content);if(!match)return"No summary available";let body=match[1].split(`
5394
- `).map((line)=>line.replace(/^\s*\*\s?/,"").trim()).join(" ").replace(/\s+/g," ").trim();if(body.length>MAX_PURPOSE_LENGTH)body=`${body.substring(0,MAX_PURPOSE_LENGTH)}...`;return body||"No summary available"}var decisionCounter=0;function nextDecisionId(){return decisionCounter+=1,`A${decisionCounter}`}function deriveFinalStatus(params){if(params.rejection_reasons&&params.rejection_reasons.length>0)return"rejected";switch(params.final_status){case"completed":return"approved";case"failed":return"rejected";case"blocked":return"blocked";case"cancelled":return"rejected"}}function readFileContent(absolutePath2){try{if(!_internals112.existsSync(absolutePath2))return null;return _internals112.readFileSync(absolutePath2,"utf-8")}catch{return null}}function refreshFileEntry(relativePath2,absolutePath2,existingEntry){let content=readFileContent(absolutePath2);if(content===null)return null;return _internals112.extractFileSummary(relativePath2,content,absolutePath2,existingEntry)}var _internals112={loadContextMap,saveContextMap,createEmptyContextMap,extractFileSummary,existsSync:fs88.existsSync,readFileSync:fs88.readFileSync,readdirSync:fs88.readdirSync,realpathSync:fs88.realpathSync,appendTaskHistory,appendDecision};function extractEvidenceFindings(taskId,directory){let result={rejection_reasons:[],review_findings:[]};try{let evidenceDir=path168.join(directory,".swarm","evidence",taskId);if(!_internals112.existsSync(evidenceDir))return result;let evidenceFiles=_internals112.readdirSync(evidenceDir),targetFiles=["evidence.json","reviewer.json","test-engineer.json","test_engineer.json"];for(let fileName of evidenceFiles){if(!targetFiles.includes(fileName))continue;let filePath=path168.join(evidenceDir,fileName),content=readFileContent(filePath);if(content===null)continue;try{let parsed=JSON.parse(content);if(typeof parsed!=="object"||parsed===null||Array.isArray(parsed))continue;let obj=parsed;if(Array.isArray(obj.entries))for(let entry of obj.entries){if(typeof entry!=="object"||entry===null||Array.isArray(entry))continue;let entryObj=entry,entryType=String(entryObj.type??"").toLowerCase(),isActionable=entryType==="review"||entryType==="test"||entryType==="reviewer"||entryType==="test_engineer"||entryType==="test-engineer";if(isActionable&&typeof entryObj.verdict==="string"){let normalizedVerdict=String(entryObj.verdict).toLowerCase();if(normalizedVerdict==="rejected"||normalizedVerdict==="fail"||normalizedVerdict==="concerns")result.rejection_reasons.push(`[${fileName.replace(".json","")}] ${entryObj.verdict}`)}if(isActionable){let entryIssues=entryObj.issues||entryObj.findings||[];if(Array.isArray(entryIssues))for(let issue3 of entryIssues){let issueText=typeof issue3==="object"&&issue3!==null?String(issue3.message||issue3.detail||issue3.description||""):String(issue3);if(issueText)result.review_findings.push(issueText)}let entryFailures=entryObj.failures;if(Array.isArray(entryFailures))for(let failure of entryFailures){let failureText=typeof failure==="object"&&failure!==null?String(failure.message||failure.detail||String(failure)):String(failure);if(failureText)result.review_findings.push(failureText)}}}else{if(typeof obj.verdict==="string"){let normalizedVerdict=String(obj.verdict).toLowerCase();if(normalizedVerdict==="rejected"||normalizedVerdict==="fail"||normalizedVerdict==="concerns")result.rejection_reasons.push(`[${fileName.replace(".json","")}] ${obj.verdict}`)}if(Array.isArray(obj.issues))for(let issue3 of obj.issues){let issueText=typeof issue3==="object"&&issue3!==null?String(issue3.message||issue3.detail||issue3.description||""):String(issue3);if(issueText)result.review_findings.push(issueText)}if(Array.isArray(obj.findings)){for(let finding of obj.findings)if(typeof finding==="object"&&finding!==null){let findingText=String(finding.message||finding.detail||finding.description||"");if(findingText)result.review_findings.push(findingText)}}}}catch{}}}catch{}return result}function updateContextMapAfterAgent(params){try{let map3=_internals112.loadContextMap(params.directory);if(map3===null)map3=_internals112.createEmptyContextMap();let root=path168.resolve(params.directory),updatedFiles={...map3.files},validFiles=[],realRoot=_internals112.realpathSync(root);for(let filePath of params.files_touched)try{let resolved=path168.resolve(root,filePath),realResolved=_internals112.realpathSync(resolved),relative32=path168.relative(realRoot,realResolved);if(relative32.startsWith("..")||path168.isAbsolute(relative32))continue;let normalizedRelative=relative32.replace(/\\/g,"/"),existingEntry=map3.files[normalizedRelative],refreshed=refreshFileEntry(normalizedRelative,resolved,existingEntry);if(refreshed!==null)updatedFiles[normalizedRelative]=refreshed;validFiles.push(normalizedRelative)}catch{}map3={...map3,files:updatedFiles};let evidenceFindings=extractEvidenceFindings(params.task_id,params.directory),rejectionReasons=params.rejection_reasons??[],reviewFindings=params.review_findings??[],mergedRejectionReasons=[...rejectionReasons,...evidenceFindings.rejection_reasons.filter((r)=>!rejectionReasons.includes(r))],mergedReviewFindings=[...reviewFindings,...evidenceFindings.review_findings.filter((f)=>!reviewFindings.includes(f))],reviewerFindings=[...mergedRejectionReasons.map((r)=>`[rejection] ${r}`),...mergedReviewFindings],taskSummary={task_id:params.task_id,goal:params.task_goal,files_touched:validFiles,implementation_summary:params.implementation_summary,reviewer_findings:reviewerFindings.length>0?reviewerFindings:void 0,final_status:mergedRejectionReasons.length>0?"rejected":deriveFinalStatus(params)};if(map3=_internals112.appendTaskHistory(map3,taskSummary),params.decisions)for(let entry of params.decisions){let decision={id:nextDecisionId(),decision:entry.decision,rationale:entry.rationale,timestamp:new Date().toISOString(),task_id:params.task_id};map3=_internals112.appendDecision(map3,decision)}return _internals112.saveContextMap(map3,params.directory),map3}catch{try{return _internals112.loadContextMap(params.directory)??_internals112.createEmptyContextMap()}catch{return _internals112.createEmptyContextMap()}}}init_logger();init_provider_error_classification();var READ_ONLY_TOOLS={write:!1,edit:!1,patch:!1,bash:!1,task:!1,todowrite:!1};function parseRequestedModel(modelId){if(modelId==="configured")return;let separator=modelId.indexOf("/");if(separator<=0||separator===modelId.length-1)throw Error("explicit evaluation models must use provider/model syntax");return{providerID:modelId.slice(0,separator),modelID:modelId.slice(separator+1)}}function resolveEvaluationAgentName(agents,logicalName,preferredSwarm){let names=agents.map((agent)=>agent.name);if(preferredSwarm){let preferred=`${preferredSwarm}_${logicalName}`;if(names.includes(preferred))return preferred;throw Error(`preferred swarm ${preferredSwarm} does not provide evaluation agent ${logicalName}`)}if(names.includes(logicalName))return logicalName;let prefixed=names.filter((name)=>name.endsWith(`_${logicalName}`)).sort((left,right)=>left.localeCompare(right));if(prefixed.length===1)return prefixed[0];if(prefixed.length>1)throw Error(`multiple swarms provide ${logicalName}; preferredSwarm is required`);throw Error(`evaluation agent ${logicalName} is not registered`)}async function boundedDelete(client,sessionId,timeoutMs=500){let controller=new AbortController,timer;try{if(await Promise.race([client.session.delete({path:{id:sessionId},signal:controller.signal}).then(()=>"deleted"),new Promise((resolve61)=>{timer=setTimeout(()=>{controller.abort(),resolve61("timed-out")},timeoutMs)})])==="timed-out")_internals113.log("evaluation session cleanup timed out",{sessionId,timeoutMs})}catch(error93){_internals113.log("evaluation session cleanup failed",{sessionId,error:error93 instanceof Error?error93.message:String(error93)})}finally{if(timer)clearTimeout(timer);controller.abort()}}var _internals113={boundedDelete,log};function createEvaluationModelDispatcher(client){return async(request)=>{let startedAt=Date.now();if(request.abortSignal?.aborted)return{status:"cancelled",modelId:request.modelId,text:"",durationMs:0};let sessionId,resolvedAgentName,controller=new AbortController,timedOut=!1,abortListener=()=>controller.abort();request.abortSignal?.addEventListener("abort",abortListener,{once:!0});let timeoutHandle=setTimeout(()=>{timedOut=!0,controller.abort()},request.timeoutMs);try{let operation=async()=>{let requestedModel=parseRequestedModel(request.modelId),agentsResult=await client.app.agents({query:{directory:request.directory},signal:controller.signal});if(!agentsResult.data)throw Error("Failed to list registered evaluation agents");if(resolvedAgentName=resolveEvaluationAgentName(agentsResult.data,request.agentName,request.preferredSwarm),sessionId=(await client.session.create({body:{...request.parentSessionId?{parentID:request.parentSessionId}:{},title:`evaluation gate (${resolvedAgentName})`},query:{directory:request.directory},signal:controller.signal})).data?.id,!sessionId)throw Error("Failed to create evaluation session");let response=await client.session.prompt({path:{id:sessionId},body:{agent:resolvedAgentName,...requestedModel?{model:requestedModel}:{},...request.system?{system:request.system}:{},tools:READ_ONLY_TOOLS,parts:[{type:"text",text:request.prompt}]},signal:controller.signal});if(!response.data)throw Error("Evaluation session returned no data");let text=response.data.parts.filter((part)=>part.type==="text").map((part)=>part.text??"").join(`
5395
- `);if(Buffer.byteLength(text,"utf8")>65536)throw Error("Evaluation model output exceeded 65536 bytes");let actualModel=response.data.info;return{status:"completed",modelId:actualModel.providerID&&actualModel.modelID?`${actualModel.providerID}/${actualModel.modelID}`:request.modelId,agentName:resolvedAgentName,text,durationMs:Date.now()-startedAt}},maxSameModelRetries=2;for(let attempt=0;;attempt++)try{return await Promise.race([operation(),new Promise((_,reject)=>{controller.signal.addEventListener("abort",()=>reject(Error("evaluation dispatch aborted")),{once:!0})})])}catch(error93){let cancelled=request.abortSignal?.aborted===!0,msg=error93 instanceof Error?error93.message:String(error93);if(!(!cancelled&&!timedOut&&attempt<2&&isTransientProviderError(msg)))return{status:cancelled?"cancelled":timedOut?"timeout":"error",modelId:request.modelId,agentName:resolvedAgentName,text:"",durationMs:Date.now()-startedAt,error:isQuotaError(msg)?`${msg} (model quota/usage limit; retried the same model ${attempt} time(s) — not substituted, to preserve benchmark attribution)`:msg};if(sessionId)await _internals113.boundedDelete(client,sessionId),sessionId=void 0}}finally{if(clearTimeout(timeoutHandle),request.abortSignal?.removeEventListener("abort",abortListener),controller.abort(),sessionId)await _internals113.boundedDelete(client,sessionId)}}}init_constants();init_schema();init_logger();init_critic();init_agents2();init_schema();init_utils2();init_file_locks();init_state2();init_telemetry();init_bun_compat();init_logger();import*as fs89 from"node:fs";import*as path169 from"node:path";function parseModelString(model){if(!model||!model.trim())return;let separator=model.indexOf("/");if(separator<=0||separator===model.length-1)throw Error(`fallback model must use provider/model syntax, got: "${model}"`);return{providerID:model.slice(0,separator),modelID:model.slice(separator+1)}}var defaultBackoff=(retryAttempt)=>2**(retryAttempt-1)*1000,defaultSleep=(ms)=>new Promise((resolve61)=>setTimeout(resolve61,ms));async function dispatchWithModelFallback(opts){let maxRetries=Math.max(0,opts.maxTransientRetriesPerModel??1),backoff=opts.backoffMs??defaultBackoff,sleep3=opts.sleep??defaultSleep,attempts=0,lastError,anyDispatched=!1;for(let fallbackIndex=0;;fallbackIndex++){let model,modelUsed;if(fallbackIndex>0){let fbStr=opts.resolveFallback(fallbackIndex);if(fbStr===null)break;try{model=parseModelString(fbStr)}catch{continue}modelUsed=fbStr,opts.onFallback?.({toModel:fbStr,fallbackIndex})}for(let retry=0;retry<=maxRetries;retry++){attempts++,anyDispatched=!0;try{return{result:await opts.dispatch(model),modelUsed,fallbackIndex,attempts}}catch(err){if(lastError=err,opts.classify(err)==="permanent")throw err;if(retry<maxRetries)await sleep3(backoff(retry+1))}}}throw lastError??Error(anyDispatched?"dispatchWithModelFallback: all models exhausted":"dispatchWithModelFallback: no dispatch attempted")}init_provider_error_classification();var KNOWN_FIELDS=new Set(["VERDICT","REASONING","EVIDENCE_CHECKED","ANTI_PATTERNS_DETECTED","ESCALATION_NEEDED"]),DEFAULT_VALID_VERDICTS=["APPROVED","NEEDS_REVISION","REJECTED","BLOCKED","ANSWER","ESCALATE_TO_HUMAN","REPHRASE","PENDING"];function parseCriticResponseFields(rawResponse,options={}){let validVerdicts=options.validVerdicts??DEFAULT_VALID_VERDICTS,result={verdict:"NEEDS_REVISION",reasoning:"",evidenceChecked:[],antiPatternsDetected:[],escalationNeeded:!1,rawResponse},lines=rawResponse.split(`
5394
+ `).map((line)=>line.replace(/^\s*\*\s?/,"").trim()).join(" ").replace(/\s+/g," ").trim();if(body.length>MAX_PURPOSE_LENGTH)body=`${body.substring(0,MAX_PURPOSE_LENGTH)}...`;return body||"No summary available"}var decisionCounter=0;function nextDecisionId(){return decisionCounter+=1,`A${decisionCounter}`}function deriveFinalStatus(params){if(params.rejection_reasons&&params.rejection_reasons.length>0)return"rejected";switch(params.final_status){case"completed":return"approved";case"failed":return"rejected";case"blocked":return"blocked";case"cancelled":return"rejected"}}function readFileContent(absolutePath2){try{if(!_internals112.existsSync(absolutePath2))return null;return _internals112.readFileSync(absolutePath2,"utf-8")}catch{return null}}function refreshFileEntry(relativePath2,absolutePath2,existingEntry){let content=readFileContent(absolutePath2);if(content===null)return null;return _internals112.extractFileSummary(relativePath2,content,absolutePath2,existingEntry)}var _internals112={loadContextMap,saveContextMap,createEmptyContextMap,extractFileSummary,existsSync:fs88.existsSync,readFileSync:fs88.readFileSync,readdirSync:fs88.readdirSync,realpathSync:fs88.realpathSync,appendTaskHistory,appendDecision};function extractEvidenceFindings(taskId,directory){let result={rejection_reasons:[],review_findings:[]};try{let evidenceDir=path168.join(directory,".swarm","evidence",taskId);if(!_internals112.existsSync(evidenceDir))return result;let evidenceFiles=_internals112.readdirSync(evidenceDir),targetFiles=["evidence.json","reviewer.json","test-engineer.json","test_engineer.json"];for(let fileName of evidenceFiles){if(!targetFiles.includes(fileName))continue;let filePath=path168.join(evidenceDir,fileName),content=readFileContent(filePath);if(content===null)continue;try{let parsed=JSON.parse(content);if(typeof parsed!=="object"||parsed===null||Array.isArray(parsed))continue;let obj=parsed;if(Array.isArray(obj.entries))for(let entry of obj.entries){if(typeof entry!=="object"||entry===null||Array.isArray(entry))continue;let entryObj=entry,entryType=String(entryObj.type??"").toLowerCase(),isActionable=entryType==="review"||entryType==="test"||entryType==="reviewer"||entryType==="test_engineer"||entryType==="test-engineer";if(isActionable&&typeof entryObj.verdict==="string"){let normalizedVerdict=String(entryObj.verdict).toLowerCase();if(normalizedVerdict==="rejected"||normalizedVerdict==="fail"||normalizedVerdict==="concerns")result.rejection_reasons.push(`[${fileName.replace(".json","")}] ${entryObj.verdict}`)}if(isActionable){let entryIssues=entryObj.issues||entryObj.findings||[];if(Array.isArray(entryIssues))for(let issue3 of entryIssues){let issueText=typeof issue3==="object"&&issue3!==null?String(issue3.message||issue3.detail||issue3.description||""):String(issue3);if(issueText)result.review_findings.push(issueText)}let entryFailures=entryObj.failures;if(Array.isArray(entryFailures))for(let failure of entryFailures){let failureText=typeof failure==="object"&&failure!==null?String(failure.message||failure.detail||String(failure)):String(failure);if(failureText)result.review_findings.push(failureText)}}}else{if(typeof obj.verdict==="string"){let normalizedVerdict=String(obj.verdict).toLowerCase();if(normalizedVerdict==="rejected"||normalizedVerdict==="fail"||normalizedVerdict==="concerns")result.rejection_reasons.push(`[${fileName.replace(".json","")}] ${obj.verdict}`)}if(Array.isArray(obj.issues))for(let issue3 of obj.issues){let issueText=typeof issue3==="object"&&issue3!==null?String(issue3.message||issue3.detail||issue3.description||""):String(issue3);if(issueText)result.review_findings.push(issueText)}if(Array.isArray(obj.findings)){for(let finding of obj.findings)if(typeof finding==="object"&&finding!==null){let findingText=String(finding.message||finding.detail||finding.description||"");if(findingText)result.review_findings.push(findingText)}}}}catch{}}}catch{}return result}function updateContextMapAfterAgent(params){try{let map3=_internals112.loadContextMap(params.directory);if(map3===null)map3=_internals112.createEmptyContextMap();let root=path168.resolve(params.directory),updatedFiles={...map3.files},validFiles=[],realRoot=_internals112.realpathSync(root);for(let filePath of params.files_touched)try{let resolved=path168.resolve(root,filePath),realResolved=_internals112.realpathSync(resolved),relative32=path168.relative(realRoot,realResolved);if(relative32.startsWith("..")||path168.isAbsolute(relative32))continue;let normalizedRelative=relative32.replace(/\\/g,"/"),existingEntry=map3.files[normalizedRelative],refreshed=refreshFileEntry(normalizedRelative,resolved,existingEntry);if(refreshed!==null)updatedFiles[normalizedRelative]=refreshed;validFiles.push(normalizedRelative)}catch{}map3={...map3,files:updatedFiles};let evidenceFindings=extractEvidenceFindings(params.task_id,params.directory),rejectionReasons=params.rejection_reasons??[],reviewFindings=params.review_findings??[],mergedRejectionReasons=[...rejectionReasons,...evidenceFindings.rejection_reasons.filter((r)=>!rejectionReasons.includes(r))],mergedReviewFindings=[...reviewFindings,...evidenceFindings.review_findings.filter((f)=>!reviewFindings.includes(f))],reviewerFindings=[...mergedRejectionReasons.map((r)=>`[rejection] ${r}`),...mergedReviewFindings],taskSummary={task_id:params.task_id,goal:params.task_goal,files_touched:validFiles,implementation_summary:params.implementation_summary,reviewer_findings:reviewerFindings.length>0?reviewerFindings:void 0,final_status:mergedRejectionReasons.length>0?"rejected":deriveFinalStatus(params)};if(map3=_internals112.appendTaskHistory(map3,taskSummary),params.decisions)for(let entry of params.decisions){let decision={id:nextDecisionId(),decision:entry.decision,rationale:entry.rationale,timestamp:new Date().toISOString(),task_id:params.task_id};map3=_internals112.appendDecision(map3,decision)}return _internals112.saveContextMap(map3,params.directory),map3}catch{try{return _internals112.loadContextMap(params.directory)??_internals112.createEmptyContextMap()}catch{return _internals112.createEmptyContextMap()}}}init_logger();init_provider_error_classification();var READ_ONLY_TOOLS={write:!1,edit:!1,patch:!1,bash:!1,task:!1,todowrite:!1};function parseRequestedModel(modelId){if(modelId==="configured")return;let separator=modelId.indexOf("/");if(separator<=0||separator===modelId.length-1)throw Error("explicit evaluation models must use provider/model syntax");return{providerID:modelId.slice(0,separator),modelID:modelId.slice(separator+1)}}function resolveEvaluationAgentName(agents,logicalName,preferredSwarm){let names=agents.map((agent)=>agent.name);if(preferredSwarm){let preferred=`${preferredSwarm}_${logicalName}`;if(names.includes(preferred))return preferred;throw Error(`preferred swarm ${preferredSwarm} does not provide evaluation agent ${logicalName}`)}if(names.includes(logicalName))return logicalName;let prefixed=names.filter((name)=>name.endsWith(`_${logicalName}`)).sort((left,right)=>left.localeCompare(right));if(prefixed.length===1)return prefixed[0];if(prefixed.length>1)throw Error(`multiple swarms provide ${logicalName}; preferredSwarm is required`);throw Error(`evaluation agent ${logicalName} is not registered`)}async function boundedDelete(client,sessionId,timeoutMs=500){let controller=new AbortController,timer;try{if(await Promise.race([client.session.delete({path:{id:sessionId},signal:controller.signal}).then(()=>"deleted"),new Promise((resolve61)=>{timer=setTimeout(()=>{controller.abort(),resolve61("timed-out")},timeoutMs)})])==="timed-out")_internals113.log("evaluation session cleanup timed out",{sessionId,timeoutMs})}catch(error93){_internals113.log("evaluation session cleanup failed",{sessionId,error:error93 instanceof Error?error93.message:String(error93)})}finally{if(timer)clearTimeout(timer);controller.abort()}}var _internals113={boundedDelete,log};function createEvaluationModelDispatcher(client){return async(request)=>{let startedAt=Date.now();if(request.abortSignal?.aborted)return{status:"cancelled",modelId:request.modelId,text:"",durationMs:0};let sessionId,resolvedAgentName,controller=new AbortController,timedOut=!1,abortListener=()=>controller.abort();request.abortSignal?.addEventListener("abort",abortListener,{once:!0});let timeoutHandle=setTimeout(()=>{timedOut=!0,controller.abort()},request.timeoutMs);try{let operation=async()=>{let requestedModel=parseRequestedModel(request.modelId),agentsResult=await client.app.agents({query:{directory:request.directory},signal:controller.signal});if(!agentsResult.data)throw Error("Failed to list registered evaluation agents");if(resolvedAgentName=resolveEvaluationAgentName(agentsResult.data,request.agentName,request.preferredSwarm),sessionId=(await client.session.create({body:{...request.parentSessionId?{parentID:request.parentSessionId}:{},title:`evaluation gate (${resolvedAgentName})`},query:{directory:request.directory},signal:controller.signal})).data?.id,!sessionId)throw Error("Failed to create evaluation session");let response=await client.session.prompt({path:{id:sessionId},body:{agent:resolvedAgentName,...requestedModel?{model:requestedModel}:{},...request.system?{system:request.system}:{},tools:READ_ONLY_TOOLS,parts:[{type:"text",text:request.prompt}]},signal:controller.signal});if(!response.data)throw Error(`Evaluation session returned no data: ${JSON.stringify(response.error)}`);let text=response.data.parts.filter((part)=>part.type==="text").map((part)=>part.text??"").join(`
5395
+ `);if(Buffer.byteLength(text,"utf8")>65536)throw Error("Evaluation model output exceeded 65536 bytes");let actualModel=response.data.info;return{status:"completed",modelId:actualModel.providerID&&actualModel.modelID?`${actualModel.providerID}/${actualModel.modelID}`:request.modelId,agentName:resolvedAgentName,text,durationMs:Date.now()-startedAt}},maxSameModelRetries=2;for(let attempt=0;;attempt++)try{return await Promise.race([operation(),new Promise((_,reject)=>{controller.signal.addEventListener("abort",()=>reject(Error("evaluation dispatch aborted")),{once:!0})})])}catch(error93){let cancelled=request.abortSignal?.aborted===!0,msg=error93 instanceof Error?error93.message:String(error93);if(!(!cancelled&&!timedOut&&attempt<2&&isTransientProviderError(msg)))return{status:cancelled?"cancelled":timedOut?"timeout":"error",modelId:request.modelId,agentName:resolvedAgentName,text:"",durationMs:Date.now()-startedAt,error:isQuotaError(msg)?`${msg} (model quota/usage limit; retried the same model ${attempt} time(s) — not substituted, to preserve benchmark attribution)`:msg};if(sessionId)await _internals113.boundedDelete(client,sessionId),sessionId=void 0}}finally{if(clearTimeout(timeoutHandle),request.abortSignal?.removeEventListener("abort",abortListener),controller.abort(),sessionId)await _internals113.boundedDelete(client,sessionId)}}}init_constants();init_schema();init_logger();init_critic();init_agents2();init_schema();init_utils2();init_file_locks();init_state2();init_telemetry();init_bun_compat();import*as fs89 from"node:fs";import*as path169 from"node:path";function parseModelString(model){if(!model||!model.trim())return;let separator=model.indexOf("/");if(separator<=0||separator===model.length-1)throw Error(`fallback model must use provider/model syntax, got: "${model}"`);return{providerID:model.slice(0,separator),modelID:model.slice(separator+1)}}var defaultBackoff=(retryAttempt)=>2**(retryAttempt-1)*1000,defaultSleep=(ms)=>new Promise((resolve61)=>setTimeout(resolve61,ms));async function dispatchWithModelFallback(opts){let maxRetries=Math.max(0,opts.maxTransientRetriesPerModel??1),backoff=opts.backoffMs??defaultBackoff,sleep3=opts.sleep??defaultSleep,attempts=0,lastError,anyDispatched=!1;for(let fallbackIndex=0;;fallbackIndex++){let model,modelUsed;if(fallbackIndex>0){let fbStr=opts.resolveFallback(fallbackIndex);if(fbStr===null)break;try{model=parseModelString(fbStr)}catch{continue}modelUsed=fbStr,opts.onFallback?.({toModel:fbStr,fallbackIndex})}for(let retry=0;retry<=maxRetries;retry++){attempts++,anyDispatched=!0;try{return{result:await opts.dispatch(model),modelUsed,fallbackIndex,attempts}}catch(err){if(lastError=err,opts.classify(err)==="permanent")throw err;if(retry<maxRetries)await sleep3(backoff(retry+1))}}}throw lastError??Error(anyDispatched?"dispatchWithModelFallback: all models exhausted":"dispatchWithModelFallback: no dispatch attempted")}init_provider_error_classification();function advanceInlineFallback(opts){let nextModel=opts.resolveFallback(opts.index+1);if(!nextModel)return{nextIndex:opts.index,adopted:null};let advancedIndex=opts.index+1,parsed;try{parsed=parseModelString(nextModel)}catch{parsed=void 0}if(!parsed)return{nextIndex:advancedIndex,adopted:null};let reason=isQuotaError(opts.lastError instanceof Error?opts.lastError.message:String(opts.lastError))?"quota":"transient_model_error";return opts.onAdopt({toModel:nextModel,fallbackIndex:advancedIndex,reason}),{nextIndex:advancedIndex,adopted:{modelString:nextModel,override:parsed}}}init_logger();init_provider_error_classification();var KNOWN_FIELDS=new Set(["VERDICT","REASONING","EVIDENCE_CHECKED","ANTI_PATTERNS_DETECTED","ESCALATION_NEEDED"]),DEFAULT_VALID_VERDICTS=["APPROVED","NEEDS_REVISION","REJECTED","BLOCKED","ANSWER","ESCALATE_TO_HUMAN","REPHRASE","PENDING"];function parseCriticResponseFields(rawResponse,options={}){let validVerdicts=options.validVerdicts??DEFAULT_VALID_VERDICTS,result={verdict:"NEEDS_REVISION",reasoning:"",evidenceChecked:[],antiPatternsDetected:[],escalationNeeded:!1,rawResponse},lines=rawResponse.split(`
5396
5396
  `),currentKey="",currentValue="",commitField=(res,key,value)=>{switch(key){case"VERDICT":{let normalized=value.trim().toUpperCase().replace(/[`*]/g,"");if(validVerdicts.includes(normalized))res.verdict=normalized;else options.onUnknownVerdict?.(value),res.verdict="NEEDS_REVISION";break}case"REASONING":res.reasoning=value.trim();break;case"EVIDENCE_CHECKED":if(value&&value!=="none"&&value!=='"none"')res.evidenceChecked=value.split(",").map((s)=>s.trim()).filter(Boolean);break;case"ANTI_PATTERNS_DETECTED":if(value&&value!=="none"&&value!=='"none"')res.antiPatternsDetected=value.split(",").map((s)=>s.trim()).filter(Boolean);break;case"ESCALATION_NEEDED":res.escalationNeeded=value.trim().toUpperCase()==="YES";break}};for(let line of lines){let colonIndex=line.indexOf(":");if(colonIndex!==-1){let key=line.slice(0,colonIndex).trim().toUpperCase();if(KNOWN_FIELDS.has(key)){if(currentKey)commitField(result,currentKey,currentValue);currentKey=key,currentValue=line.slice(colonIndex+1).trim()}else currentValue+=`
5397
5397
  ${line}`}else if(line.trim())currentValue+=`
5398
5398
  ${line}`}if(currentKey)commitField(result,currentKey,currentValue);return result}init_state3();var oversightSequenceCounter=0;function parseFullAutoCriticResponse(rawResponse){return parseCriticResponseFields(rawResponse,{onUnknownVerdict:(value)=>{warn(`[full-auto/oversight] Unknown verdict '${value}' — defaulting to NEEDS_REVISION`)}})}function buildOversightPrompt(input){let{trigger,triggerSource,phase,taskID,architectOutput,actionContext}=input,archBlock=architectOutput?`
@@ -5413,7 +5413,7 @@ ${ctxJSON.length>3000?`${ctxJSON.slice(0,3000)}
5413
5413
  REASONING: Critic returned empty response
5414
5414
  EVIDENCE_CHECKED: none
5415
5415
  ANTI_PATTERNS_DETECTED: empty_response
5416
- ESCALATION_NEEDED: NO`,error:void 0};return{ok:!0,response,error:void 0}}}}catch(err){lastError2=err}return{ok:!1,response:"",error:lastError2}}let lastError;for(let attempt=0;attempt<=maxRetries;attempt++){let result=await attemptDispatch(attempt,modelOverride);if(result.ok){criticResponse=result.response,dispatchError=void 0;break}if(lastError=result.error,dispatchFailureWasTransient=isTransientDispatchError(lastError),warn(`[full-auto/oversight] dispatch attempt ${attempt+1}/${maxRetries+1} failed: ${lastError instanceof Error?lastError.message:String(lastError)}`),dispatchFailureWasTransient&&attempt<maxRetries){dispatchError=void 0;let nextModel=resolveOversightFallback(modelFallbackIndex+1);if(nextModel){modelFallbackIndex++;let parsed2;try{parsed2=parseModelString(nextModel)}catch{parsed2=void 0}if(parsed2){modelOverride=parsed2,modelUsedLabel=nextModel;let reason=isQuotaError(lastError instanceof Error?lastError.message:String(lastError))?"quota":"transient_model_error";warn(`[full-auto/oversight] failing over critic to fallback model "${nextModel}" (fallback ${modelFallbackIndex}, reason=${reason})`),telemetry.modelFallback(input.sessionID,input.oversightAgentName,input.criticModel,nextModel,reason)}}}else{dispatchError=lastError;break}}if(cleanup(),modelFallbackIndex>0)baseEvent.critic_model=modelUsedLabel;if(dispatchError){let infraReason=dispatchFailureWasTransient?`oversight infrastructure failure after ${maxRetries+1} attempt(s): ${dispatchError instanceof Error?dispatchError.message:String(dispatchError)}`:`oversight dispatch failed without retry: ${dispatchError instanceof Error?dispatchError.message:String(dispatchError)}`,consecutive=0;if(dispatchFailureWasTransient)consecutive=incrementOversightFailureCounter(input.directory,input.sessionID);else resetOversightFailureCounter(input.directory,input.sessionID);if(consecutive>=maxConsecutiveFailures&&maxConsecutiveFailures>0){let degradeReason=`auto-degraded to manual mode after ${consecutive} consecutive oversight infrastructure failures`;terminateFullAutoRun(input.directory,input.sessionID,degradeReason),error48(`[full-auto/oversight] ${degradeReason}`);let event3={...baseEvent,verdict:"BLOCKED",reasoning:infraReason,decision:"pause",full_auto_status_after:"terminated"};await writeFullAutoOversightEvent(input.directory,event3);let evidencePath3=await writeFullAutoOversightEvidence(input.directory,input.phase,event3);return recordFullAutoOversight(input.directory,input.sessionID,"BLOCKED",infraReason),{verdict:"BLOCKED",reasoning:infraReason,evidenceChecked:[],antiPatternsDetected:[],escalationNeeded:!1,rawResponse:"",decision:"pause",event:event3,evidencePath:evidencePath3}}pauseFullAutoRun(input.directory,input.sessionID,infraReason);let event2={...baseEvent,verdict:"BLOCKED",reasoning:infraReason,decision:"pause",full_auto_status_after:"paused"};await writeFullAutoOversightEvent(input.directory,event2);let evidencePath2=await writeFullAutoOversightEvidence(input.directory,input.phase,event2);return recordFullAutoOversight(input.directory,input.sessionID,"BLOCKED",infraReason),{verdict:"BLOCKED",reasoning:infraReason,evidenceChecked:[],antiPatternsDetected:[],escalationNeeded:!1,rawResponse:"",decision:"pause",event:event2,evidencePath:evidencePath2}}resetOversightFailureCounter(input.directory,input.sessionID);let parsed=parseFullAutoCriticResponse(criticResponse),decision=decisionFromVerdict(parsed.verdict,parsed.escalationNeeded),afterStatus=beforeStatus;if(decision==="pause")pauseFullAutoRun(input.directory,input.sessionID,`critic verdict ${parsed.verdict}`),afterStatus="paused";else if(decision==="escalate_human")terminateFullAutoRun(input.directory,input.sessionID,"critic ESCALATE_TO_HUMAN"),afterStatus="terminated";let event={...baseEvent,verdict:parsed.verdict,reasoning:parsed.reasoning,evidence_checked:parsed.evidenceChecked,anti_patterns_detected:parsed.antiPatternsDetected,escalation_needed:parsed.escalationNeeded,decision,full_auto_status_after:afterStatus},failClosed=input.fullAutoConfig?.fail_closed!==!1,persistError,evidencePath;try{await writeFullAutoOversightEvent(input.directory,event)}catch(error93){persistError=error93 instanceof Error?error93.message:String(error93)}if(!persistError)try{evidencePath=await writeFullAutoOversightEvidence(input.directory,input.phase,event)}catch(error93){persistError=error93 instanceof Error?error93.message:String(error93)}if(persistError){if(failClosed)pauseFullAutoRun(input.directory,input.sessionID,`oversight persistence failure: ${persistError}`);let failedEvent={...event,verdict:"BLOCKED",reasoning:`oversight persistence failed: ${persistError}`,decision:"pause",full_auto_status_after:"paused"};try{recordFullAutoOversight(input.directory,input.sessionID,"BLOCKED",`oversight-persistence-failure:${persistError}`)}catch{}return{verdict:"BLOCKED",reasoning:failedEvent.reasoning,evidenceChecked:[],antiPatternsDetected:[],escalationNeeded:!1,rawResponse:criticResponse,decision:"pause",event:failedEvent,evidencePath:void 0}}return recordFullAutoOversight(input.directory,input.sessionID,parsed.verdict,input.trigger),{...parsed,decision,event,evidencePath}}init_state3();function configCadence(config3){let oversight=config3.full_auto?.oversight;return{everyToolCalls:oversight?.every_tool_calls??25,everyArchitectTurns:oversight?.every_architect_turns??5,everyMinutes:oversight?.every_minutes??20}}function denialLimits(config3){return{maxConsecutive:config3.full_auto?.denials?.max_consecutive??3,maxTotal:config3.full_auto?.denials?.max_total??20}}function evaluateFullAutoCadence(state,config3,now=Date.now()){let triggers=[],cadence=configCadence(config3),denials=denialLimits(config3);if(cadence.everyToolCalls>0&&state.counters.toolCalls>0&&state.counters.toolCalls%cadence.everyToolCalls===0)triggers.push({kind:"tool_calls",threshold:cadence.everyToolCalls});if(cadence.everyArchitectTurns>0&&state.counters.architectTurns>0&&state.counters.architectTurns%cadence.everyArchitectTurns===0)triggers.push({kind:"architect_turns",threshold:cadence.everyArchitectTurns});if(cadence.everyMinutes>0&&state.lastOversightAt){let lastTs=Date.parse(state.lastOversightAt);if(Number.isFinite(lastTs)){let elapsedMinutes=(now-lastTs)/60000;if(elapsedMinutes>=cadence.everyMinutes)triggers.push({kind:"minutes",threshold:cadence.everyMinutes,elapsedMinutes})}}if(state.counters.consecutiveNoProgressTurns>=3)triggers.push({kind:"consecutive_no_progress",threshold:3});if(denials.maxConsecutive>1&&state.denialCounters.consecutive>=denials.maxConsecutive-1&&state.denialCounters.consecutive<denials.maxConsecutive)triggers.push({kind:"denials_near_limit",consecutive:state.denialCounters.consecutive,max:denials.maxConsecutive});return{shouldEscalate:triggers.length>0,triggers}}function tickAndEvaluate(directory,sessionID,counter,config3){let before=loadFullAutoRunState(directory,sessionID);if(!before||before.status!=="running")return;let updated=incrementFullAutoCounter(directory,sessionID,counter);if(!updated)return;return evaluateFullAutoCadence(updated,config3)}var cadenceDispatchInFlight=new Set;function resolveOversightAgentName(activeAgent){if(!activeAgent)return"critic_oversight";if(stripKnownSwarmPrefix(activeAgent)!==ORCHESTRATOR_NAME)return"critic_oversight";let lastIdx=activeAgent.toLowerCase().lastIndexOf("architect");if(lastIdx>0)return`${activeAgent.slice(0,lastIdx)}critic_oversight`;return"critic_oversight"}function tickAndMaybeDispatchCadence(directory,sessionID,counter,config3,options={}){let decision=tickAndEvaluate(directory,sessionID,counter,config3);if(!decision||!decision.shouldEscalate)return decision;if(cadenceDispatchInFlight.has(sessionID))return decision;let runState=loadFullAutoRunState(directory,sessionID);if(!runState||runState.status!=="running")return decision;let oversightAgentName=resolveOversightAgentName(options.activeAgent),criticModel=config3.full_auto?.critic_model??config3.agents?.critic?.model??"opencode/big-pickle";return cadenceDispatchInFlight.add(sessionID),(options.dispatch??dispatchFullAutoOversight)({directory,sessionID,trigger:`cadence:${decision.triggers.map((t)=>t.kind).join(",")}`,triggerSource:"cadence",phase:runState.currentPhase,taskID:runState.currentTaskID??void 0,planID:runState.planID,actionContext:{counters:runState.counters,denialCounters:runState.denialCounters,triggers:decision.triggers},criticModel,oversightAgentName,fullAutoConfig:{fail_closed:config3.full_auto?.fail_closed!==!1,max_dispatch_retries:config3.full_auto?.oversight?.max_dispatch_retries??2,max_consecutive_dispatch_failures:config3.full_auto?.oversight?.max_consecutive_dispatch_failures??3}}).catch((err)=>{error48(`[full-auto/cadence] dispatch threw past dispatcher's own fail-closed branches: ${err instanceof Error?err.message:String(err)}`)}).finally(()=>{cadenceDispatchInFlight.delete(sessionID)}),decision}init_state2();init_utils();init_bun_compat();init_realtime_learning_nudge();init_utils2();import{renameSync as renameSync27,unlinkSync as unlinkSync26}from"node:fs";import*as nodePath from"node:path";function createAgentActivityHooks(config3,directory){if(config3.hooks?.agent_activity===!1)return{toolBefore:async()=>{},toolAfter:async()=>{}};return{toolBefore:async(input)=>{swarmState.activeToolCalls.set(input.callID,{tool:input.tool,sessionID:input.sessionID,callID:input.callID,startTime:Date.now()})},toolAfter:async(input,output)=>{let entry=swarmState.activeToolCalls.get(input.callID);if(!entry)return;swarmState.activeToolCalls.delete(input.callID);let duration5=Date.now()-entry.startTime,success3=!((typeof output.success==="boolean"?output.success:void 0)===!1||!!output.error),key=entry.tool,existing=swarmState.toolAggregates.get(key)??{tool:key,count:0,successCount:0,failureCount:0,totalDuration:0};if(existing.count++,success3)existing.successCount++;else existing.failureCount++;if(existing.totalDuration+=duration5,swarmState.toolAggregates.set(key,existing),recordRealtimeLearningToolCall(entry.sessionID),swarmState.pendingEvents++,swarmState.pendingEvents>=20)flushActivityToFile(directory).catch((err)=>warn("Agent activity flush trigger failed:",err))}}}var flushPromise=null;async function flushActivityToFile(directory){if(flushPromise)return flushPromise=flushPromise.then(()=>doFlush(directory)).catch((err)=>{warn("Queued agent activity flush failed:",err)}),flushPromise;flushPromise=doFlush(directory);try{await flushPromise}finally{flushPromise=null}}async function doFlush(directory){try{let existing=await readSwarmFileAsync(directory,"context.md")??"",activitySection=renderActivitySection(),updated=replaceOrAppendSection(existing,"## Agent Activity",activitySection),flushedCount=swarmState.pendingEvents,path170=nodePath.join(directory,".swarm","context.md"),tempPath=`${path170}.tmp`;try{await bunWrite(tempPath,updated),renameSync27(tempPath,path170)}catch(writeError){try{unlinkSync26(tempPath)}catch{}throw writeError}swarmState.pendingEvents=Math.max(0,swarmState.pendingEvents-flushedCount)}catch(error93){warn("Agent activity flush failed:",error93)}}function renderActivitySection(){let lines=["## Agent Activity",""];if(swarmState.toolAggregates.size===0)return lines.push("No tool activity recorded yet."),lines.join(`
5416
+ ESCALATION_NEEDED: NO`,error:void 0};return{ok:!0,response,error:void 0}}}}catch(err){lastError2=err}return{ok:!1,response:"",error:lastError2}}let lastError;for(let attempt=0;attempt<=maxRetries;attempt++){let result=await attemptDispatch(attempt,modelOverride);if(result.ok){criticResponse=result.response,dispatchError=void 0;break}if(lastError=result.error,dispatchFailureWasTransient=isTransientDispatchError(lastError),warn(`[full-auto/oversight] dispatch attempt ${attempt+1}/${maxRetries+1} failed: ${lastError instanceof Error?lastError.message:String(lastError)}`),dispatchFailureWasTransient&&attempt<maxRetries){dispatchError=void 0;let advanced=advanceInlineFallback({resolveFallback:resolveOversightFallback,index:modelFallbackIndex,lastError,onAdopt:({toModel,fallbackIndex,reason})=>{warn(`[full-auto/oversight] failing over critic to fallback model "${toModel}" (fallback ${fallbackIndex}, reason=${reason})`),telemetry.modelFallback(input.sessionID,input.oversightAgentName,input.criticModel,toModel,reason)}});if(modelFallbackIndex=advanced.nextIndex,advanced.adopted)modelOverride=advanced.adopted.override,modelUsedLabel=advanced.adopted.modelString}else{dispatchError=lastError;break}}if(cleanup(),modelFallbackIndex>0)baseEvent.critic_model=modelUsedLabel;if(dispatchError){let infraReason=dispatchFailureWasTransient?`oversight infrastructure failure after ${maxRetries+1} attempt(s): ${dispatchError instanceof Error?dispatchError.message:String(dispatchError)}`:`oversight dispatch failed without retry: ${dispatchError instanceof Error?dispatchError.message:String(dispatchError)}`,consecutive=0;if(dispatchFailureWasTransient)consecutive=incrementOversightFailureCounter(input.directory,input.sessionID);else resetOversightFailureCounter(input.directory,input.sessionID);if(consecutive>=maxConsecutiveFailures&&maxConsecutiveFailures>0){let degradeReason=`auto-degraded to manual mode after ${consecutive} consecutive oversight infrastructure failures`;terminateFullAutoRun(input.directory,input.sessionID,degradeReason),error48(`[full-auto/oversight] ${degradeReason}`);let event3={...baseEvent,verdict:"BLOCKED",reasoning:infraReason,decision:"pause",full_auto_status_after:"terminated"};await writeFullAutoOversightEvent(input.directory,event3);let evidencePath3=await writeFullAutoOversightEvidence(input.directory,input.phase,event3);return recordFullAutoOversight(input.directory,input.sessionID,"BLOCKED",infraReason),{verdict:"BLOCKED",reasoning:infraReason,evidenceChecked:[],antiPatternsDetected:[],escalationNeeded:!1,rawResponse:"",decision:"pause",event:event3,evidencePath:evidencePath3}}pauseFullAutoRun(input.directory,input.sessionID,infraReason);let event2={...baseEvent,verdict:"BLOCKED",reasoning:infraReason,decision:"pause",full_auto_status_after:"paused"};await writeFullAutoOversightEvent(input.directory,event2);let evidencePath2=await writeFullAutoOversightEvidence(input.directory,input.phase,event2);return recordFullAutoOversight(input.directory,input.sessionID,"BLOCKED",infraReason),{verdict:"BLOCKED",reasoning:infraReason,evidenceChecked:[],antiPatternsDetected:[],escalationNeeded:!1,rawResponse:"",decision:"pause",event:event2,evidencePath:evidencePath2}}resetOversightFailureCounter(input.directory,input.sessionID);let parsed=parseFullAutoCriticResponse(criticResponse),decision=decisionFromVerdict(parsed.verdict,parsed.escalationNeeded),afterStatus=beforeStatus;if(decision==="pause")pauseFullAutoRun(input.directory,input.sessionID,`critic verdict ${parsed.verdict}`),afterStatus="paused";else if(decision==="escalate_human")terminateFullAutoRun(input.directory,input.sessionID,"critic ESCALATE_TO_HUMAN"),afterStatus="terminated";let event={...baseEvent,verdict:parsed.verdict,reasoning:parsed.reasoning,evidence_checked:parsed.evidenceChecked,anti_patterns_detected:parsed.antiPatternsDetected,escalation_needed:parsed.escalationNeeded,decision,full_auto_status_after:afterStatus},failClosed=input.fullAutoConfig?.fail_closed!==!1,persistError,evidencePath;try{await writeFullAutoOversightEvent(input.directory,event)}catch(error93){persistError=error93 instanceof Error?error93.message:String(error93)}if(!persistError)try{evidencePath=await writeFullAutoOversightEvidence(input.directory,input.phase,event)}catch(error93){persistError=error93 instanceof Error?error93.message:String(error93)}if(persistError){if(failClosed)pauseFullAutoRun(input.directory,input.sessionID,`oversight persistence failure: ${persistError}`);let failedEvent={...event,verdict:"BLOCKED",reasoning:`oversight persistence failed: ${persistError}`,decision:"pause",full_auto_status_after:"paused"};try{recordFullAutoOversight(input.directory,input.sessionID,"BLOCKED",`oversight-persistence-failure:${persistError}`)}catch{}return{verdict:"BLOCKED",reasoning:failedEvent.reasoning,evidenceChecked:[],antiPatternsDetected:[],escalationNeeded:!1,rawResponse:criticResponse,decision:"pause",event:failedEvent,evidencePath:void 0}}return recordFullAutoOversight(input.directory,input.sessionID,parsed.verdict,input.trigger),{...parsed,decision,event,evidencePath}}init_state3();function configCadence(config3){let oversight=config3.full_auto?.oversight;return{everyToolCalls:oversight?.every_tool_calls??25,everyArchitectTurns:oversight?.every_architect_turns??5,everyMinutes:oversight?.every_minutes??20}}function denialLimits(config3){return{maxConsecutive:config3.full_auto?.denials?.max_consecutive??3,maxTotal:config3.full_auto?.denials?.max_total??20}}function evaluateFullAutoCadence(state,config3,now=Date.now()){let triggers=[],cadence=configCadence(config3),denials=denialLimits(config3);if(cadence.everyToolCalls>0&&state.counters.toolCalls>0&&state.counters.toolCalls%cadence.everyToolCalls===0)triggers.push({kind:"tool_calls",threshold:cadence.everyToolCalls});if(cadence.everyArchitectTurns>0&&state.counters.architectTurns>0&&state.counters.architectTurns%cadence.everyArchitectTurns===0)triggers.push({kind:"architect_turns",threshold:cadence.everyArchitectTurns});if(cadence.everyMinutes>0&&state.lastOversightAt){let lastTs=Date.parse(state.lastOversightAt);if(Number.isFinite(lastTs)){let elapsedMinutes=(now-lastTs)/60000;if(elapsedMinutes>=cadence.everyMinutes)triggers.push({kind:"minutes",threshold:cadence.everyMinutes,elapsedMinutes})}}if(state.counters.consecutiveNoProgressTurns>=3)triggers.push({kind:"consecutive_no_progress",threshold:3});if(denials.maxConsecutive>1&&state.denialCounters.consecutive>=denials.maxConsecutive-1&&state.denialCounters.consecutive<denials.maxConsecutive)triggers.push({kind:"denials_near_limit",consecutive:state.denialCounters.consecutive,max:denials.maxConsecutive});return{shouldEscalate:triggers.length>0,triggers}}function tickAndEvaluate(directory,sessionID,counter,config3){let before=loadFullAutoRunState(directory,sessionID);if(!before||before.status!=="running")return;let updated=incrementFullAutoCounter(directory,sessionID,counter);if(!updated)return;return evaluateFullAutoCadence(updated,config3)}var cadenceDispatchInFlight=new Set;function resolveOversightAgentName(activeAgent){if(!activeAgent)return"critic_oversight";if(stripKnownSwarmPrefix(activeAgent)!==ORCHESTRATOR_NAME)return"critic_oversight";let lastIdx=activeAgent.toLowerCase().lastIndexOf("architect");if(lastIdx>0)return`${activeAgent.slice(0,lastIdx)}critic_oversight`;return"critic_oversight"}function tickAndMaybeDispatchCadence(directory,sessionID,counter,config3,options={}){let decision=tickAndEvaluate(directory,sessionID,counter,config3);if(!decision||!decision.shouldEscalate)return decision;if(cadenceDispatchInFlight.has(sessionID))return decision;let runState=loadFullAutoRunState(directory,sessionID);if(!runState||runState.status!=="running")return decision;let oversightAgentName=resolveOversightAgentName(options.activeAgent),criticModel=config3.full_auto?.critic_model??config3.agents?.critic?.model??"opencode/big-pickle";return cadenceDispatchInFlight.add(sessionID),(options.dispatch??dispatchFullAutoOversight)({directory,sessionID,trigger:`cadence:${decision.triggers.map((t)=>t.kind).join(",")}`,triggerSource:"cadence",phase:runState.currentPhase,taskID:runState.currentTaskID??void 0,planID:runState.planID,actionContext:{counters:runState.counters,denialCounters:runState.denialCounters,triggers:decision.triggers},criticModel,oversightAgentName,fullAutoConfig:{fail_closed:config3.full_auto?.fail_closed!==!1,max_dispatch_retries:config3.full_auto?.oversight?.max_dispatch_retries??2,max_consecutive_dispatch_failures:config3.full_auto?.oversight?.max_consecutive_dispatch_failures??3}}).catch((err)=>{error48(`[full-auto/cadence] dispatch threw past dispatcher's own fail-closed branches: ${err instanceof Error?err.message:String(err)}`)}).finally(()=>{cadenceDispatchInFlight.delete(sessionID)}),decision}init_state2();init_utils();init_bun_compat();init_realtime_learning_nudge();init_utils2();import{renameSync as renameSync27,unlinkSync as unlinkSync26}from"node:fs";import*as nodePath from"node:path";function createAgentActivityHooks(config3,directory){if(config3.hooks?.agent_activity===!1)return{toolBefore:async()=>{},toolAfter:async()=>{}};return{toolBefore:async(input)=>{swarmState.activeToolCalls.set(input.callID,{tool:input.tool,sessionID:input.sessionID,callID:input.callID,startTime:Date.now()})},toolAfter:async(input,output)=>{let entry=swarmState.activeToolCalls.get(input.callID);if(!entry)return;swarmState.activeToolCalls.delete(input.callID);let duration5=Date.now()-entry.startTime,success3=!((typeof output.success==="boolean"?output.success:void 0)===!1||!!output.error),key=entry.tool,existing=swarmState.toolAggregates.get(key)??{tool:key,count:0,successCount:0,failureCount:0,totalDuration:0};if(existing.count++,success3)existing.successCount++;else existing.failureCount++;if(existing.totalDuration+=duration5,swarmState.toolAggregates.set(key,existing),recordRealtimeLearningToolCall(entry.sessionID),swarmState.pendingEvents++,swarmState.pendingEvents>=20)flushActivityToFile(directory).catch((err)=>warn("Agent activity flush trigger failed:",err))}}}var flushPromise=null;async function flushActivityToFile(directory){if(flushPromise)return flushPromise=flushPromise.then(()=>doFlush(directory)).catch((err)=>{warn("Queued agent activity flush failed:",err)}),flushPromise;flushPromise=doFlush(directory);try{await flushPromise}finally{flushPromise=null}}async function doFlush(directory){try{let existing=await readSwarmFileAsync(directory,"context.md")??"",activitySection=renderActivitySection(),updated=replaceOrAppendSection(existing,"## Agent Activity",activitySection),flushedCount=swarmState.pendingEvents,path170=nodePath.join(directory,".swarm","context.md"),tempPath=`${path170}.tmp`;try{await bunWrite(tempPath,updated),renameSync27(tempPath,path170)}catch(writeError){try{unlinkSync26(tempPath)}catch{}throw writeError}swarmState.pendingEvents=Math.max(0,swarmState.pendingEvents-flushedCount)}catch(error93){warn("Agent activity flush failed:",error93)}}function renderActivitySection(){let lines=["## Agent Activity",""];if(swarmState.toolAggregates.size===0)return lines.push("No tool activity recorded yet."),lines.join(`
5417
5417
  `);lines.push("| Tool | Calls | Success | Failed | Avg Duration |"),lines.push("|------|-------|---------|--------|--------------|");let sorted=[...swarmState.toolAggregates.values()].sort((a,b)=>b.count-a.count);for(let agg of sorted){let avgDuration=agg.count>0?Math.round(agg.totalDuration/agg.count):0;lines.push(`| ${agg.tool} | ${agg.count} | ${agg.successCount} | ${agg.failureCount} | ${avgDuration}ms |`)}return lines.join(`
5418
5418
  `)}function replaceOrAppendSection(content,heading,newSection){let headingIndex=content.indexOf(heading);if(headingIndex===-1)return`${content.trimEnd()}
5419
5419
 
@@ -5433,7 +5433,7 @@ ${content.substring(endIndex+1)}`}return`${content.substring(0,headingIndex)}${n
5433
5433
  `),tokenEstimate=_internals114.estimateTokens(content),maxCapsuleTokens=params.max_capsule_tokens??2000,prunedContent=content;if(tokenEstimate>maxCapsuleTokens){let{prunedSections,prunedTokenEstimate}=pruneCapsuleContent(sections,tokenEstimate,maxCapsuleTokens,_internals114.estimateTokens);prunedContent=prunedSections.join(`
5434
5434
  `),tokenEstimate=prunedTokenEstimate}return{capsule:{task_id,agent_role,delegation_reason,generated_at:generatedAt,files_in_scope:filesInScope,task_goal:params.task_goal,prior_rejection:params.prior_rejection,required_fix:params.required_fix,relevant_facts:params.relevant_facts??[],review_checklist:params.review_checklist,coverage_targets:params.coverage_targets,read_policy:readPolicy,content:prunedContent},metadata:{success:!0,capsule_path:"",token_estimate:tokenEstimate,cache_hits:cacheHits,cache_misses:cacheMisses,stale_entries:staleEntries,recommended_reads:recommendedReads,skipped_reads:skippedReads}}}import*as fs92 from"node:fs";import*as path171 from"node:path";var _internals115={writeFileSync:fs92.writeFileSync,readFileSync:fs92.readFileSync,existsSync:fs92.existsSync,mkdirSync:fs92.mkdirSync,readdirSync:fs92.readdirSync,unlinkSync:fs92.unlinkSync,renameSync:fs92.renameSync},TASK_ID_RE=/^\d+(?:\.\d+)+$/;function isValidTaskId3(taskId){return TASK_ID_RE.test(taskId)}function capsulePath(taskId,directory){return path171.join(directory,".swarm","capsules",`${taskId}.json`)}function estimateTokens4(content){return Math.max(1,Math.ceil(content.length/4))}function saveCapsule(capsule,directory){try{if(!isValidTaskId3(capsule.task_id))return{success:!1,capsule_path:"",token_estimate:0,cache_hits:0,cache_misses:0,stale_entries:0,recommended_reads:[],skipped_reads:[]};let capsulesDir=path171.join(directory,".swarm","capsules"),finalPath=capsulePath(capsule.task_id,directory),tmpPath=path171.join(capsulesDir,`capsule-${capsule.task_id}.tmp`);_internals115.mkdirSync(capsulesDir,{recursive:!0});let json3=JSON.stringify(capsule,null,2);return _internals115.writeFileSync(tmpPath,json3,"utf-8"),_internals115.renameSync(tmpPath,finalPath),{success:!0,capsule_path:finalPath,token_estimate:estimateTokens4(capsule.content),cache_hits:0,cache_misses:0,stale_entries:0,recommended_reads:capsule.read_policy.filter((p)=>p.read_original).map((p)=>p.file_path),skipped_reads:capsule.read_policy.filter((p)=>p.trust_summary).map((p)=>p.file_path)}}catch{return{success:!1,capsule_path:"",token_estimate:0,cache_hits:0,cache_misses:0,stale_entries:0,recommended_reads:[],skipped_reads:[]}}}import*as fs93 from"node:fs";import*as path172 from"node:path";var _internals116={appendFileSync:fs93.appendFileSync,readFileSync:fs93.readFileSync,existsSync:fs93.existsSync,mkdirSync:fs93.mkdirSync};function telemetryFilePath(directory){return path172.join(directory,".swarm","context-telemetry.jsonl")}function recordTelemetry(entry,directory){let filePath=telemetryFilePath(directory),swarmDir=path172.join(directory,".swarm");try{_internals116.mkdirSync(swarmDir,{recursive:!0});let line=`${JSON.stringify(entry)}
5435
5435
  `;return _internals116.appendFileSync(filePath,line,"utf-8"),!0}catch{return!1}}init_state2();function resolveCapsuleDelegationReason(session,agentRole,taskId){if(agentRole==="critic")return"critic_plan_review";if(!session)return"new_task";let workflowState=session.taskWorkflowStates?.get(taskId);if(workflowState==="tests_run")return"test_failure_fix";if(workflowState==="reviewer_run")return"reviewer_rejection_fix";return"new_task"}function extractTaskGoal(taskId,directory){try{let planPath=path173.join(directory,".swarm","plan.json"),raw=fs94.readFileSync(planPath,"utf-8"),plan=JSON.parse(raw);if(!Array.isArray(plan.phases))return"";for(let phase of plan.phases){if(!Array.isArray(phase.tasks))continue;for(let task of phase.tasks)if(task.id===taskId&&typeof task.description==="string")return task.description}return""}catch{return""}}var _internals117={buildCapsule,recordTelemetry,saveCapsule,getActiveAgent:(sessionID)=>swarmState.activeAgent.get(sessionID),getSession:(sessionID)=>swarmState.agentSessions.get(sessionID),getCurrentTaskId:(sessionID)=>{return swarmState.agentSessions.get(sessionID)?.currentTaskId??null},readScopeFile:(taskId,dir)=>{try{let scopePath=path173.join(dir,".swarm","scopes",`scope-${taskId}.json`),raw=fs94.readFileSync(scopePath,"utf-8"),parsed=JSON.parse(raw);return Array.isArray(parsed.files)?parsed.files:[]}catch{return[]}},resolveCapsuleDelegationReason,extractTaskGoal},OPENCODE_NATIVE_AGENTS2=new Set(["build","plan","general","explore","compaction","title","summary"]),VALID_AGENT_ROLES=new Set(["coder","reviewer","critic","test_engineer","sme"]);function extractCapsuleRole(agentName){let normalized=agentName.toLowerCase();if(normalized==="architect"||OPENCODE_NATIVE_AGENTS2.has(normalized))return;for(let role of VALID_AGENT_ROLES)if(normalized===role||normalized.endsWith(`_${role}`))return role;return}function createContextCapsuleInjectHook(config3,directory){if(config3.context_map?.enabled!==!0)return{};return{"experimental.chat.system.transform":async(_input,output)=>{try{await injectCapsule(_input,output,config3,directory)}catch{}}}}async function injectCapsule(input,output,config3,directory){let sessionID=input.sessionID;if(!sessionID)return;let agentName=_internals117.getActiveAgent(sessionID);if(!agentName)return;let role=extractCapsuleRole(agentName);if(!role)return;let effectiveTaskId=_internals117.getCurrentTaskId(sessionID)??"unknown",files=_internals117.readScopeFile(effectiveTaskId,directory);if(files.length===0)return;let maxTokens=config3.context_map?.max_capsule_tokens,delegationReason=_internals117.resolveCapsuleDelegationReason(_internals117.getSession(sessionID),role,effectiveTaskId),taskGoal=_internals117.extractTaskGoal(effectiveTaskId,directory),{capsule,metadata}=_internals117.buildCapsule({task_id:effectiveTaskId,agent_role:role,delegation_reason:delegationReason,files_in_scope:files,task_goal:taskGoal,directory,max_capsule_tokens:maxTokens,mode:config3.context_map?.mode,invalidate_on_hash_change:config3.context_map?.invalidate_on_hash_change,agent_profiles:config3.context_map?.agent_profiles});if(!capsule.content.trim())return;output.system.push(capsule.content);try{_internals117.saveCapsule(capsule,directory)}catch{}let telemetryEntry={timestamp:new Date().toISOString(),task_id:effectiveTaskId,agent_role:role,delegation_reason:capsule.delegation_reason,token_estimate:metadata.token_estimate,cache_hits:metadata.cache_hits,cache_misses:metadata.cache_misses,stale_entries:metadata.stale_entries,recommended_reads:metadata.recommended_reads.length,skipped_reads:metadata.skipped_reads.length,success:metadata.success};try{_internals117.recordTelemetry(telemetryEntry,directory)}catch{}}init_curator_llm_factory();init_delegation_gate();init_utils2();import*as fs95 from"node:fs";var SANITIZATION_PATTERNS=[/\b\d+(st|nd|rd|th)\s+(attempt|try|time)\b/gi,/\b(5th|fifth|final|last)\s+attempt\b/gi,/attempt\s+\d+\s*\/\s*\d+/gi,/\bthis\s+is\s+(the\s+)?(5th|fifth|final|last)\b/gi,/\bwe('re|\s+are)\s+(behind|late)\b/gi,/\buser\s+is\s+waiting\b/gi,/\bship\s+(this|it)\s+now\b/gi,/\bor\s+I('ll|\s+will)\s+(stop|halt|alert)\b/gi,/\bor\s+all\s+work\s+stops\b/gi,/\bthis\s+will\s+(delay|block)\s+everything\b/gi,/\b(I'm|I\s+am)\s+(frustrated|disappointed)\b/gi];function sanitizeMessage(text,patterns=SANITIZATION_PATTERNS){let sanitized=text,stripped=[];for(let pattern of patterns){let matches=sanitized.match(pattern);if(matches)stripped.push(...matches),sanitized=sanitized.replace(pattern,"")}return sanitized=sanitized.replace(/\s+/g," ").trim(),{sanitized,modified:stripped.length>0,stripped}}function isGateAgentMessage(agentName){let gateAgents=["reviewer","test_engineer","critic","test-engineer"],normalized=agentName.toLowerCase().replace(/-/g,"_");return gateAgents.includes(normalized)}function createDelegationSanitizerHook(directory){return safeHook(async(_input,output)=>{let messages=output?.messages;if(!messages||!Array.isArray(messages))return;for(let message of messages){let info=message?.info;if(!info)continue;let agent=info.agent;if(!agent||!isGateAgentMessage(agent))continue;if(!message.parts||!Array.isArray(message.parts))continue;for(let part of message.parts){if(part?.type!=="text"||!part.text)continue;let originalText=part.text,result=sanitizeMessage(originalText);if(result.modified){part.text=result.sanitized;try{let eventsPath=validateSwarmPath(directory,"events.jsonl"),event={event:"message_sanitized",agent,original_length:originalText.length,stripped_count:result.stripped.length,stripped_patterns:result.stripped,timestamp:new Date().toISOString()};fs95.appendFileSync(eventsPath,`${JSON.stringify(event)}
5436
- `,"utf-8")}catch{}}}}})}init_constants();init_schema();init_state2();function createDelegationTrackerHook(config3,guardrailsEnabled=!0){return async(input,_output)=>{let now=Date.now();if(!input.agent||input.agent===""){let session2=ensureAgentSession(input.sessionID,ORCHESTRATOR_NAME);if(session2.delegationActive=!1,swarmState.activeAgent.set(input.sessionID,ORCHESTRATOR_NAME),updateAgentEventTime(input.sessionID),guardrailsEnabled)beginInvocation(input.sessionID,ORCHESTRATOR_NAME);return}let agentName=input.agent,previousAgent=swarmState.activeAgent.get(input.sessionID);swarmState.activeAgent.set(input.sessionID,agentName);let isArchitect=stripKnownSwarmPrefix(agentName)===ORCHESTRATOR_NAME,session=ensureAgentSession(input.sessionID,agentName);if(session.delegationActive=!isArchitect,!isArchitect)session.lastDelegationReason="normal_delegation";if(recordPhaseAgentDispatch(input.sessionID,agentName),guardrailsEnabled)beginInvocation(input.sessionID,agentName);let delegationTrackerEnabled=config3?.hooks?.delegation_tracker===!0,delegationGateEnabled=config3?.hooks?.delegation_gate!==!1;if((delegationTrackerEnabled||delegationGateEnabled)&&previousAgent&&previousAgent!==agentName){let entry={from:previousAgent,to:agentName,timestamp:now};if(!swarmState.delegationChains.has(input.sessionID))swarmState.delegationChains.set(input.sessionID,[]);if(swarmState.delegationChains.get(input.sessionID)?.push(entry),delegationTrackerEnabled)swarmState.pendingEvents++}}}init_extractors();init_critic();init_schema();import*as fs96 from"node:fs";init_state3();init_file_locks();init_state2();init_telemetry();init_bun_compat();init_logger();init_utils2();var END_OF_SENTENCE_QUESTION_PATTERN=/\?\s*$/,PHASE_COMPLETION_PATTERNS=[/Ready for Phase (?:\d+|\[?N\+1\]?)\??/i,/phase.{0,20}(?:complete|finish|done|wrap)/i,/move(?:d?)?\s+(?:on\s+)?to\s+(?:the\s+)?(?:next\s+)?phase/i,/(?:proceed|move)\s+to\s+the\s+next\s+phase/i,/what would you like.{0,20}(?:next|do next)/i],QUESTION_ESCALATION_PATTERNS=[/escalat/i,/What would you like/i,/Should I proceed/i,/Do you want/i,/Shall I/i,/Would you like/i,/Can I proceed/i,/May I proceed/i,/Awaiting (?:your |)(?:approval|confirmation|input|decision|direction)/i,/Please (?:confirm|approve|advise|let me know)/i,/How (?:would you like|should I)/i],MID_SENTENCE_QUESTION_PATTERNS=[/\b(v\d+\?)/i,/\b(v\d+\.\d+\?)/i,/\bAPI\?/i,/\bOK\?/i,/\b\d+\?\d+/];function hashString(str){let hash4=5381;for(let i=0;i<str.length;i++)hash4=(hash4<<5)+hash4+str.charCodeAt(i),hash4=hash4&hash4;return Math.abs(hash4).toString(36)}function isMidSentenceQuestion(text){return MID_SENTENCE_QUESTION_PATTERNS.some((pattern)=>pattern.test(text))}function resolveOversightAgentName2(architectAgentName){if(!architectAgentName)return"critic_oversight";if(stripKnownSwarmPrefix(architectAgentName)!=="architect")return"critic_oversight";let baseRole="architect",lastIndex=architectAgentName.toLowerCase().lastIndexOf(baseRole);if(lastIndex<=0)return"critic_oversight";return`${architectAgentName.slice(0,lastIndex)}critic_oversight`}function detectEscalation(text){for(let pattern of PHASE_COMPLETION_PATTERNS)if(pattern.test(text))return"phase_completion";for(let pattern of QUESTION_ESCALATION_PATTERNS)if(pattern.test(text))return"question";if(END_OF_SENTENCE_QUESTION_PATTERN.test(text)){if(!isMidSentenceQuestion(text))return"question"}return null}function extractMessageText3(message){if(!message?.parts)return"";return message.parts.filter((p)=>p?.type==="text"&&p.text).map((p)=>p.text??"").join(`
5436
+ `,"utf-8")}catch{}}}}})}init_constants();init_schema();init_state2();function createDelegationTrackerHook(config3,guardrailsEnabled=!0){return async(input,_output)=>{let now=Date.now();if(!input.agent||input.agent===""){let session2=ensureAgentSession(input.sessionID,ORCHESTRATOR_NAME);if(session2.delegationActive=!1,swarmState.activeAgent.set(input.sessionID,ORCHESTRATOR_NAME),updateAgentEventTime(input.sessionID),guardrailsEnabled)beginInvocation(input.sessionID,ORCHESTRATOR_NAME);return}let agentName=input.agent,previousAgent=swarmState.activeAgent.get(input.sessionID);swarmState.activeAgent.set(input.sessionID,agentName);let isArchitect=stripKnownSwarmPrefix(agentName)===ORCHESTRATOR_NAME,session=ensureAgentSession(input.sessionID,agentName);if(session.delegationActive=!isArchitect,!isArchitect)session.lastDelegationReason="normal_delegation";if(recordPhaseAgentDispatch(input.sessionID,agentName),guardrailsEnabled)beginInvocation(input.sessionID,agentName);let delegationTrackerEnabled=config3?.hooks?.delegation_tracker===!0,delegationGateEnabled=config3?.hooks?.delegation_gate!==!1;if((delegationTrackerEnabled||delegationGateEnabled)&&previousAgent&&previousAgent!==agentName){let entry={from:previousAgent,to:agentName,timestamp:now};if(!swarmState.delegationChains.has(input.sessionID))swarmState.delegationChains.set(input.sessionID,[]);if(swarmState.delegationChains.get(input.sessionID)?.push(entry),delegationTrackerEnabled)swarmState.pendingEvents++}}}init_extractors();init_critic();init_agents2();init_schema();import*as fs96 from"node:fs";init_state3();init_file_locks();init_state2();init_telemetry();init_bun_compat();init_logger();init_provider_error_classification();init_utils2();var END_OF_SENTENCE_QUESTION_PATTERN=/\?\s*$/,PHASE_COMPLETION_PATTERNS=[/Ready for Phase (?:\d+|\[?N\+1\]?)\??/i,/phase.{0,20}(?:complete|finish|done|wrap)/i,/move(?:d?)?\s+(?:on\s+)?to\s+(?:the\s+)?(?:next\s+)?phase/i,/(?:proceed|move)\s+to\s+the\s+next\s+phase/i,/what would you like.{0,20}(?:next|do next)/i],QUESTION_ESCALATION_PATTERNS=[/escalat/i,/What would you like/i,/Should I proceed/i,/Do you want/i,/Shall I/i,/Would you like/i,/Can I proceed/i,/May I proceed/i,/Awaiting (?:your |)(?:approval|confirmation|input|decision|direction)/i,/Please (?:confirm|approve|advise|let me know)/i,/How (?:would you like|should I)/i],MID_SENTENCE_QUESTION_PATTERNS=[/\b(v\d+\?)/i,/\b(v\d+\.\d+\?)/i,/\bAPI\?/i,/\bOK\?/i,/\b\d+\?\d+/];function hashString(str){let hash4=5381;for(let i=0;i<str.length;i++)hash4=(hash4<<5)+hash4+str.charCodeAt(i),hash4=hash4&hash4;return Math.abs(hash4).toString(36)}function isMidSentenceQuestion(text){return MID_SENTENCE_QUESTION_PATTERNS.some((pattern)=>pattern.test(text))}function resolveOversightAgentName2(architectAgentName){if(!architectAgentName)return"critic_oversight";if(stripKnownSwarmPrefix(architectAgentName)!=="architect")return"critic_oversight";let baseRole="architect",lastIndex=architectAgentName.toLowerCase().lastIndexOf(baseRole);if(lastIndex<=0)return"critic_oversight";return`${architectAgentName.slice(0,lastIndex)}critic_oversight`}function detectEscalation(text){for(let pattern of PHASE_COMPLETION_PATTERNS)if(pattern.test(text))return"phase_completion";for(let pattern of QUESTION_ESCALATION_PATTERNS)if(pattern.test(text))return"question";if(END_OF_SENTENCE_QUESTION_PATTERN.test(text)){if(!isMidSentenceQuestion(text))return"question"}return null}function extractMessageText3(message){if(!message?.parts)return"";return message.parts.filter((p)=>p?.type==="text"&&p.text).map((p)=>p.text??"").join(`
5437
5437
  `)}function parseCriticResponse(rawResponse){return parseCriticResponseFields(rawResponse,{onUnknownVerdict:(value)=>{warn(`[full-auto-intercept] Unknown verdict '${value}' — defaulting to NEEDS_REVISION`)}})}function escalationTypeToInteractionMode(escalationType){return escalationType==="phase_completion"?"phase_completion":"question_resolution"}async function writeAutoOversightEvent(directory,architectOutput,criticVerdict,criticReasoning,evidenceChecked,interactionCount,deadlockCount,escalationType){let event={type:"auto_oversight",timestamp:new Date().toISOString(),interaction_mode:escalationTypeToInteractionMode(escalationType),architect_output:architectOutput,critic_verdict:criticVerdict,critic_reasoning:criticReasoning,evidence_checked:evidenceChecked,interaction_count:interactionCount,deadlock_count:deadlockCount},lockTaskId=`auto-oversight-${Date.now()}`,eventsFilePath="events.jsonl",dir=directory,lockResult;try{lockResult=await tryAcquireLock(dir,"events.jsonl","auto-oversight",lockTaskId)}catch(error93){warn(`[full-auto-intercept] Warning: failed to acquire lock for auto_oversight event: ${error93 instanceof Error?error93.message:String(error93)}`)}if(!lockResult?.acquired)warn("[full-auto-intercept] Warning: could not acquire lock for events.jsonl write — proceeding without lock");try{let eventsPath=validateSwarmPath(dir,"events.jsonl");fs96.appendFileSync(eventsPath,`${JSON.stringify(event)}
5438
5438
  `,"utf-8")}catch(writeError){throw error48(`[full-auto-intercept] Failed to write auto_oversight event: ${writeError instanceof Error?writeError.message:String(writeError)}`),writeError}finally{if(lockResult?.acquired&&lockResult.lock._release)try{await lockResult.lock._release()}catch(releaseError){error48("[full-auto-intercept] Lock release failed:",releaseError)}}}function injectVerdictIntoMessages(messages,architectIndex,criticResult,escalationType,oversightAgentName){if(criticResult.escalationNeeded||criticResult.verdict==="ESCALATE_TO_HUMAN"){let verdictMessage2={info:{role:"assistant",agent:oversightAgentName},parts:[{type:"text",text:`[FULL-AUTO OVERSIGHT — ESCALATE_TO_HUMAN]
5439
5439
 
@@ -5443,12 +5443,12 @@ This question requires human judgment. The swarm has been paused for human revie
5443
5443
 
5444
5444
  ${criticResult.reasoning}`}]};messages.splice(architectIndex+1,0,verdictMessage2);let continuationMessage={info:{role:"user",agent:oversightAgentName},parts:[{type:"text",text:"[FULL-AUTO CONTINUATION] The critic has answered your question. Incorporate the answer above and continue executing the current plan. Do not ask follow-up questions about this answer — proceed with implementation."}]};messages.splice(architectIndex+2,0,continuationMessage);return}let verdictEmoji=criticResult.verdict==="APPROVED"?"✅":criticResult.verdict==="NEEDS_REVISION"?"\uD83D\uDD04":criticResult.verdict==="REJECTED"?"❌":criticResult.verdict==="BLOCKED"?"\uD83D\uDEAB":"\uD83D\uDCAC",verdictMessage={info:{role:"assistant",agent:oversightAgentName},parts:[{type:"text",text:`[FULL-AUTO OVERSIGHT] ${verdictEmoji} **${criticResult.verdict}**
5445
5445
 
5446
- Critic reasoning: ${criticResult.reasoning}`}]};if(messages.splice(architectIndex+1,0,verdictMessage),criticResult.verdict==="APPROVED"&&escalationType==="phase_completion"){let continuationMessage={info:{role:"user",agent:oversightAgentName},parts:[{type:"text",text:"[FULL-AUTO CONTINUATION] Phase approved by autonomous oversight. Call `phase_complete` now to finalize this phase, then proceed to the next phase in the plan. Do not wait for further human input."}]};messages.splice(architectIndex+2,0,continuationMessage)}else if(criticResult.verdict==="APPROVED"){let continuationMessage={info:{role:"user",agent:oversightAgentName},parts:[{type:"text",text:"[FULL-AUTO CONTINUATION] Approved by autonomous oversight. Continue executing the current task and plan. Do not wait for further human input."}]};messages.splice(architectIndex+2,0,continuationMessage)}}async function dispatchCriticAndWriteEvent(directory,architectOutput,criticContext,criticModel,escalationType,interactionCount,deadlockCount,oversightAgentName,sessionID,maxDispatchRetries=2,maxConsecutiveDispatchFailures=3){let client=_internals32.swarmState.opencodeClient;if(!client){warn("[full-auto-intercept] No opencodeClient — critic dispatch skipped (fallback to PENDING)");let result={verdict:"PENDING",reasoning:"No opencodeClient available — critic dispatch not possible",evidenceChecked:[],antiPatternsDetected:[],escalationNeeded:!1,rawResponse:""};return await writeAutoOversightEvent(directory,architectOutput,result.verdict,result.reasoning,result.evidenceChecked,interactionCount,deadlockCount,escalationType),result}let oversightAgent=createCriticAutonomousOversightAgent(criticModel,criticContext);log(`[full-auto-intercept] Dispatching critic: ${oversightAgent.name} using model ${criticModel}`);let ephemeralSessionId,promptController=new AbortController,cleanup=()=>{if(promptController.abort(),ephemeralSessionId){let id=ephemeralSessionId;ephemeralSessionId=void 0,client.session.delete({path:{id}}).catch(()=>{})}};async function attemptDispatch(attempt){if(!client)return{ok:!1,response:"",error:Error("OpenCode client unavailable")};if(attempt>0){let delay2=2**(attempt-1)*1000;await sleep(delay2)}if(ephemeralSessionId){let staleId=ephemeralSessionId;ephemeralSessionId=void 0,client.session.delete({path:{id:staleId}}).catch(()=>{})}let lastError;try{let createResult=await client.session.create({...sessionID?{body:{parentID:sessionID,title:"full_auto_critic background"}}:{},query:{directory}});if(!createResult.data)lastError=Error(`Failed to create critic session: ${JSON.stringify(createResult.error)}`);else{ephemeralSessionId=createResult.data.id,log(`[full-auto-intercept] Created ephemeral session: ${ephemeralSessionId}`);let promptResult=await client.session.prompt({path:{id:ephemeralSessionId},body:{agent:oversightAgentName,tools:{write:!1,edit:!1,patch:!1},parts:[{type:"text",text:criticContext}]},signal:promptController.signal});if(!promptResult.data)lastError=Error(`Critic LLM prompt failed: ${JSON.stringify(promptResult.error)}`);else{let response=promptResult.data.parts.filter((p)=>p.type==="text").map((p)=>p.text).join(`
5446
+ Critic reasoning: ${criticResult.reasoning}`}]};if(messages.splice(architectIndex+1,0,verdictMessage),criticResult.verdict==="APPROVED"&&escalationType==="phase_completion"){let continuationMessage={info:{role:"user",agent:oversightAgentName},parts:[{type:"text",text:"[FULL-AUTO CONTINUATION] Phase approved by autonomous oversight. Call `phase_complete` now to finalize this phase, then proceed to the next phase in the plan. Do not wait for further human input."}]};messages.splice(architectIndex+2,0,continuationMessage)}else if(criticResult.verdict==="APPROVED"){let continuationMessage={info:{role:"user",agent:oversightAgentName},parts:[{type:"text",text:"[FULL-AUTO CONTINUATION] Approved by autonomous oversight. Continue executing the current task and plan. Do not wait for further human input."}]};messages.splice(architectIndex+2,0,continuationMessage)}}async function dispatchCriticAndWriteEvent(directory,architectOutput,criticContext,criticModel,escalationType,interactionCount,deadlockCount,oversightAgentName,sessionID,maxDispatchRetries=2,maxConsecutiveDispatchFailures=3){let client=_internals32.swarmState.opencodeClient;if(!client){warn("[full-auto-intercept] No opencodeClient — critic dispatch skipped (fallback to PENDING)");let result={verdict:"PENDING",reasoning:"No opencodeClient available — critic dispatch not possible",evidenceChecked:[],antiPatternsDetected:[],escalationNeeded:!1,rawResponse:""};return await writeAutoOversightEvent(directory,architectOutput,result.verdict,result.reasoning,result.evidenceChecked,interactionCount,deadlockCount,escalationType),result}let oversightAgent=createCriticAutonomousOversightAgent(criticModel,criticContext);log(`[full-auto-intercept] Dispatching critic: ${oversightAgent.name} using model ${criticModel}`);let ephemeralSessionId,promptController=new AbortController,cleanup=()=>{if(promptController.abort(),ephemeralSessionId){let id=ephemeralSessionId;ephemeralSessionId=void 0,client.session.delete({path:{id}}).catch(()=>{})}};async function attemptDispatch(attempt,modelOverride2){if(!client)return{ok:!1,response:"",error:Error("OpenCode client unavailable")};if(attempt>0){let delay2=2**(attempt-1)*1000;await sleep(delay2)}if(ephemeralSessionId){let staleId=ephemeralSessionId;ephemeralSessionId=void 0,client.session.delete({path:{id:staleId}}).catch(()=>{})}let lastError;try{let createResult=await client.session.create({...sessionID?{body:{parentID:sessionID,title:"full_auto_critic background"}}:{},query:{directory}});if(!createResult.data)lastError=Error(`Failed to create critic session: ${JSON.stringify(createResult.error)}`);else{ephemeralSessionId=createResult.data.id,log(`[full-auto-intercept] Created ephemeral session: ${ephemeralSessionId}`);let promptResult=await client.session.prompt({path:{id:ephemeralSessionId},body:{agent:oversightAgentName,...modelOverride2?{model:modelOverride2}:{},tools:{write:!1,edit:!1,patch:!1},parts:[{type:"text",text:criticContext}]},signal:promptController.signal});if(!promptResult.data)lastError=Error(`Critic LLM prompt failed: ${JSON.stringify(promptResult.error)}`);else{let response=promptResult.data.parts.filter((p)=>p.type==="text").map((p)=>p.text).join(`
5447
5447
  `);if(log(`[full-auto-intercept] Critic response received (${response.length} chars)`),!response.trim())return warn("[full-auto-intercept] Critic returned empty response — using fallback verdict"),{ok:!0,response:`VERDICT: NEEDS_REVISION
5448
5448
  REASONING: Critic returned empty response
5449
5449
  EVIDENCE_CHECKED: none
5450
5450
  ANTI_PATTERNS_DETECTED: empty_response
5451
- ESCALATION_NEEDED: NO`,error:void 0};return{ok:!0,response,error:void 0}}}}catch(err){lastError=err}return{ok:!1,response:"",error:lastError}}let criticResponse="",lastDispatchError;for(let attempt=0;attempt<=maxDispatchRetries;attempt++){let result=await attemptDispatch(attempt);if(result.ok){criticResponse=result.response,lastDispatchError=void 0,resetOversightFailureCounter(directory,sessionID??"");break}if(lastDispatchError=result.error,warn(`[full-auto-intercept] dispatch attempt ${attempt+1}/${maxDispatchRetries+1} failed: ${lastDispatchError instanceof Error?lastDispatchError.message:String(lastDispatchError)}`),attempt<maxDispatchRetries);else{let infraReason=`oversight infrastructure failure after ${maxDispatchRetries+1} attempt(s): ${lastDispatchError instanceof Error?lastDispatchError.message:String(lastDispatchError)}`,consecutive=incrementOversightFailureCounter(directory,sessionID??"");if(consecutive>=maxConsecutiveDispatchFailures&&maxConsecutiveDispatchFailures>0){let degradeReason=`auto-degraded to manual mode after ${consecutive} consecutive oversight infrastructure failures`;pauseFullAutoRun(directory,sessionID??"",infraReason),terminateFullAutoRun(directory,sessionID??"",degradeReason),error48(`[full-auto-intercept] ${degradeReason}`)}else pauseFullAutoRun(directory,sessionID??"",infraReason),error48(`[full-auto-intercept] [ADVISORY] Oversight dispatch exhausted ${maxDispatchRetries+1} attempts and failed. Intercepting with NEEDS_REVISION. Last error: ${lastDispatchError instanceof Error?lastDispatchError.message:String(lastDispatchError)}`)}}cleanup();let parsed;try{parsed=parseCriticResponse(criticResponse),log(`[full-auto-intercept] Critic verdict: ${parsed.verdict} | escalation: ${parsed.escalationNeeded}`)}catch(parseError){error48(`[full-auto-intercept] Failed to parse critic response: ${parseError instanceof Error?parseError.message:String(parseError)}`),parsed={verdict:"NEEDS_REVISION",reasoning:"Critic response parsing failed — defaulting to NEEDS_REVISION",evidenceChecked:[],antiPatternsDetected:[],escalationNeeded:!1,rawResponse:criticResponse}}await writeAutoOversightEvent(directory,architectOutput,parsed.verdict,parsed.reasoning,parsed.evidenceChecked,interactionCount,deadlockCount,escalationType);try{await mirrorReactiveVerdictToV2({directory,parsed,architectOutput,escalationType,oversightAgentName,criticModel,sessionID})}catch(mirrorError){error48(`[full-auto-intercept] v2 mirror failed: ${mirrorError instanceof Error?mirrorError.message:String(mirrorError)}`)}return parsed}function createFullAutoInterceptHook(config3,directory){let fullAutoConfig=config3.full_auto??{enabled:!1,max_interactions_per_phase:50,deadlock_threshold:3,escalation_mode:"pause"},deadlockThreshold=fullAutoConfig.deadlock_threshold??3,maxInteractions=fullAutoConfig.max_interactions_per_phase??50,escalationMode=fullAutoConfig.escalation_mode??"pause";return{messagesTransform:async(_input,output)=>{let messages=output.messages;if(!messages||messages.length===0)return;let lastArchitectMessageIndex=-1;for(let i=messages.length-1;i>=0;i--){let msg=messages[i];if(msg?.info?.role==="user"){let agent=msg.info?.agent,strippedAgent=agent?stripKnownSwarmPrefix(agent):void 0;if(!agent||strippedAgent==="architect"){lastArchitectMessageIndex=i;break}}}if(lastArchitectMessageIndex===-1)return;let architectMessage=messages[lastArchitectMessageIndex],architectText=extractMessageText3(architectMessage);if(!architectText)return;let sessionID=architectMessage.info?.sessionID;if(!_internals32.hasActiveFullAuto(sessionID))return;let session=null;if(sessionID)session=_internals32.ensureAgentSession(sessionID);if(session){let interactionCount=session.fullAutoInteractionCount??0;if(interactionCount>=maxInteractions){if(await handleEscalation(directory,"interaction_limit",sessionID,architectText,interactionCount,session.fullAutoDeadlockCount??0,escalationMode))return}}let escalationType=detectEscalation(architectText);if(!escalationType)return;if(session)session.fullAutoInteractionCount=(session.fullAutoInteractionCount??0)+1;if(escalationType==="question"){let questionHash=hashString(architectText.trim());if(session){if(session.fullAutoLastQuestionHash===questionHash){if(session.fullAutoDeadlockCount=(session.fullAutoDeadlockCount??0)+1,warn(`[full-auto-intercept] Potential deadlock detected (count: ${session.fullAutoDeadlockCount}/${deadlockThreshold}) — identical question repeated`),session.fullAutoDeadlockCount>=deadlockThreshold){if(await handleEscalation(directory,"deadlock",sessionID,architectText,session.fullAutoInteractionCount??0,session.fullAutoDeadlockCount,escalationMode))return}}else session.fullAutoDeadlockCount=0;session.fullAutoLastQuestionHash=questionHash}}log(`[full-auto-intercept] Escalation detected (${escalationType}) — triggering autonomous oversight`);let criticContext=buildCriticContext(architectText,escalationType),criticModel=fullAutoConfig.critic_model??"claude-sonnet-4-20250514",oversightAgent=createCriticAutonomousOversightAgent(criticModel,criticContext),architectAgent=architectMessage.info?.agent,resolvedOversightAgentName=resolveOversightAgentName2(architectAgent),dispatchAgentName=resolvedOversightAgentName&&resolvedOversightAgentName.length>0?resolvedOversightAgentName:"critic_oversight";log(`[full-auto-intercept] Created autonomous oversight agent: ${oversightAgent.name} using model ${criticModel} (dispatch as: ${dispatchAgentName})`);let criticResult=await dispatchCriticAndWriteEvent(directory,architectText,criticContext,criticModel,escalationType,session?.fullAutoInteractionCount??0,session?.fullAutoDeadlockCount??0,dispatchAgentName,sessionID,fullAutoConfig.oversight?.max_dispatch_retries??2,fullAutoConfig.oversight?.max_consecutive_dispatch_failures??3);injectVerdictIntoMessages(messages,lastArchitectMessageIndex,criticResult,escalationType,dispatchAgentName)}}}function buildCriticContext(architectOutput,escalationType){let contextHeader=escalationType==="phase_completion"?`## ARCHITECT PHASE COMPLETION REQUEST
5451
+ ESCALATION_NEEDED: NO`,error:void 0};return{ok:!0,response,error:void 0}}}}catch(err){lastError=err}return{ok:!1,response:"",error:lastError}}let oversightBaseRole=stripKnownSwarmPrefix(oversightAgentName),oversightSwarmId=oversightBaseRole!==oversightAgentName?oversightAgentName.slice(0,oversightAgentName.length-oversightBaseRole.length-1):void 0,oversightSwarmAgents=getSwarmAgents(oversightSwarmId),oversightFallbackRole=oversightSwarmAgents?.[oversightBaseRole]?.fallback_models?.length?oversightBaseRole:"critic",resolveOversightFallback=(index)=>resolveFallbackModel(oversightFallbackRole,index,oversightSwarmAgents),modelFallbackIndex=0,modelOverride,modelUsedLabel=criticModel,criticResponse="",lastDispatchError;for(let attempt=0;attempt<=maxDispatchRetries;attempt++){let result=await attemptDispatch(attempt,modelOverride);if(result.ok){criticResponse=result.response,lastDispatchError=void 0,resetOversightFailureCounter(directory,sessionID??"");break}if(lastDispatchError=result.error,warn(`[full-auto-intercept] dispatch attempt ${attempt+1}/${maxDispatchRetries+1} failed: ${lastDispatchError instanceof Error?lastDispatchError.message:String(lastDispatchError)}`),attempt<maxDispatchRetries){let failureText=lastDispatchError instanceof Error?lastDispatchError.message:String(lastDispatchError);if(isTransientProviderError(failureText)){let advanced=advanceInlineFallback({resolveFallback:resolveOversightFallback,index:modelFallbackIndex,lastError:lastDispatchError,onAdopt:({toModel,fallbackIndex,reason})=>{warn(`[full-auto-intercept] failing over critic to fallback model "${toModel}" (fallback ${fallbackIndex}, reason=${reason})`),telemetry.modelFallback(sessionID??"",oversightAgentName,criticModel,toModel,reason)}});if(modelFallbackIndex=advanced.nextIndex,advanced.adopted)modelOverride=advanced.adopted.override,modelUsedLabel=advanced.adopted.modelString}}else{let infraReason=`oversight infrastructure failure after ${maxDispatchRetries+1} attempt(s): ${lastDispatchError instanceof Error?lastDispatchError.message:String(lastDispatchError)}`,consecutive=incrementOversightFailureCounter(directory,sessionID??"");if(consecutive>=maxConsecutiveDispatchFailures&&maxConsecutiveDispatchFailures>0){let degradeReason=`auto-degraded to manual mode after ${consecutive} consecutive oversight infrastructure failures`;pauseFullAutoRun(directory,sessionID??"",infraReason),terminateFullAutoRun(directory,sessionID??"",degradeReason),error48(`[full-auto-intercept] ${degradeReason}`)}else pauseFullAutoRun(directory,sessionID??"",infraReason),error48(`[full-auto-intercept] [ADVISORY] Oversight dispatch exhausted ${maxDispatchRetries+1} attempts and failed. Intercepting with NEEDS_REVISION. Last error: ${lastDispatchError instanceof Error?lastDispatchError.message:String(lastDispatchError)}`)}}cleanup();let parsed;try{if(parsed=parseCriticResponse(criticResponse),log(`[full-auto-intercept] Critic verdict: ${parsed.verdict} | escalation: ${parsed.escalationNeeded}`),modelFallbackIndex>0)log(`[full-auto-intercept] Critic verdict recovered on fallback model "${modelUsedLabel}" (fallback ${modelFallbackIndex})`)}catch(parseError){error48(`[full-auto-intercept] Failed to parse critic response: ${parseError instanceof Error?parseError.message:String(parseError)}`),parsed={verdict:"NEEDS_REVISION",reasoning:"Critic response parsing failed — defaulting to NEEDS_REVISION",evidenceChecked:[],antiPatternsDetected:[],escalationNeeded:!1,rawResponse:criticResponse}}await writeAutoOversightEvent(directory,architectOutput,parsed.verdict,parsed.reasoning,parsed.evidenceChecked,interactionCount,deadlockCount,escalationType);try{await mirrorReactiveVerdictToV2({directory,parsed,architectOutput,escalationType,oversightAgentName,criticModel,criticModelUsed:modelUsedLabel,sessionID})}catch(mirrorError){error48(`[full-auto-intercept] v2 mirror failed: ${mirrorError instanceof Error?mirrorError.message:String(mirrorError)}`)}return parsed}function createFullAutoInterceptHook(config3,directory){let fullAutoConfig=config3.full_auto??{enabled:!1,max_interactions_per_phase:50,deadlock_threshold:3,escalation_mode:"pause"},deadlockThreshold=fullAutoConfig.deadlock_threshold??3,maxInteractions=fullAutoConfig.max_interactions_per_phase??50,escalationMode=fullAutoConfig.escalation_mode??"pause";return{messagesTransform:async(_input,output)=>{let messages=output.messages;if(!messages||messages.length===0)return;let lastArchitectMessageIndex=-1;for(let i=messages.length-1;i>=0;i--){let msg=messages[i];if(msg?.info?.role==="user"){let agent=msg.info?.agent,strippedAgent=agent?stripKnownSwarmPrefix(agent):void 0;if(!agent||strippedAgent==="architect"){lastArchitectMessageIndex=i;break}}}if(lastArchitectMessageIndex===-1)return;let architectMessage=messages[lastArchitectMessageIndex],architectText=extractMessageText3(architectMessage);if(!architectText)return;let sessionID=architectMessage.info?.sessionID;if(!_internals32.hasActiveFullAuto(sessionID))return;let session=null;if(sessionID)session=_internals32.ensureAgentSession(sessionID);if(session){let interactionCount=session.fullAutoInteractionCount??0;if(interactionCount>=maxInteractions){if(await handleEscalation(directory,"interaction_limit",sessionID,architectText,interactionCount,session.fullAutoDeadlockCount??0,escalationMode))return}}let escalationType=detectEscalation(architectText);if(!escalationType)return;if(session)session.fullAutoInteractionCount=(session.fullAutoInteractionCount??0)+1;if(escalationType==="question"){let questionHash=hashString(architectText.trim());if(session){if(session.fullAutoLastQuestionHash===questionHash){if(session.fullAutoDeadlockCount=(session.fullAutoDeadlockCount??0)+1,warn(`[full-auto-intercept] Potential deadlock detected (count: ${session.fullAutoDeadlockCount}/${deadlockThreshold}) — identical question repeated`),session.fullAutoDeadlockCount>=deadlockThreshold){if(await handleEscalation(directory,"deadlock",sessionID,architectText,session.fullAutoInteractionCount??0,session.fullAutoDeadlockCount,escalationMode))return}}else session.fullAutoDeadlockCount=0;session.fullAutoLastQuestionHash=questionHash}}log(`[full-auto-intercept] Escalation detected (${escalationType}) — triggering autonomous oversight`);let criticContext=buildCriticContext(architectText,escalationType),criticModel=fullAutoConfig.critic_model??"claude-sonnet-4-20250514",oversightAgent=createCriticAutonomousOversightAgent(criticModel,criticContext),architectAgent=architectMessage.info?.agent,resolvedOversightAgentName=resolveOversightAgentName2(architectAgent),dispatchAgentName=resolvedOversightAgentName&&resolvedOversightAgentName.length>0?resolvedOversightAgentName:"critic_oversight";log(`[full-auto-intercept] Created autonomous oversight agent: ${oversightAgent.name} using model ${criticModel} (dispatch as: ${dispatchAgentName})`);let criticResult=await dispatchCriticAndWriteEvent(directory,architectText,criticContext,criticModel,escalationType,session?.fullAutoInteractionCount??0,session?.fullAutoDeadlockCount??0,dispatchAgentName,sessionID,fullAutoConfig.oversight?.max_dispatch_retries??2,fullAutoConfig.oversight?.max_consecutive_dispatch_failures??3);injectVerdictIntoMessages(messages,lastArchitectMessageIndex,criticResult,escalationType,dispatchAgentName)}}}function buildCriticContext(architectOutput,escalationType){let contextHeader=escalationType==="phase_completion"?`## ARCHITECT PHASE COMPLETION REQUEST
5452
5452
 
5453
5453
  The architect has signaled phase completion and is awaiting oversight approval to proceed.`:`## ARCHITECT QUESTION
5454
5454
 
@@ -5487,7 +5487,7 @@ ${currentPhase!==void 0?"- **Phase Status**: Pending completion":""}
5487
5487
  ## Resolution
5488
5488
  This escalation requires human intervention. The swarm has been paused.
5489
5489
  Please review the architect's output above and provide guidance.
5490
- `;fs96.writeFileSync(reportPath,reportContent,"utf-8"),log(`[full-auto-intercept] Escalation report written to: ${reportPath}`)}catch(error93){error48("[full-auto-intercept] Failed to write escalation report:",error93 instanceof Error?error93.message:String(error93))}}async function handleEscalation(directory,reason,sessionID,architectOutput,interactionCount,deadlockCount,escalationMode,phase){if(telemetry.autoOversightEscalation(sessionID??"unknown",reason,interactionCount,deadlockCount,phase),await writeEscalationReport(directory,reason,architectOutput,interactionCount,deadlockCount,phase),sessionID){if(!loadFullAutoRunState(directory,sessionID))startFullAutoRun(directory,sessionID,{enabled:!0});recordFullAutoEscalation(directory,sessionID,{reason,interactionCount,deadlockCount,phase})}if(escalationMode==="terminate"){if(error48(`[full-auto-intercept] ESCALATION (terminate mode) — reason: ${reason}, session: ${sessionID}`),sessionID){if(!loadFullAutoRunState(directory,sessionID))startFullAutoRun(directory,sessionID,{enabled:!0});terminateFullAutoRun(directory,sessionID,reason)}return!0}if(warn(`[full-auto-intercept] ESCALATION (pause mode) — reason: ${reason}, session: ${sessionID}`),sessionID){if(!loadFullAutoRunState(directory,sessionID))startFullAutoRun(directory,sessionID,{enabled:!0});pauseFullAutoRun(directory,sessionID,reason)}return!0}var reactiveOversightSequence=0;async function mirrorReactiveVerdictToV2(params){reactiveOversightSequence+=1;let triggerSource=params.escalationType==="phase_completion"?"phase_boundary":"text_pattern",sessionID="",phase,planID;try{let filePath=validateSwarmPath(params.directory,"full-auto-state.json");if(fs96.existsSync(filePath)){let raw=fs96.readFileSync(filePath,"utf-8"),persisted=JSON.parse(raw);if(persisted.sessions){let callerSid=params.sessionID;if(callerSid&&persisted.sessions[callerSid]){let rec=persisted.sessions[callerSid];if(rec.status==="running")sessionID=callerSid,phase=rec.currentPhase,planID=rec.planID}else if(!callerSid)for(let sid of Object.keys(persisted.sessions)){let rec=persisted.sessions[sid];if(rec?.status==="running"){sessionID=sid,phase=rec.currentPhase,planID=rec.planID;break}}}}}catch{}if(!sessionID)return;let decision=(()=>{if(params.parsed.escalationNeeded||params.parsed.verdict==="ESCALATE_TO_HUMAN")return"escalate_human";if(params.parsed.verdict==="APPROVED"||params.parsed.verdict==="ANSWER")return"allow";if(params.parsed.verdict==="BLOCKED")return"pause";if(params.parsed.verdict==="PENDING")return"pending";return"deny"})(),beforeStatus=sessionID?loadFullAutoRunState(params.directory,sessionID)?.status:void 0,event={type:"full_auto_oversight",timestamp:new Date().toISOString(),session_id:sessionID,plan_id:planID,phase,trigger_source:triggerSource,trigger_reason:`reactive intercept (${params.escalationType})`,critic_agent:params.oversightAgentName,critic_model:params.criticModel,verdict:params.parsed.verdict,reasoning:params.parsed.reasoning,evidence_checked:params.parsed.evidenceChecked,anti_patterns_detected:params.parsed.antiPatternsDetected,escalation_needed:params.parsed.escalationNeeded,decision,full_auto_status_before:beforeStatus,full_auto_status_after:beforeStatus,oversight_sequence:reactiveOversightSequence};if(sessionID){if(decision==="pause")pauseFullAutoRun(params.directory,sessionID,`reactive verdict ${params.parsed.verdict}`),event.full_auto_status_after="paused";else if(decision==="escalate_human")terminateFullAutoRun(params.directory,sessionID,"reactive ESCALATE_TO_HUMAN"),event.full_auto_status_after="terminated";recordFullAutoOversight(params.directory,sessionID,params.parsed.verdict,`reactive ${params.escalationType}`)}if(await writeFullAutoOversightEvent(params.directory,event),params.escalationType==="phase_completion"&&params.parsed.verdict==="APPROVED"&&typeof phase==="number")await writeFullAutoOversightEvidence(params.directory,phase,event)}init_guardrails2();function isPartsShape(message){let info=message.info;return typeof info==="object"&&info!==null&&typeof info.role==="string"&&Array.isArray(message.parts)}function getRole(message){if(isPartsShape(message))return message.info.role;return message.role}function isToolResultSystemMessage(message){if(isPartsShape(message))return!1;let flat=message;return flat.tool_call_id!==void 0||flat.name!==void 0}function getSystemText(message){if(isPartsShape(message)){let texts=message.parts.filter((part)=>part.type==="text"&&typeof part.text==="string").map((part)=>part.text.trim()).filter((t)=>t.length>0);return texts.length>0?texts.join(`
5490
+ `;fs96.writeFileSync(reportPath,reportContent,"utf-8"),log(`[full-auto-intercept] Escalation report written to: ${reportPath}`)}catch(error93){error48("[full-auto-intercept] Failed to write escalation report:",error93 instanceof Error?error93.message:String(error93))}}async function handleEscalation(directory,reason,sessionID,architectOutput,interactionCount,deadlockCount,escalationMode,phase){if(telemetry.autoOversightEscalation(sessionID??"unknown",reason,interactionCount,deadlockCount,phase),await writeEscalationReport(directory,reason,architectOutput,interactionCount,deadlockCount,phase),sessionID){if(!loadFullAutoRunState(directory,sessionID))startFullAutoRun(directory,sessionID,{enabled:!0});recordFullAutoEscalation(directory,sessionID,{reason,interactionCount,deadlockCount,phase})}if(escalationMode==="terminate"){if(error48(`[full-auto-intercept] ESCALATION (terminate mode) — reason: ${reason}, session: ${sessionID}`),sessionID){if(!loadFullAutoRunState(directory,sessionID))startFullAutoRun(directory,sessionID,{enabled:!0});terminateFullAutoRun(directory,sessionID,reason)}return!0}if(warn(`[full-auto-intercept] ESCALATION (pause mode) — reason: ${reason}, session: ${sessionID}`),sessionID){if(!loadFullAutoRunState(directory,sessionID))startFullAutoRun(directory,sessionID,{enabled:!0});pauseFullAutoRun(directory,sessionID,reason)}return!0}var reactiveOversightSequence=0;async function mirrorReactiveVerdictToV2(params){reactiveOversightSequence+=1;let triggerSource=params.escalationType==="phase_completion"?"phase_boundary":"text_pattern",sessionID="",phase,planID;try{let filePath=validateSwarmPath(params.directory,"full-auto-state.json");if(fs96.existsSync(filePath)){let raw=fs96.readFileSync(filePath,"utf-8"),persisted=JSON.parse(raw);if(persisted.sessions){let callerSid=params.sessionID;if(callerSid&&persisted.sessions[callerSid]){let rec=persisted.sessions[callerSid];if(rec.status==="running")sessionID=callerSid,phase=rec.currentPhase,planID=rec.planID}else if(!callerSid)for(let sid of Object.keys(persisted.sessions)){let rec=persisted.sessions[sid];if(rec?.status==="running"){sessionID=sid,phase=rec.currentPhase,planID=rec.planID;break}}}}}catch{}if(!sessionID)return;let decision=(()=>{if(params.parsed.escalationNeeded||params.parsed.verdict==="ESCALATE_TO_HUMAN")return"escalate_human";if(params.parsed.verdict==="APPROVED"||params.parsed.verdict==="ANSWER")return"allow";if(params.parsed.verdict==="BLOCKED")return"pause";if(params.parsed.verdict==="PENDING")return"pending";return"deny"})(),beforeStatus=sessionID?loadFullAutoRunState(params.directory,sessionID)?.status:void 0,event={type:"full_auto_oversight",timestamp:new Date().toISOString(),session_id:sessionID,plan_id:planID,phase,trigger_source:triggerSource,trigger_reason:`reactive intercept (${params.escalationType})`,critic_agent:params.oversightAgentName,critic_model:params.criticModelUsed??params.criticModel,verdict:params.parsed.verdict,reasoning:params.parsed.reasoning,evidence_checked:params.parsed.evidenceChecked,anti_patterns_detected:params.parsed.antiPatternsDetected,escalation_needed:params.parsed.escalationNeeded,decision,full_auto_status_before:beforeStatus,full_auto_status_after:beforeStatus,oversight_sequence:reactiveOversightSequence};if(sessionID){if(decision==="pause")pauseFullAutoRun(params.directory,sessionID,`reactive verdict ${params.parsed.verdict}`),event.full_auto_status_after="paused";else if(decision==="escalate_human")terminateFullAutoRun(params.directory,sessionID,"reactive ESCALATE_TO_HUMAN"),event.full_auto_status_after="terminated";recordFullAutoOversight(params.directory,sessionID,params.parsed.verdict,`reactive ${params.escalationType}`)}if(await writeFullAutoOversightEvent(params.directory,event),params.escalationType==="phase_completion"&&params.parsed.verdict==="APPROVED"&&typeof phase==="number")await writeFullAutoOversightEvidence(params.directory,phase,event)}init_guardrails2();function isPartsShape(message){let info=message.info;return typeof info==="object"&&info!==null&&typeof info.role==="string"&&Array.isArray(message.parts)}function getRole(message){if(isPartsShape(message))return message.info.role;return message.role}function isToolResultSystemMessage(message){if(isPartsShape(message))return!1;let flat=message;return flat.tool_call_id!==void 0||flat.name!==void 0}function getSystemText(message){if(isPartsShape(message)){let texts=message.parts.filter((part)=>part.type==="text"&&typeof part.text==="string").map((part)=>part.text.trim()).filter((t)=>t.length>0);return texts.length>0?texts.join(`
5491
5491
  `):null}let content=message.content;if(typeof content==="string"){let trimmed=content.trim();return trimmed.length>0?trimmed:null}if(Array.isArray(content)){let texts=content.filter((part)=>part.type==="text"&&typeof part.text==="string").map((part)=>part.text.trim()).filter((t)=>t.length>0);return texts.length>0?texts.join(`
5492
5492
  `):null}return null}function isWhitespaceOnlySystem(message){if(getRole(message)!=="system")return!1;if(isPartsShape(message))return message.parts.length>0&&message.parts.every((part)=>part.type!=="text"||typeof part.text!=="string"||part.text.trim().length===0);let content=message.content;return typeof content==="string"&&content.trim().length===0}function buildConsolidatedSystem(firstSystem,mergedText){if(isPartsShape(firstSystem))return{...firstSystem,info:{...firstSystem.info,role:"system"},parts:[{type:"text",text:mergedText}]};return{role:"system",content:mergedText,...Object.fromEntries(Object.entries(firstSystem).filter(([key])=>key!=="role"&&key!=="content"&&key!=="name"&&key!=="tool_call_id"))}}function consolidateSystemMessages(messages){if(messages.length>0&&getRole(messages[0])==="system"&&getSystemText(messages[0])!==null&&(isPartsShape(messages[0])||typeof messages[0].content==="string")){if(messages.filter((m)=>getRole(m)==="system").length===1)return[...messages]}let systemMessageIndices=[],systemContents=[];for(let i=0;i<messages.length;i++){let message=messages[i];if(getRole(message)!=="system")continue;if(isToolResultSystemMessage(message))continue;let textContent=getSystemText(message);if(systemMessageIndices.push(i),textContent)systemContents.push(textContent)}if(systemContents.length===0)return messages.filter((m,idx)=>{if(getRole(m)!=="system")return!0;return idx===0});let mergedSystemContent=systemContents.join(`
5493
5493
 
@@ -5886,7 +5886,7 @@ ${activitySection}`;break}if(contextSummary.length>maxChars)return`${contextSumm
5886
5886
  `)}function createSummary(output,toolName,summaryId,maxSummaryChars){let contentType=detectContentType(output,toolName),lineCount=output.split(`
5887
5887
  `).length,byteSize=Buffer.byteLength(output,"utf8"),formattedSize=formatBytes2(byteSize),headerLine=`[SUMMARY ${summaryId}] ${formattedSize} | ${contentType} | ${lineCount} lines`,footerLine=`→ Use /swarm retrieve ${summaryId} for full content`,overhead=headerLine.length+1+footerLine.length+1,maxPreviewChars=maxSummaryChars-overhead,preview;switch(contentType){case"json":{try{let parsed=JSON.parse(output.trim());if(Array.isArray(parsed))preview=summarizeJsonArray(parsed);else if(typeof parsed==="object"&&parsed!==null)preview=summarizeJsonObject(parsed);else preview=summarizeText(output,3)}catch{preview=summarizeText(output,3)}break}case"code":{preview=summarizeCode(output);break}case"text":{preview=summarizeText(output,5);break}case"binary":{preview=`[Binary content - ${formattedSize}]`;break}default:preview=summarizeText(output,5)}if(preview.length>maxPreviewChars)preview=`${preview.substring(0,maxPreviewChars-3)}...`;return`${headerLine}
5888
5888
  ${preview}
5889
- ${footerLine}`}init_utils();var nextSummaryId=1;function createToolSummarizerHook(config3,directory){if(config3.enabled===!1)return async()=>{};return async(input,output)=>{if(typeof output.output!=="string"||output.output.length===0)return;if((config3.exempt_tools??["retrieve_summary","retrieve_lane_output","task","read"]).includes(input.tool))return;if(!shouldSummarize(output.output,config3.threshold_bytes))return;let summaryId=`S${nextSummaryId++}`,summaryText=createSummary(output.output,input.tool,summaryId,config3.max_summary_chars);try{await storeSummary(directory,summaryId,output.output,summaryText,config3.max_stored_bytes),output.output=summaryText}catch(error93){warn(`Tool output summarization failed for ${summaryId}: ${error93 instanceof Error?error93.message:String(error93)}`)}}}init_utils2();init_constants();init_schema();init_state2();import*as child_process12 from"node:child_process";import*as fs106 from"node:fs";init_agents2();init_schema();init_state2();init_telemetry();import*as fs105 from"node:fs/promises";import*as path192 from"node:path";init_provider_error_classification();init_bun_compat();import{rmSync as rmSync13}from"node:fs";import*as fs104 from"node:fs/promises";import*as path191 from"node:path";function leanTurboEvidenceDir(directory,phase){return path191.join(directory,".swarm","evidence",String(phase),"lean-turbo")}function validateLaneId(laneId){if(laneId.length===0)throw Error("Invalid laneId: empty string is not allowed");if(laneId.length>128)throw Error(`Invalid laneId: exceeds maximum length of 128 characters (got ${laneId.length})`);if(laneId.includes("/")||laneId.includes("\\"))throw Error(`Invalid laneId: path separators are not allowed (got "${laneId}")`);if(laneId.includes(".."))throw Error(`Invalid laneId: parent-directory references are not allowed (got "${laneId}")`);if(laneId.startsWith("/")||/^[a-zA-Z]:/i.test(laneId))throw Error(`Invalid laneId: absolute paths are not allowed (got "${laneId}")`)}function laneEvidencePath(directory,phase,laneId){validateLaneId(laneId);let expectedDir=leanTurboEvidenceDir(directory,phase),resolvedPath=path191.resolve(path191.join(expectedDir,`${laneId}.json`)),resolvedDir=path191.resolve(expectedDir);if(!resolvedPath.startsWith(resolvedDir+path191.sep)&&resolvedPath!==resolvedDir)throw Error(`Invalid laneId: path traversal detected (got "${laneId}")`);return resolvedPath}async function atomicWriteJson(filePath,data){let content=JSON.stringify(data,null,2),dir=path191.dirname(filePath);await fs104.mkdir(dir,{recursive:!0});let tempPath=`${filePath}.tmp.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}`;try{await bunWrite(tempPath,content),await fs104.rename(tempPath,filePath)}catch(error93){try{rmSync13(tempPath,{force:!0})}catch{}throw error93}}function phaseEvidencePath(directory,phase){return path191.join(leanTurboEvidenceDir(directory,phase),"lean-turbo-phase.json")}async function writeLaneEvidence(directory,phase,evidence){let targetPath=laneEvidencePath(directory,phase,evidence.laneId);await atomicWriteJson(targetPath,evidence)}async function writePhaseEvidence(directory,evidence){let targetPath=phaseEvidencePath(directory,evidence.phase);await atomicWriteJson(targetPath,evidence)}async function readPhaseEvidence(directory,phase){let targetPath=phaseEvidencePath(directory,phase),content;try{content=await fs104.readFile(targetPath,"utf-8")}catch(error93){let code=error93.code;if(code==="ENOENT"||code==="ENOTDIR")return null;throw error93}try{return JSON.parse(content)}catch{return null}}async function listLaneEvidence(directory,phase){let evidenceDir=leanTurboEvidenceDir(directory,phase),entries;try{entries=await fs104.readdir(evidenceDir)}catch(error93){let code=error93.code;if(code==="ENOENT"||code==="ENOTDIR")return[];throw error93}entries.sort();let lanes=[];for(let entry of entries){if(!entry.endsWith(".json"))continue;if(entry==="lean-turbo-phase.json")continue;let filePath=path191.join(evidenceDir,entry),content;try{content=await fs104.readFile(filePath,"utf-8")}catch{continue}try{let parsed=JSON.parse(content);lanes.push(parsed)}catch{}}return lanes}init_state4();var DEFAULT_CONFIG2={reviewerAgent:"",timeoutMs:0,requireDiffSummary:!1};function resolveDefaultReviewerAgent(generatedAgentNames){if(generatedAgentNames.length===0)return"reviewer";let best=null;for(let name of generatedAgentNames){let lower=name.toLowerCase();if((lower.endsWith("_reviewer")||lower.endsWith("-reviewer"))&&(!best||name.length>best.length))best=name}return best??(generatedAgentNames.includes("reviewer")?"reviewer":generatedAgentNames[0])}async function compileReviewPackage(directory,phase,sessionID,requireDiffSummary){let lanes=await listLaneEvidence(directory,phase),persisted=_internals123.readPersisted?.(directory)??null;if(persisted){let matchingRunState=null;for(let sessionState of Object.values(persisted.sessions))if(typeof sessionState==="object"&&sessionState!==null&&sessionState.status==="running"&&sessionState.phase===phase&&sessionState.strategy==="lean"&&sessionState.sessionID===sessionID){matchingRunState=sessionState;break}if(!matchingRunState&&sessionID===void 0){for(let sessionState of Object.values(persisted.sessions))if(typeof sessionState==="object"&&sessionState!==null&&sessionState.status==="running"&&sessionState.phase===phase&&sessionState.strategy==="lean"){matchingRunState=sessionState;break}}if(matchingRunState?.lanes&&matchingRunState.lanes.length>0){let evidenceLaneIds=new Set(lanes.map((l)=>l.laneId)),missingLanes=matchingRunState.lanes.filter((l)=>(l.status==="completed"||l.status==="failed")&&!evidenceLaneIds.has(l.laneId));if(missingLanes.length>0)throw Error(`Lane evidence missing for ${missingLanes.length} lane(s): ${missingLanes.map((l)=>l.laneId).join(", ")}. Run lane execution before review.`)}}let phaseEvidence=await readPhaseEvidence(directory,phase),filesChangedSet=new Set;for(let lane of lanes)for(let file3 of lane.files)filesChangedSet.add(file3);let completedLanes=lanes.filter((l)=>l.status==="completed").length,failedLanes=lanes.filter((l)=>l.status==="failed").length,laneSummaries=lanes.map((lane)=>({laneId:lane.laneId,taskIds:lane.taskIds,files:lane.files,status:lane.status,agent:lane.agent})),degradedTasks=phaseEvidence?.degradedTasks??[],pendingDegraded=degradedTasks.filter((dt)=>!lanes.some((l)=>l.taskIds.includes(dt.taskId)&&l.status==="completed")).length,buildStatus="unknown";if(phaseEvidence?.status==="completed")buildStatus=failedLanes===0?"passed":"failed";else if(phaseEvidence?.status==="failed")buildStatus="failed";let pkg={phase,sessionID,laneSummaries,filesChanged:[...filesChangedSet],testResults:{totalLanes:lanes.length,completedLanes,failedLanes},buildStatus,degradationSummary:{totalDegraded:degradedTasks.length,resolvedDegraded:degradedTasks.length-pendingDegraded,pendingDegraded}};if(phaseEvidence?.validationArtifacts)pkg.validationArtifacts=phaseEvidence.validationArtifacts;if(requireDiffSummary){if(!phaseEvidence?.integratedDiffSummary)throw Error(`Integrated diff summary is required for phase ${phaseEvidence?.phase??"unknown"} but missing. Run the review step with diff evidence generation enabled.`);pkg.integratedDiffSummary=phaseEvidence.integratedDiffSummary}return pkg}function parseReviewerVerdict2(responseText){let verdictMatch=responseText.toUpperCase().match(/VERDICT\s*:\s*(APPROVED|NEEDS_REVISION|REJECTED)/);if(!verdictMatch)return null;let verdict=verdictMatch[1],lines=responseText.split(`
5889
+ ${footerLine}`}init_utils();var nextSummaryId=1;function createToolSummarizerHook(config3,directory){if(config3.enabled===!1)return async()=>{};return async(input,output)=>{if(typeof output.output!=="string"||output.output.length===0)return;if((config3.exempt_tools??["retrieve_summary","retrieve_lane_output","task","read"]).includes(input.tool))return;if(!shouldSummarize(output.output,config3.threshold_bytes))return;let summaryId=`S${nextSummaryId++}`,summaryText=createSummary(output.output,input.tool,summaryId,config3.max_summary_chars);try{await storeSummary(directory,summaryId,output.output,summaryText,config3.max_stored_bytes),output.output=summaryText}catch(error93){warn(`Tool output summarization failed for ${summaryId}: ${error93 instanceof Error?error93.message:String(error93)}`)}}}init_utils2();init_agents2();init_constants();init_schema();init_state2();init_telemetry();import*as child_process12 from"node:child_process";import*as fs106 from"node:fs";init_agents2();init_schema();init_state2();init_telemetry();import*as fs105 from"node:fs/promises";import*as path192 from"node:path";init_provider_error_classification();init_bun_compat();import{rmSync as rmSync13}from"node:fs";import*as fs104 from"node:fs/promises";import*as path191 from"node:path";function leanTurboEvidenceDir(directory,phase){return path191.join(directory,".swarm","evidence",String(phase),"lean-turbo")}function validateLaneId(laneId){if(laneId.length===0)throw Error("Invalid laneId: empty string is not allowed");if(laneId.length>128)throw Error(`Invalid laneId: exceeds maximum length of 128 characters (got ${laneId.length})`);if(laneId.includes("/")||laneId.includes("\\"))throw Error(`Invalid laneId: path separators are not allowed (got "${laneId}")`);if(laneId.includes(".."))throw Error(`Invalid laneId: parent-directory references are not allowed (got "${laneId}")`);if(laneId.startsWith("/")||/^[a-zA-Z]:/i.test(laneId))throw Error(`Invalid laneId: absolute paths are not allowed (got "${laneId}")`)}function laneEvidencePath(directory,phase,laneId){validateLaneId(laneId);let expectedDir=leanTurboEvidenceDir(directory,phase),resolvedPath=path191.resolve(path191.join(expectedDir,`${laneId}.json`)),resolvedDir=path191.resolve(expectedDir);if(!resolvedPath.startsWith(resolvedDir+path191.sep)&&resolvedPath!==resolvedDir)throw Error(`Invalid laneId: path traversal detected (got "${laneId}")`);return resolvedPath}async function atomicWriteJson(filePath,data){let content=JSON.stringify(data,null,2),dir=path191.dirname(filePath);await fs104.mkdir(dir,{recursive:!0});let tempPath=`${filePath}.tmp.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}`;try{await bunWrite(tempPath,content),await fs104.rename(tempPath,filePath)}catch(error93){try{rmSync13(tempPath,{force:!0})}catch{}throw error93}}function phaseEvidencePath(directory,phase){return path191.join(leanTurboEvidenceDir(directory,phase),"lean-turbo-phase.json")}async function writeLaneEvidence(directory,phase,evidence){let targetPath=laneEvidencePath(directory,phase,evidence.laneId);await atomicWriteJson(targetPath,evidence)}async function writePhaseEvidence(directory,evidence){let targetPath=phaseEvidencePath(directory,evidence.phase);await atomicWriteJson(targetPath,evidence)}async function readPhaseEvidence(directory,phase){let targetPath=phaseEvidencePath(directory,phase),content;try{content=await fs104.readFile(targetPath,"utf-8")}catch(error93){let code=error93.code;if(code==="ENOENT"||code==="ENOTDIR")return null;throw error93}try{return JSON.parse(content)}catch{return null}}async function listLaneEvidence(directory,phase){let evidenceDir=leanTurboEvidenceDir(directory,phase),entries;try{entries=await fs104.readdir(evidenceDir)}catch(error93){let code=error93.code;if(code==="ENOENT"||code==="ENOTDIR")return[];throw error93}entries.sort();let lanes=[];for(let entry of entries){if(!entry.endsWith(".json"))continue;if(entry==="lean-turbo-phase.json")continue;let filePath=path191.join(evidenceDir,entry),content;try{content=await fs104.readFile(filePath,"utf-8")}catch{continue}try{let parsed=JSON.parse(content);lanes.push(parsed)}catch{}}return lanes}init_state4();var DEFAULT_CONFIG2={reviewerAgent:"",timeoutMs:0,requireDiffSummary:!1};function resolveDefaultReviewerAgent(generatedAgentNames){if(generatedAgentNames.length===0)return"reviewer";let best=null;for(let name of generatedAgentNames){let lower=name.toLowerCase();if((lower.endsWith("_reviewer")||lower.endsWith("-reviewer"))&&(!best||name.length>best.length))best=name}return best??(generatedAgentNames.includes("reviewer")?"reviewer":generatedAgentNames[0])}async function compileReviewPackage(directory,phase,sessionID,requireDiffSummary){let lanes=await listLaneEvidence(directory,phase),persisted=_internals123.readPersisted?.(directory)??null;if(persisted){let matchingRunState=null;for(let sessionState of Object.values(persisted.sessions))if(typeof sessionState==="object"&&sessionState!==null&&sessionState.status==="running"&&sessionState.phase===phase&&sessionState.strategy==="lean"&&sessionState.sessionID===sessionID){matchingRunState=sessionState;break}if(!matchingRunState&&sessionID===void 0){for(let sessionState of Object.values(persisted.sessions))if(typeof sessionState==="object"&&sessionState!==null&&sessionState.status==="running"&&sessionState.phase===phase&&sessionState.strategy==="lean"){matchingRunState=sessionState;break}}if(matchingRunState?.lanes&&matchingRunState.lanes.length>0){let evidenceLaneIds=new Set(lanes.map((l)=>l.laneId)),missingLanes=matchingRunState.lanes.filter((l)=>(l.status==="completed"||l.status==="failed")&&!evidenceLaneIds.has(l.laneId));if(missingLanes.length>0)throw Error(`Lane evidence missing for ${missingLanes.length} lane(s): ${missingLanes.map((l)=>l.laneId).join(", ")}. Run lane execution before review.`)}}let phaseEvidence=await readPhaseEvidence(directory,phase),filesChangedSet=new Set;for(let lane of lanes)for(let file3 of lane.files)filesChangedSet.add(file3);let completedLanes=lanes.filter((l)=>l.status==="completed").length,failedLanes=lanes.filter((l)=>l.status==="failed").length,laneSummaries=lanes.map((lane)=>({laneId:lane.laneId,taskIds:lane.taskIds,files:lane.files,status:lane.status,agent:lane.agent})),degradedTasks=phaseEvidence?.degradedTasks??[],pendingDegraded=degradedTasks.filter((dt)=>!lanes.some((l)=>l.taskIds.includes(dt.taskId)&&l.status==="completed")).length,buildStatus="unknown";if(phaseEvidence?.status==="completed")buildStatus=failedLanes===0?"passed":"failed";else if(phaseEvidence?.status==="failed")buildStatus="failed";let pkg={phase,sessionID,laneSummaries,filesChanged:[...filesChangedSet],testResults:{totalLanes:lanes.length,completedLanes,failedLanes},buildStatus,degradationSummary:{totalDegraded:degradedTasks.length,resolvedDegraded:degradedTasks.length-pendingDegraded,pendingDegraded}};if(phaseEvidence?.validationArtifacts)pkg.validationArtifacts=phaseEvidence.validationArtifacts;if(requireDiffSummary){if(!phaseEvidence?.integratedDiffSummary)throw Error(`Integrated diff summary is required for phase ${phaseEvidence?.phase??"unknown"} but missing. Run the review step with diff evidence generation enabled.`);pkg.integratedDiffSummary=phaseEvidence.integratedDiffSummary}return pkg}function parseReviewerVerdict2(responseText){let verdictMatch=responseText.toUpperCase().match(/VERDICT\s*:\s*(APPROVED|NEEDS_REVISION|REJECTED)/);if(!verdictMatch)return null;let verdict=verdictMatch[1],lines=responseText.split(`
5890
5890
  `),verdictIndex=lines.findIndex((l)=>l.toUpperCase().match(/VERDICT\s*:\s*(APPROVED|NEEDS_REVISION|REJECTED)/i)),reason;if(verdictIndex>=0&&verdictIndex+1<lines.length){let reasonMatch=lines[verdictIndex+1].match(/^REASON\s*:\s*(.+)/i);if(reasonMatch)reason=reasonMatch[1].trim()}return{verdict,reason}}async function writeReviewerEvidence(directory,phase,verdict,reason){let evidenceDir=path192.join(directory,".swarm","evidence",String(phase));await fs105.mkdir(evidenceDir,{recursive:!0});let evidencePath=path192.join(evidenceDir,"lean-turbo-reviewer.json"),content=JSON.stringify({phase,verdict,reason:reason??null,timestamp:new Date().toISOString()},null,2),tempPath=`${evidencePath}.tmp.${process.pid}.${Date.now()}`;try{await fs105.writeFile(tempPath,content,"utf-8"),await fs105.rename(tempPath,evidencePath)}catch(error93){try{await fs105.unlink(tempPath)}catch{}throw error93}return evidencePath}async function defaultDispatchReviewerAgent(directory,reviewPackage,agentName,timeoutMs,parentSessionId,model){let client=swarmState.opencodeClient;if(!client)throw Error("OpencodeClient not available");let sessionResult=await client.session.create({...parentSessionId?{body:{parentID:parentSessionId,title:"lean_turbo_reviewer background"}}:{},query:{directory}});if(!sessionResult.data?.id)throw Error("Failed to create reviewer session");let sessionId=sessionResult.data.id,promptController=new AbortController,timeoutHandle;try{let promptText=`You are a read-only phase reviewer for Lean Turbo execution.
5891
5891
 
5892
5892
  ## Phase Review Package
@@ -5922,17 +5922,17 @@ OR
5922
5922
  VERDICT: REJECTED
5923
5923
  REASON: [critical issues that block phase advancement]
5924
5924
 
5925
- Be specific and evidence-based. Do not approve a phase with unresolved degraded tasks or incomplete lane execution.`,response=timeoutMs>0?await Promise.race([client.session.prompt({path:{id:sessionId},body:{agent:agentName,...model?{model}:{},tools:{write:!1,edit:!1,patch:!1},parts:[{type:"text",text:promptText}]},signal:promptController.signal}),new Promise((_,reject)=>{timeoutHandle=setTimeout(()=>{promptController.abort(),reject(Error(`Reviewer dispatch timed out after ${timeoutMs}ms`))},timeoutMs)})]):await client.session.prompt({path:{id:sessionId},body:{agent:agentName,tools:{write:!1,edit:!1,patch:!1},parts:[{type:"text",text:promptText}]},signal:promptController.signal});if(!response.data)throw Error("Reviewer session returned no data");return response.data.parts.filter((p)=>p.type==="text").map((p)=>p.text??"").join(`
5926
- `)}finally{if(timeoutHandle!==void 0)clearTimeout(timeoutHandle);promptController.abort(),client.session.delete({path:{id:sessionId}}).catch(()=>{})}}var _internals123={compileReviewPackage,parseReviewerVerdict:parseReviewerVerdict2,writeReviewerEvidence,dispatchReviewerAgent:defaultDispatchReviewerAgent,resolveDefaultReviewerAgent,listLaneEvidence,readPhaseEvidence,readPersisted:readPersisted3};async function dispatchPhaseReviewer(directory,phase,sessionID,config3){let mergedConfig={...DEFAULT_CONFIG2,...config3},generatedAgentNames=swarmState.generatedAgentNames,agentName=mergedConfig.reviewerAgent||resolveDefaultReviewerAgent(generatedAgentNames),pkg=await _internals123.compileReviewPackage(directory,phase,sessionID,mergedConfig.requireDiffSummary),reviewerBase=stripKnownSwarmPrefix(agentName),reviewerSwarmId=reviewerBase!==agentName?agentName.slice(0,agentName.length-reviewerBase.length-1):void 0,reviewerSwarmAgents=getSwarmAgents(reviewerSwarmId),responseText;try{responseText=(await dispatchWithModelFallback({dispatch:(model)=>_internals123.dispatchReviewerAgent(directory,pkg,agentName,mergedConfig.timeoutMs,sessionID,model),resolveFallback:(index)=>resolveFallbackModel(reviewerBase,index,reviewerSwarmAgents),maxTransientRetriesPerModel:0,classify:(err)=>{let msg=err instanceof Error?err.message:String(err);if(/Reviewer dispatch timed out/i.test(msg))return"permanent";return isTransientProviderError(msg)?"transient":"permanent"},onFallback:({toModel,fallbackIndex})=>{telemetry.modelFallback(sessionID,agentName,reviewerSwarmAgents?.[reviewerBase]?.model??"default",toModel,"transient_model_error");let session=getAgentSession(sessionID);if(session)session.pendingAdvisoryMessages??=[],session.pendingAdvisoryMessages.push(`MODEL FALLBACK: reviewer failed over to "${toModel}" (fallback ${fallbackIndex}) after a transient/quota dispatch error.`)}})).result}catch(error93){let isQuota=isQuotaError(error93 instanceof Error?error93.message:String(error93)),evidencePath2=await _internals123.writeReviewerEvidence(directory,phase,"REJECTED",error93 instanceof Error?error93.message:String(error93));return{verdict:"REJECTED",reason:`Reviewer dispatch failed${isQuota?" (model quota/usage limit exhausted across all configured fallbacks)":""}: ${error93 instanceof Error?error93.message:String(error93)}`,evidencePath:evidencePath2}}let parsed=_internals123.parseReviewerVerdict(responseText);if(!parsed)return{verdict:"REJECTED",reason:"Reviewer response could not be parsed",evidencePath:await _internals123.writeReviewerEvidence(directory,phase,"REJECTED","Reviewer response could not be parsed")};let evidencePath=await _internals123.writeReviewerEvidence(directory,phase,parsed.verdict,parsed.reason);return{verdict:parsed.verdict,reason:parsed.reason,evidencePath}}init_logger();init_normalize_tool_name();init_review_receipt();init_utils2();var MAX_TRACKED_SESSIONS5=256,COOLDOWN_MS=60000,inFlightSessions=new Set,lastDispatchBySession=new Map;function evictCooldownMap(){while(lastDispatchBySession.size>MAX_TRACKED_SESSIONS5){let firstKey=lastDispatchBySession.keys().next().value;if(firstKey===void 0)break;lastDispatchBySession.delete(firstKey)}}function execGit2(directory,args2,opts){return new Promise((resolve69,reject)=>{let proc=child_process12.execFile("git",args2,{encoding:"utf-8",cwd:directory,timeout:opts.timeoutMs,maxBuffer:opts.maxBuffer,stdio:["ignore","pipe","pipe"]},(error93,stdout)=>{if(proc.kill(),error93){reject(error93);return}resolve69(stdout??"")})})}async function computeExecutionDiff(directory,maxBytes){try{let[diff,status]=await Promise.all([execGit2(directory,["diff","HEAD"],{timeoutMs:15000,maxBuffer:Math.max(maxBytes*2,1048576)}),execGit2(directory,["status","--porcelain"],{timeoutMs:1e4,maxBuffer:262144})]),untracked=status.split(`
5925
+ Be specific and evidence-based. Do not approve a phase with unresolved degraded tasks or incomplete lane execution.`,response=timeoutMs>0?await Promise.race([client.session.prompt({path:{id:sessionId},body:{agent:agentName,...model?{model}:{},tools:{write:!1,edit:!1,patch:!1},parts:[{type:"text",text:promptText}]},signal:promptController.signal}),new Promise((_,reject)=>{timeoutHandle=setTimeout(()=>{promptController.abort(),reject(Error(`Reviewer dispatch timed out after ${timeoutMs}ms`))},timeoutMs)})]):await client.session.prompt({path:{id:sessionId},body:{agent:agentName,...model?{model}:{},tools:{write:!1,edit:!1,patch:!1},parts:[{type:"text",text:promptText}]},signal:promptController.signal});if(!response.data)throw Error(`Reviewer session returned no data: ${JSON.stringify(response.error)}`);return response.data.parts.filter((p)=>p.type==="text").map((p)=>p.text??"").join(`
5926
+ `)}finally{if(timeoutHandle!==void 0)clearTimeout(timeoutHandle);promptController.abort(),client.session.delete({path:{id:sessionId}}).catch(()=>{})}}var _internals123={compileReviewPackage,parseReviewerVerdict:parseReviewerVerdict2,writeReviewerEvidence,dispatchReviewerAgent:defaultDispatchReviewerAgent,resolveDefaultReviewerAgent,listLaneEvidence,readPhaseEvidence,readPersisted:readPersisted3};async function dispatchPhaseReviewer(directory,phase,sessionID,config3){let mergedConfig={...DEFAULT_CONFIG2,...config3},generatedAgentNames=swarmState.generatedAgentNames,agentName=mergedConfig.reviewerAgent||resolveDefaultReviewerAgent(generatedAgentNames),pkg=await _internals123.compileReviewPackage(directory,phase,sessionID,mergedConfig.requireDiffSummary),reviewerBase=stripKnownSwarmPrefix(agentName),reviewerSwarmId=reviewerBase!==agentName?agentName.slice(0,agentName.length-reviewerBase.length-1):void 0,reviewerSwarmAgents=getSwarmAgents(reviewerSwarmId),responseText;try{responseText=(await dispatchWithModelFallback({dispatch:(model)=>_internals123.dispatchReviewerAgent(directory,pkg,agentName,mergedConfig.timeoutMs,sessionID,model),resolveFallback:(index)=>resolveFallbackModel(reviewerBase,index,reviewerSwarmAgents),maxTransientRetriesPerModel:0,classify:(err)=>{let msg=err instanceof Error?err.message:String(err);if(/Reviewer dispatch timed out/i.test(msg))return"permanent";return isTransientProviderError(msg)?"transient":"permanent"},onFallback:({toModel,fallbackIndex})=>{telemetry.modelFallback(sessionID,agentName,reviewerSwarmAgents?.[reviewerBase]?.model??"default",toModel,"transient_model_error");let session=getAgentSession(sessionID);if(session)session.pendingAdvisoryMessages??=[],session.pendingAdvisoryMessages.push(`MODEL FALLBACK: reviewer failed over to "${toModel}" (fallback ${fallbackIndex}) after a transient/quota dispatch error.`)}})).result}catch(error93){let isQuota=isQuotaError(error93 instanceof Error?error93.message:String(error93)),evidencePath2=await _internals123.writeReviewerEvidence(directory,phase,"REJECTED",error93 instanceof Error?error93.message:String(error93));return{verdict:"REJECTED",reason:`Reviewer dispatch failed${isQuota?" (model quota/usage limit exhausted across all configured fallbacks)":""}: ${error93 instanceof Error?error93.message:String(error93)}`,evidencePath:evidencePath2}}let parsed=_internals123.parseReviewerVerdict(responseText);if(!parsed)return{verdict:"REJECTED",reason:"Reviewer response could not be parsed",evidencePath:await _internals123.writeReviewerEvidence(directory,phase,"REJECTED","Reviewer response could not be parsed")};let evidencePath=await _internals123.writeReviewerEvidence(directory,phase,parsed.verdict,parsed.reason);return{verdict:parsed.verdict,reason:parsed.reason,evidencePath}}init_logger();init_provider_error_classification();init_normalize_tool_name();init_review_receipt();init_utils2();var MAX_TRACKED_SESSIONS5=256,COOLDOWN_MS=60000,inFlightSessions=new Set,lastDispatchBySession=new Map;function evictCooldownMap(){while(lastDispatchBySession.size>MAX_TRACKED_SESSIONS5){let firstKey=lastDispatchBySession.keys().next().value;if(firstKey===void 0)break;lastDispatchBySession.delete(firstKey)}}function execGit2(directory,args2,opts){return new Promise((resolve69,reject)=>{let proc=child_process12.execFile("git",args2,{encoding:"utf-8",cwd:directory,timeout:opts.timeoutMs,maxBuffer:opts.maxBuffer,stdio:["ignore","pipe","pipe"]},(error93,stdout)=>{if(proc.kill(),error93){reject(error93);return}resolve69(stdout??"")})})}async function computeExecutionDiff(directory,maxBytes){try{let[diff,status]=await Promise.all([execGit2(directory,["diff","HEAD"],{timeoutMs:15000,maxBuffer:Math.max(maxBytes*2,1048576)}),execGit2(directory,["status","--porcelain"],{timeoutMs:1e4,maxBuffer:262144})]),untracked=status.split(`
5927
5927
  `).filter((l)=>l.startsWith("??")).map((l)=>l.slice(3).trim()).filter(Boolean);if(!diff.trim()&&untracked.length===0)return{status:"clean"};let combined=diff;if(untracked.length>0)combined+=`
5928
5928
 
5929
5929
  ## UNTRACKED FILES (not in diff above)
5930
5930
  ${untracked.slice(0,100).map((f)=>`- ${f}`).join(`
5931
5931
  `)}`;if(combined.length>maxBytes)combined=`${combined.slice(0,maxBytes)}
5932
5932
  ... [diff truncated at ${maxBytes} bytes]`;return{status:"ok",diff:combined}}catch(err){let reason=err instanceof Error?err.message:String(err);return warn(`[auto-review] diff collection failed: ${reason}`),{status:"error",reason}}}function buildReviewPrompt(trigger,diff,taskId,phase){return[`TASK: Review the execution diff below (automatic ${trigger} review pass).`,taskId?`Plan task under review: ${taskId}.`:"",phase!==void 0?`Phase under review: ${phase}.`:"","FILE: see DIFF","DIFF:","```diff",diff,"```","AFFECTS: infer from diff","CHECK: correctness, security, regressions","GATES: none","SKILLS: none","SKILLS_USED_BY_CODER: none","","This diff is the cumulative working-tree change — review the CHANGE, not pre-existing code.","Respond in your mandated OUTPUT FORMAT, beginning directly with VERDICT."].filter(Boolean).join(`
5933
- `)}async function dispatchReviewer(directory,prompt,agentName,timeoutMs,parentSessionId){let client=swarmState.opencodeClient;if(!client)throw Error("OpencodeClient not available");let trimmedParentID=parentSessionId?.trim(),createResult=await client.session.create({body:{...trimmedParentID?{parentID:trimmedParentID}:{},title:`auto-review (${agentName}) background`},query:{directory}});if(!createResult.data?.id)throw Error("Failed to create auto-review session");let sessionId=createResult.data.id,promptController=new AbortController,timeoutHandle;try{let promptCall=client.session.prompt({path:{id:sessionId},body:{agent:agentName,tools:{write:!1,edit:!1,patch:!1},parts:[{type:"text",text:prompt}]},signal:promptController.signal}),response=await Promise.race([promptCall,new Promise((_,reject)=>{timeoutHandle=setTimeout(()=>{promptController.abort(),reject(Error(`auto-review timed out after ${timeoutMs}ms`))},timeoutMs)})]);if(!response.data)throw Error("auto-review session returned no data");return response.data.parts.filter((p)=>p.type==="text").map((p)=>p.text).join(`
5933
+ `)}async function dispatchReviewer(directory,prompt,agentName,timeoutMs,parentSessionId,model){let client=swarmState.opencodeClient;if(!client)throw Error("OpencodeClient not available");let trimmedParentID=parentSessionId?.trim(),createResult=await client.session.create({body:{...trimmedParentID?{parentID:trimmedParentID}:{},title:`auto-review (${agentName}) background`},query:{directory}});if(!createResult.data?.id)throw Error("Failed to create auto-review session");let sessionId=createResult.data.id,promptController=new AbortController,timeoutHandle;try{let promptCall=client.session.prompt({path:{id:sessionId},body:{agent:agentName,...model?{model}:{},tools:{write:!1,edit:!1,patch:!1},parts:[{type:"text",text:prompt}]},signal:promptController.signal}),response=await Promise.race([promptCall,new Promise((_,reject)=>{timeoutHandle=setTimeout(()=>{promptController.abort(),reject(Error(`auto-review timed out after ${timeoutMs}ms`))},timeoutMs)})]);if(!response.data)throw Error(`auto-review session returned no data: ${JSON.stringify(response.error)}`);return response.data.parts.filter((p)=>p.type==="text").map((p)=>p.text).join(`
5934
5934
  `)}finally{if(timeoutHandle!==void 0)clearTimeout(timeoutHandle);promptController.abort(),client.session.delete({path:{id:sessionId}}).catch(()=>{})}}var _eventWriteLockChain=Promise.resolve();function withEventWriteLock(fn2){let release;_eventWriteLockChain=new Promise((r)=>{release=r});try{return fn2()}finally{release()}}function writeAutoReviewEvent(directory,event){try{let eventsPath=validateSwarmPath(directory,"events.jsonl"),line=`${JSON.stringify(event)}
5935
- `;withEventWriteLock(()=>{fs106.appendFileSync(eventsPath,line,"utf-8")})}catch(err){warn(`[auto-review] event write failed: ${err instanceof Error?err.message:String(err)}`)}}async function runAutoReview(input){let{directory,sessionID,trigger,taskId,phase,config:config3}=input,base={type:"auto_review",timestamp:new Date().toISOString(),session_id:sessionID,trigger,task_id:taskId,phase};try{let diffResult=await _internals124.computeExecutionDiff(directory,config3.max_diff_kb*1024);if(diffResult.status==="clean"){writeAutoReviewEvent(directory,{...base,verdict:"skipped",detail:"clean working tree — nothing to review"});return}if(diffResult.status==="error"){writeAutoReviewEvent(directory,{...base,verdict:"error",detail:`diff collection failed: ${diffResult.reason}`});return}let diff=diffResult.diff,agentName=resolveDefaultReviewerAgent(swarmState.generatedAgentNames),prompt=buildReviewPrompt(trigger,diff,taskId,phase),transcript;try{transcript=await _internals124.dispatchReviewer(directory,prompt,agentName,config3.timeout_ms,sessionID)}catch(err){writeAutoReviewEvent(directory,{...base,verdict:"error",detail:`dispatch failed: ${err instanceof Error?err.message:String(err)}`});return}let parsed=parseReviewerOutput(transcript);if(!parsed){writeAutoReviewEvent(directory,{...base,verdict:"unparseable",detail:"reviewer response had no VERDICT line"}),input.injectAdvisory(sessionID,`[AUTO-REVIEW] Automatic ${trigger} review returned no machine-readable verdict. Treat as UNVERIFIED — inspect the diff or re-dispatch @reviewer before proceeding.`);return}let receipt=parsed.verdict==="approved"?buildApprovedReceipt({agent:"reviewer",sessionId:sessionID,scopeContent:diff,scopeDescription:`auto-review-${trigger}-diff`,checkedAspects:["correctness","security","regressions"],validatedClaims:[`AUTO-REVIEW VERDICT: APPROVED${parsed.risk?` (risk ${parsed.risk})`:""}`],caveats:parsed.issues.map((i)=>i.text)}):buildRejectedReceipt({agent:"reviewer",sessionId:sessionID,scopeContent:diff,scopeDescription:`auto-review-${trigger}-diff`,blockingFindings:parsed.issues.map((i)=>({location:i.location??"unknown",summary:i.text,severity:i.severity})),evidenceReferences:parsed.issues.map((i)=>i.location).filter((loc)=>Boolean(loc)),passConditions:parsed.fixes,summary:`Auto-review REJECTED${parsed.risk?` (risk ${parsed.risk})`:""}`}),receiptPath;try{receiptPath=await persistReviewReceipt(directory,receipt)}catch(err){warn(`[auto-review] receipt persistence failed: ${err instanceof Error?err.message:String(err)}`)}if(writeAutoReviewEvent(directory,{...base,verdict:parsed.verdict,detail:parsed.verdict==="approved"?`approved${parsed.risk?` (risk ${parsed.risk})`:""}`:`rejected with ${parsed.issues.length} issue(s)`,receipt_path:receiptPath}),parsed.verdict==="rejected"){let topIssues=parsed.issues.slice(0,3).map((i)=>` • ${i.text}`).join(`
5935
+ `;withEventWriteLock(()=>{fs106.appendFileSync(eventsPath,line,"utf-8")})}catch(err){warn(`[auto-review] event write failed: ${err instanceof Error?err.message:String(err)}`)}}async function runAutoReview(input){let{directory,sessionID,trigger,taskId,phase,config:config3}=input,base={type:"auto_review",timestamp:new Date().toISOString(),session_id:sessionID,trigger,task_id:taskId,phase};try{let diffResult=await _internals124.computeExecutionDiff(directory,config3.max_diff_kb*1024);if(diffResult.status==="clean"){writeAutoReviewEvent(directory,{...base,verdict:"skipped",detail:"clean working tree — nothing to review"});return}if(diffResult.status==="error"){writeAutoReviewEvent(directory,{...base,verdict:"error",detail:`diff collection failed: ${diffResult.reason}`});return}let diff=diffResult.diff,agentName=resolveDefaultReviewerAgent(swarmState.generatedAgentNames),prompt=buildReviewPrompt(trigger,diff,taskId,phase),reviewerBase=stripKnownSwarmPrefix(agentName),reviewerSwarmId=reviewerBase!==agentName?agentName.slice(0,agentName.length-reviewerBase.length-1):void 0,reviewerSwarmAgents=getSwarmAgents(reviewerSwarmId),transcript;try{transcript=(await dispatchWithModelFallback({dispatch:(model)=>_internals124.dispatchReviewer(directory,prompt,agentName,config3.timeout_ms,sessionID,model),resolveFallback:(index)=>resolveFallbackModel(reviewerBase,index,reviewerSwarmAgents),maxTransientRetriesPerModel:0,classify:(err)=>{let msg=err instanceof Error?err.message:String(err);if(/auto-review timed out/i.test(msg))return"permanent";return isTransientProviderError(msg)?"transient":"permanent"},onFallback:({toModel,fallbackIndex})=>{telemetry.modelFallback(sessionID,agentName,reviewerSwarmAgents?.[reviewerBase]?.model??"default",toModel,"transient_model_error"),input.injectAdvisory(sessionID,`MODEL FALLBACK: auto-review reviewer failed over to "${toModel}" (fallback ${fallbackIndex}) after a transient/quota dispatch error.`)}})).result}catch(err){let isQuota=isQuotaError(err instanceof Error?err.message:String(err));writeAutoReviewEvent(directory,{...base,verdict:"error",detail:`dispatch failed${isQuota?" (model quota/usage limit exhausted across all configured fallbacks)":""}: ${err instanceof Error?err.message:String(err)}`});return}let parsed=parseReviewerOutput(transcript);if(!parsed){writeAutoReviewEvent(directory,{...base,verdict:"unparseable",detail:"reviewer response had no VERDICT line"}),input.injectAdvisory(sessionID,`[AUTO-REVIEW] Automatic ${trigger} review returned no machine-readable verdict. Treat as UNVERIFIED — inspect the diff or re-dispatch @reviewer before proceeding.`);return}let receipt=parsed.verdict==="approved"?buildApprovedReceipt({agent:"reviewer",sessionId:sessionID,scopeContent:diff,scopeDescription:`auto-review-${trigger}-diff`,checkedAspects:["correctness","security","regressions"],validatedClaims:[`AUTO-REVIEW VERDICT: APPROVED${parsed.risk?` (risk ${parsed.risk})`:""}`],caveats:parsed.issues.map((i)=>i.text)}):buildRejectedReceipt({agent:"reviewer",sessionId:sessionID,scopeContent:diff,scopeDescription:`auto-review-${trigger}-diff`,blockingFindings:parsed.issues.map((i)=>({location:i.location??"unknown",summary:i.text,severity:i.severity})),evidenceReferences:parsed.issues.map((i)=>i.location).filter((loc)=>Boolean(loc)),passConditions:parsed.fixes,summary:`Auto-review REJECTED${parsed.risk?` (risk ${parsed.risk})`:""}`}),receiptPath;try{receiptPath=await persistReviewReceipt(directory,receipt)}catch(err){warn(`[auto-review] receipt persistence failed: ${err instanceof Error?err.message:String(err)}`)}if(writeAutoReviewEvent(directory,{...base,verdict:parsed.verdict,detail:parsed.verdict==="approved"?`approved${parsed.risk?` (risk ${parsed.risk})`:""}`:`rejected with ${parsed.issues.length} issue(s)`,receipt_path:receiptPath}),parsed.verdict==="rejected"){let topIssues=parsed.issues.slice(0,3).map((i)=>` • ${i.text}`).join(`
5936
5936
  `);input.injectAdvisory(sessionID,[`[AUTO-REVIEW] Automatic ${trigger} review REJECTED the current diff${parsed.risk?` (risk ${parsed.risk})`:""}.`,topIssues,parsed.fixes.length>0?`Required fixes: ${parsed.fixes.slice(0,3).join("; ")}`:"","Address the findings (delegate to coder, then re-review) before continuing."].filter(Boolean).join(`
5937
5937
  `))}}catch(err){warn(`[auto-review] run failed: ${err instanceof Error?err.message:String(err)}`)}}function createAutoReviewHook(options){let{config:config3,directory,injectAdvisory}=options;if(!config3.enabled)return{toolAfter:async()=>{}};let wantsTask=config3.trigger==="task_completion"||config3.trigger==="both",wantsPhase=config3.trigger==="phase_boundary"||config3.trigger==="both";return{toolAfter:async(input,output)=>{try{let tool3=(normalizeToolName(input.tool)??input.tool??"").toLowerCase(),sessionID=input.sessionID;if(!sessionID)return;let agentName=swarmState.activeAgent.get(sessionID)??swarmState.agentSessions.get(sessionID)?.agentName??"";if(agentName&&stripKnownSwarmPrefix(agentName)!==ORCHESTRATOR_NAME)return;let args2=output.args??void 0,trigger=null,taskId,phase;if(wantsTask&&tool3==="update_task_status"&&args2?.status==="completed")trigger="task_completion",taskId=typeof args2.task_id==="string"?args2.task_id:void 0;else if(wantsPhase&&tool3==="phase_complete")trigger="phase_boundary",phase=typeof args2?.phase==="number"&&Number.isInteger(args2.phase)?args2.phase:void 0;if(!trigger)return;if(inFlightSessions.has(sessionID))return;let last=lastDispatchBySession.get(sessionID)??0;if(_internals124.now()-last<COOLDOWN_MS)return;inFlightSessions.add(sessionID),lastDispatchBySession.delete(sessionID),lastDispatchBySession.set(sessionID,_internals124.now()),evictCooldownMap(),_internals124.runAutoReview({directory,sessionID,trigger,taskId,phase,config:{timeout_ms:config3.timeout_ms,max_diff_kb:config3.max_diff_kb},injectAdvisory}).finally(()=>{inFlightSessions.delete(sessionID)})}catch(err){warn(`[auto-review] hook error: ${err instanceof Error?err.message:String(err)}`)}}}}var _internals124={computeExecutionDiff,dispatchReviewer,runAutoReview,now:()=>Date.now()};init_utils();init_bun_compat();init_utils2();function normalizePath3(filePath){return filePath.replace(/\\/g,"/")}async function readCoChangeJson(directory){try{let filePath=validateSwarmPath(directory,"co-change.json"),content=await bunFile(filePath).text(),data=JSON.parse(content);if(!data||typeof data.version!=="string"||!Array.isArray(data.entries))return null;let seen=new Set,dedupedEntries=[];for(let entry of data.entries){if(typeof entry.fileA!=="string"||typeof entry.fileB!=="string"||typeof entry.coChangeCount!=="number"||typeof entry.npmi!=="number")continue;let normalizedA=normalizePath3(entry.fileA),normalizedB=normalizePath3(entry.fileB),key=[normalizedA,normalizedB].sort().join("|");if(!seen.has(key))seen.add(key),dedupedEntries.push(entry)}return{...data,entries:dedupedEntries}}catch{return null}}function getCoChangePartnersForFile(entries,filePath){let normalizedTarget=normalizePath3(filePath);return entries.filter((entry)=>{let normalizedA=normalizePath3(entry.fileA),normalizedB=normalizePath3(entry.fileB);return normalizedA===normalizedTarget||normalizedB===normalizedTarget})}function createCoChangeSuggesterHook(directory){return safeHook(async(input,_output)=>{let record3=input,toolName=typeof record3.tool==="string"?record3.tool:"";if(!["write","edit","apply_patch","swarm_apply_patch","patch","create_file"].includes(toolName))return;let toolInput=record3.input,filePath=toolInput?.filePath??toolInput?.file_path??toolInput?.path;if(!filePath)return;let coChangeData=await readCoChangeJson(directory);if(!coChangeData)return;let partners=getCoChangePartnersForFile(coChangeData.entries,filePath);if(partners.length===0)return;let partnerList=partners.slice(0,3).map((e)=>{let normalizedFilePath=normalizePath3(filePath);return`${normalizePath3(e.fileA)===normalizedFilePath?e.fileB:e.fileA} (co-change: ${e.coChangeCount}x, npmi: ${e.npmi.toFixed(2)})`}).join(", ");log(`[CO-CHANGE] Files frequently modified with ${filePath}: ${partnerList}`)})}init_utils();init_bun_compat();init_utils2();function parseDarkMatterGaps(content){let unresolved=[],resolved=[],lines=content.split(`
5938
5938
  `);for(let line of lines){let unresolvedMatch=line.match(/^-\s+\[\s*\]\s*(.+)$/);if(unresolvedMatch){unresolved.push(unresolvedMatch[1].trim());continue}let resolvedMatch=line.match(/^-\s+\[x\]\s*(.+)$/i);if(resolvedMatch)resolved.push(resolvedMatch[1].trim())}return{unresolved,resolved}}async function readDarkMatterMd(directory){let filePath=validateSwarmPath(directory,"dark-matter.md"),file3=bunFile(filePath);try{let content=await file3.text();if(!content||!content.trim())return null;return parseDarkMatterGaps(content)}catch{return null}}function createDarkMatterDetectorHook(directory){let callCount=0;async function hook(_input,_output){if(callCount++,callCount%10!==0)return;let gaps=await readDarkMatterMd(directory);if(!gaps||gaps.unresolved.length===0)return;let count=gaps.unresolved.length;log(`[DARK-MATTER] ${count} unresolved coupling gap(s) in .swarm/dark-matter.md. Run /swarm dark-matter to review.`);let displayGaps=gaps.unresolved.slice(0,3);for(let description of displayGaps)log(` - ${description}`);if(count>3)log(` - ... and ${count-3} more`)}return safeHook(hook)}import{appendFile as appendFile21,mkdir as mkdir44}from"node:fs/promises";import*as path194 from"node:path";init_task_file();init_logger();init_knowledge_link();init_knowledge_store();var import_proper_lockfile12=__toESM(require_proper_lockfile(),1);import{existsSync as existsSync99}from"node:fs";import{appendFile as appendFile19,mkdir as mkdir43,readFile as readFile43}from"node:fs/promises";import*as path193 from"node:path";function resolveApplicationLogPath(directory){return path193.join(resolveKnowledgeStoreDir(directory),"knowledge-application.jsonl")}var MAX_LEGACY_APPLICATION_LOG_ENTRIES=5000,ACK_PATTERN=/KNOWLEDGE_(APPLIED|IGNORED|VIOLATED|N_A)\s*:\s*([0-9a-fA-F-]{8,64})(?:\s+reason\s*=\s*([^\n\r]+?)(?=$|[\n\r]|\s+KNOWLEDGE_))?(?=[^0-9a-fA-F-]|$)/g;function parseAcknowledgments(text){if(!text||typeof text!=="string")return[];let out=[];for(let m of text.matchAll(ACK_PATTERN)){let verb=m[1].toLowerCase(),id=m[2],reason=m[3]?.trim().slice(0,280),result=verb==="applied"?"applied":verb==="ignored"?"ignored":verb==="n_a"?"n_a":"violated";out.push({id,result,reason})}return out}async function appendAudit(directory,record3){let filePath=resolveApplicationLogPath(directory),dirPath=path193.dirname(filePath);await mkdir43(dirPath,{recursive:!0});let release;try{release=await import_proper_lockfile12.default.lock(dirPath,{retries:{retries:50,minTimeout:10,maxTimeout:100},stale:5000}),await appendFile19(filePath,`${JSON.stringify(record3)}
@@ -1,3 +1,4 @@
1
+ import { type ModelOverride } from '../../utils/model-dispatch-fallback';
1
2
  import { type LaneEvidence, listLaneEvidence, readPhaseEvidence, type ValidationArtifact } from './evidence';
2
3
  /**
3
4
  * Configuration options for phase critic dispatch.
@@ -113,7 +114,7 @@ export declare const _internals: {
113
114
  compileCriticPackage: typeof compileCriticPackage;
114
115
  parseCriticVerdict: typeof parseCriticVerdict;
115
116
  writeCriticEvidence: typeof writeCriticEvidence;
116
- dispatchCriticAgent: (directory: string, pkg: CriticPackage, agentName: string, timeoutMs: number, parentSessionId?: string) => Promise<string>;
117
+ dispatchCriticAgent: (directory: string, pkg: CriticPackage, agentName: string, timeoutMs: number, parentSessionId?: string, model?: ModelOverride) => Promise<string>;
117
118
  resolveDefaultCriticAgent: typeof resolveDefaultCriticAgent;
118
119
  readReviewerEvidence: typeof readReviewerEvidence;
119
120
  listLaneEvidence: typeof listLaneEvidence;
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Issue #1905: shared "inline fallback advancer" for bespoke dispatch loops that
3
+ * cannot use {@link dispatchWithModelFallback} because their retry semantics
4
+ * differ (e.g. retry-on-permanent, per-attempt session lifecycle, consecutive-
5
+ * failure counters).
6
+ *
7
+ * Before this helper, the advance block (resolve next → advance index → parse
8
+ * → skip-on-malformed → tag quota/transient reason → notify) was inlined in
9
+ * `src/full-auto/oversight.ts:543–579`. Issue #1905 adds a second copy at
10
+ * `src/hooks/full-auto-intercept.ts` (`dispatchCriticAndWriteEvent`). Extracting
11
+ * the block prevents the two copies from drifting — a future fix to the
12
+ * increment-before-parse ordering or the malformed-skip semantics applies to both.
13
+ *
14
+ * The helper is PURE: it resolves, parses, and classifies, then returns the
15
+ * result + invokes an `onAdopt` side-effect callback. It does NOT touch caller
16
+ * state (the loop's `modelOverride` / `modelUsedLabel` / `modelFallbackIndex`
17
+ * stay in the caller).
18
+ */
19
+ import { type ModelOverride } from './model-dispatch-fallback';
20
+ export interface AdvanceInlineFallbackOptions {
21
+ /**
22
+ * Resolve the 1-based fallback model as a `provider/model` string, or null
23
+ * when the fallback chain is exhausted. Typically wraps
24
+ * `resolveFallbackModel(baseRole, index, getSwarmAgents(swarmId))`.
25
+ */
26
+ resolveFallback: (fallbackIndex: number) => string | null;
27
+ /** Current fallback index (0 = primary / registered model). */
28
+ index: number;
29
+ /** The error from the just-failed attempt — used to tag the reason. */
30
+ lastError: unknown;
31
+ /**
32
+ * Notified when a fallback model is cleanly adopted (for advisory logging
33
+ * and telemetry). NOT called when the chain is exhausted or the entry is
34
+ * malformed. The adopted override is returned in the result's `adopted`
35
+ * field — callers read it there, not from this callback, so the info
36
+ * payload intentionally omits the parsed `ModelOverride` (it would be
37
+ * redundant with `result.adopted.override`).
38
+ */
39
+ onAdopt: (info: {
40
+ toModel: string;
41
+ fallbackIndex: number;
42
+ reason: 'quota' | 'transient_model_error';
43
+ }) => void;
44
+ }
45
+ export interface AdvanceInlineFallbackResult {
46
+ /** The new fallback index (always >= the input `index`). */
47
+ nextIndex: number;
48
+ /**
49
+ * The adopted fallback's raw string + parsed override, or `null` when no
50
+ * new model was adopted (chain exhausted OR malformed entry skipped).
51
+ *
52
+ * When `null`, the caller must NOT change its current `modelOverride` — the
53
+ * next retry continues on the same model. The index may still have advanced
54
+ * (malformed-entry skip case) so the entry is not re-resolved.
55
+ */
56
+ adopted: {
57
+ modelString: string;
58
+ override: ModelOverride;
59
+ } | null;
60
+ }
61
+ /**
62
+ * Advance the inline fallback chain by one step. Encapsulates the
63
+ * increment-before-parse + malformed-skip + reason-tagging logic shared by
64
+ * the bespoke dispatch loops in `oversight.ts` and `full-auto-intercept.ts`.
65
+ *
66
+ * Behavior:
67
+ * - Chain exhausted (`resolveFallback(index + 1)` returns null):
68
+ * `{ nextIndex: index, adopted: null }` — keep retrying the current model.
69
+ * - Malformed entry (`parseModelString` throws or returns undefined):
70
+ * `{ nextIndex: index + 1, adopted: null }` — index advances (so the entry
71
+ * is not re-resolved next retry) but the override is NOT changed.
72
+ * - Clean entry: `{ nextIndex: index + 1, adopted: { modelString, override } }`
73
+ * — `onAdopt` is called with the quota/transient reason for side effects.
74
+ */
75
+ export declare function advanceInlineFallback(opts: AdvanceInlineFallbackOptions): AdvanceInlineFallbackResult;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.127.1",
3
+ "version": "7.128.0",
4
4
  "description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",