opencode-swarm 7.127.0 → 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.
- package/.opencode/skills/swarm-pr-feedback/SKILL.md +2 -2
- package/.opencode/skills/swarm-pr-review/SKILL.md +3 -2
- package/dist/cli/{curator-llm-factory-xmwgrfr0.js → curator-llm-factory-rz4cbq28.js} +1 -1
- package/dist/cli/{curator-x0sqv6ye.js → curator-x5dzf1p7.js} +1 -1
- package/dist/cli/{guardrail-explain-g3tgjv9a.js → guardrail-explain-fwvxteqe.js} +2 -2
- package/dist/cli/{hive-promoter-d11sk30x.js → hive-promoter-z8gc80zq.js} +1 -1
- package/dist/cli/{index-hjkczwqm.js → index-nmedh7bw.js} +2 -2
- package/dist/cli/{index-fcsnw12w.js → index-npycj2tr.js} +9 -9
- package/dist/cli/{index-xq0etzbh.js → index-rczj39pc.js} +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/hooks/auto-review.d.ts +9 -1
- package/dist/hooks/pr-workflow-response-gate.d.ts +7 -5
- package/dist/index.js +18 -16
- package/dist/turbo/lean/integration.d.ts +2 -1
- package/dist/utils/inline-fallback-advancer.d.ts +75 -0
- package/package.json +1 -1
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.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
|
|
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&¤tCheckSet!==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"&¤t.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&¤t.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&¤tChecks.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&¶ms.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(
|
|
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();
|
|
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&¶ms.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"&¶ms.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"&¶ms.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(
|
|
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(
|
|
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)}
|
|
@@ -5981,9 +5981,11 @@ ${promptRaw}`,log("[delegate-directive-injection] injected",{caller_agent:caller
|
|
|
5981
5981
|
${errorSummary}`)}}}}init_file_locks();init_state2();init_utils();init_core3();init_merge();import*as fs112 from"node:fs";import*as fsPromises10 from"node:fs/promises";import*as path197 from"node:path";var INIT_ORPHAN_RECOVERY_TIMEOUT_MS=1e4,ORPHAN_RECOVERY_LOCK_FILE=".swarm/locks/init-orphan-recovery.lock",_internals128={rmSync:fs112.rmSync,removeWorktree,isLocked,listActiveLocks,tryAcquireLock};async function writeAdvisoryFile(directory,cleanupResult,warnings,attempted,removedWorktrees=[]){let advisoryPath=path197.join(directory,".swarm","advisories","init-orphan-recovery.json"),advisory={initTimestamp:new Date().toISOString(),warnings,errors:cleanupResult.errors,reclaimed:{removedBranches:cleanupResult.removed,removedWorktrees,prunedWorktrees:attempted}};try{await fsPromises10.mkdir(path197.dirname(advisoryPath),{recursive:!0}),await fsPromises10.writeFile(advisoryPath,JSON.stringify(advisory,null,2),"utf-8")}catch{log("initOrphanRecovery advisory file write failed (non-fatal)")}}async function enumerateOrphanedWorktreeDirs(directory,activeSessionIds){let orphanedDirs=[],worktreeRoot=path197.resolve(path197.dirname(directory),".swarm-worktrees"),entries;try{entries=await fsPromises10.readdir(worktreeRoot,{withFileTypes:!0})}catch{return[]}for(let entry of entries){if(!entry.isDirectory())continue;let sessionId=entry.name;if(activeSessionIds.includes(sessionId))continue;let sessionEntries;try{sessionEntries=await fsPromises10.readdir(path197.join(worktreeRoot,sessionId),{withFileTypes:!0})}catch{continue}for(let laneEntry of sessionEntries){if(!laneEntry.isDirectory())continue;let worktreePath=path197.join(worktreeRoot,sessionId,laneEntry.name);orphanedDirs.push(worktreePath)}}return orphanedDirs}async function isCrossProcessLockHeld(directory){if(_internals128.isLocked(directory,ORPHAN_RECOVERY_LOCK_FILE))return!0;if(_internals128.listActiveLocks(directory).length>0)return!0;return!1}async function removeOrphanedWorktreeDir(worktreePath,projectRoot){let removeResult=await _internals128.removeWorktree(worktreePath,projectRoot);if(!("error"in removeResult))return;try{_internals128.rmSync(worktreePath,{recursive:!0,force:!0});return}catch{return removeResult.error}}async function runInitOrphanRecovery(directory){let result,activeSessionIds=Array.from(swarmState.agentSessions.keys());try{if(await isCrossProcessLockHeld(directory)){let orphanedWorktreeDirs=await withTimeout(enumerateOrphanedWorktreeDirs(directory,activeSessionIds),INIT_ORPHAN_RECOVERY_TIMEOUT_MS,Error(`runInitOrphanRecovery exceeded ${INIT_ORPHAN_RECOVERY_TIMEOUT_MS}ms budget during worktree enumeration; continuing without orphan reclamation`)),orphanedBranches=[];return result={attempted:!0,crossProcessLockHeld:!0,warnings:["Cross-process lock held — another opencode process may be active. "+`Skipping destructive cleanup to preserve its worktrees/branches. Detected ${orphanedWorktreeDirs.length} orphaned worktree dir(s). Run '/swarm status' or check '.swarm/locks/' to identify active processes.`],orphanedBranches,removedWorktrees:[],prunedWorktrees:!1},await writeAdvisoryFile(directory,{removed:[],skipped:orphanedBranches,errors:[]},result.warnings,!1,[]),result}let lockAcquireResult=await _internals128.tryAcquireLock(directory,ORPHAN_RECOVERY_LOCK_FILE,"init-orphan-recovery","init");if(!lockAcquireResult.acquired)return result={attempted:!0,crossProcessLockHeld:!0,warnings:["Cross-process lock acquired by another process during init — "+`skipping destructive cleanup to preserve its worktrees/branches. Detected ${(await withTimeout(enumerateOrphanedWorktreeDirs(directory,activeSessionIds),INIT_ORPHAN_RECOVERY_TIMEOUT_MS,Error(`runInitOrphanRecovery exceeded ${INIT_ORPHAN_RECOVERY_TIMEOUT_MS}ms budget during worktree enumeration; continuing without orphan reclamation`))).length} orphaned worktree dir(s).`],orphanedBranches:[],removedWorktrees:[],prunedWorktrees:!1},await writeAdvisoryFile(directory,{removed:[],skipped:[],errors:[]},result.warnings,!1,[]),result;try{let orphanedWorktreeDirs=await withTimeout(enumerateOrphanedWorktreeDirs(directory,activeSessionIds),INIT_ORPHAN_RECOVERY_TIMEOUT_MS,Error(`runInitOrphanRecovery exceeded ${INIT_ORPHAN_RECOVERY_TIMEOUT_MS}ms budget during worktree enumeration; continuing without orphan reclamation`)),removedWorktrees=[],worktreeWarnings=[];for(let worktreePath of orphanedWorktreeDirs){let error93=await removeOrphanedWorktreeDir(worktreePath,directory);if(error93)worktreeWarnings.push(`Could not reclaim orphaned worktree "${worktreePath}": ${error93}`);else removedWorktrees.push(worktreePath)}let cleanupResult=await withTimeout(cleanupOrphanedBranches(directory,activeSessionIds),INIT_ORPHAN_RECOVERY_TIMEOUT_MS,Error(`runInitOrphanRecovery exceeded ${INIT_ORPHAN_RECOVERY_TIMEOUT_MS}ms budget during branch cleanup; continuing without orphan reclamation`)),branchWarnings=cleanupResult.errors.map((e)=>`Could not delete orphaned branch "${e.branch}": ${e.error}`),allWarnings=[...worktreeWarnings,...branchWarnings];result={attempted:!0,crossProcessLockHeld:!1,warnings:allWarnings,orphanedBranches:cleanupResult.removed,removedWorktrees,prunedWorktrees:!0},await writeAdvisoryFile(directory,cleanupResult,allWarnings,!0,removedWorktrees)}finally{try{await lockAcquireResult.lock._release?.()}catch{}}}catch(err){let msg=err instanceof Error?err.message:String(err);log("initOrphanRecovery timed out or failed (non-fatal)",{error:msg}),result={attempted:!1,crossProcessLockHeld:!1,warnings:[`Orphan recovery timed out or failed: ${msg}`],orphanedBranches:[],removedWorktrees:[],prunedWorktrees:!1,diagnostic:{file:".swarm/advisories/init-orphan-recovery.json",reason:msg}},await writeAdvisoryFile(directory,{removed:[],skipped:[],errors:[]},result.warnings,!1,[])}return result}init_state2();import*as fs113 from"node:fs/promises";import*as path198 from"node:path";var ADVISORY_FILENAME="init-orphan-recovery.json";function createInitOrphanRecoveryAdvisoryHook(directory){let consumedBySession=new Set;async function readAdvisoryFile(){let advisoryPath=path198.join(directory,".swarm","advisories",ADVISORY_FILENAME);try{let content=await fs113.readFile(advisoryPath,"utf-8");return JSON.parse(content)}catch{return null}}async function deleteAdvisoryFile(){let advisoryPath=path198.join(directory,".swarm","advisories",ADVISORY_FILENAME);try{await fs113.unlink(advisoryPath)}catch{}}function formatError3(error93){return`ORPHAN_RECOVERY_ERROR: Could not reclaim branch "${error93.branch}": ${error93.error}`}async function messagesTransform(_input,output){let messages=output.messages;if(!messages||messages.length===0)return;let sessionId=messages[messages.length-1]?.info?.sessionID;if(!sessionId)return;let activeAgent=swarmState.activeAgent.get(sessionId),session=swarmState.agentSessions.get(sessionId),ORCHESTRATOR_NAME2="Architect";if(!(activeAgent?activeAgent===ORCHESTRATOR_NAME2||activeAgent.endsWith("_Architect"):session?session.agentName===ORCHESTRATOR_NAME2||session.agentName.endsWith("_Architect"):!1))return;if(consumedBySession.has(sessionId))return;let advisory=await readAdvisoryFile();if(!advisory)return;consumedBySession.add(sessionId),await deleteAdvisoryFile();let targetSession=ensureAgentSession(sessionId);targetSession.pendingAdvisoryMessages??=[];let timestamp=advisory.initTimestamp?new Date(advisory.initTimestamp).toLocaleString():"unknown";targetSession.pendingAdvisoryMessages.push(`[INIT ORPHAN RECOVERY] Plugin init detected the following at ${timestamp}:`);for(let warning of advisory.warnings)targetSession.pendingAdvisoryMessages.push(` WARNING: ${warning}`);for(let err of advisory.errors)targetSession.pendingAdvisoryMessages.push(` ERROR: ${formatError3(err)}`);let reclaimed=advisory.reclaimed;if(reclaimed.removedBranches.length>0)targetSession.pendingAdvisoryMessages.push(` Reclaimed ${reclaimed.removedBranches.length} orphaned branch(es): ${reclaimed.removedBranches.join(", ")}`);if(reclaimed.removedWorktrees&&reclaimed.removedWorktrees.length>0)targetSession.pendingAdvisoryMessages.push(` Reclaimed ${reclaimed.removedWorktrees.length} orphaned worktree directory(ies): ${reclaimed.removedWorktrees.join(", ")}`);if(reclaimed.prunedWorktrees)targetSession.pendingAdvisoryMessages.push(" Stale worktree metadata pruned.")}return{messagesTransform}}init_delegation_gate();import*as fs114 from"node:fs";import*as path200 from"node:path";function computeNextMode(params){let{issueReference,traceState,workflowArtifacts}=params,noop={nextMode:null,directive:null,nextLastTransition:traceState.lastTransition,nextCompleted:traceState.completed};if(!issueReference||issueReference.flags.trace!==!0)return noop;if(traceState.completed)return noop;if(workflowArtifacts.specIssueNumber===null||workflowArtifacts.specIssueNumber!==issueReference.number||traceState.issueNumber!==issueReference.number)return noop;if(!workflowArtifacts.specExists)return noop;if(!workflowArtifacts.planExists&&(traceState.lastTransition===null||traceState.lastTransition==="ISSUE_INGEST_TO_PLAN")){if(traceState.lastTransition==="ISSUE_INGEST_TO_PLAN")return noop;return{nextMode:"PLAN",directive:null,nextLastTransition:"ISSUE_INGEST_TO_PLAN",nextCompleted:!1}}if(!workflowArtifacts.criticApproved)return noop;if(workflowArtifacts.planExists&&!workflowArtifacts.allPhasesComplete){if(traceState.lastTransition==="PLAN_TO_EXECUTE")return noop;return{nextMode:"EXECUTE",directive:null,nextLastTransition:"PLAN_TO_EXECUTE",nextCompleted:!1}}if(!workflowArtifacts.planExists)return noop;if(traceState.lastTransition==="EXECUTE_TO_COMMIT")return noop;return{nextMode:null,directive:"All phases complete. Compose commit-pr to publish the PR. Read .swarm/issue-reference.json for Closes #N.",nextLastTransition:"EXECUTE_TO_COMMIT",nextCompleted:!0}}init_manager();import{existsSync as existsSync103,mkdirSync as mkdirSync49,readFileSync as readFileSync76,renameSync as renameSync31,unlinkSync as unlinkSync31,writeFileSync as writeFileSync34}from"node:fs";import*as path199 from"node:path";async function _defaultLoadPlanFromLedger(directory){return loadPlanJsonOnly(directory)}var _internals129={readFileSync:readFileSync76,writeFileSync:writeFileSync34,existsSync:existsSync103,renameSync:renameSync31,mkdirSync:mkdirSync49,unlinkSync:unlinkSync31,loadPlanFromLedger:_defaultLoadPlanFromLedger};function isPhaseComplete(status){return status==="complete"||status==="completed"}function isValidIssueReference(obj){if(typeof obj!=="object"||obj===null)return!1;let o=obj;if(typeof o.url!=="string"||!o.url.startsWith("https://github.com/"))return!1;return typeof o.owner==="string"&&typeof o.repo==="string"&&typeof o.number==="number"&&typeof o.timestamp==="string"&&typeof o.flags==="object"&&o.flags!==null}function isValidTraceState(obj){if(typeof obj!=="object"||obj===null)return!1;let o=obj;return typeof o.issueNumber==="number"&&(o.lastTransition===null||typeof o.lastTransition==="string")&&typeof o.completed==="boolean"}function readIssueReference(directory){try{let filePath=path199.join(directory,".swarm","issue-reference.json"),raw=_internals129.readFileSync(filePath,"utf-8"),parsed=JSON.parse(raw);if(!isValidIssueReference(parsed))return null;return parsed}catch{return null}}function readTraceState(directory){let defaultState={issueNumber:0,lastTransition:null,completed:!1};try{let filePath=path199.join(directory,".swarm","issue-trace-state.json"),raw=_internals129.readFileSync(filePath,"utf-8"),parsed=JSON.parse(raw);if(!isValidTraceState(parsed))return defaultState;return parsed}catch{return defaultState}}function writeTraceState(directory,state){let swarmDir=path199.join(directory,".swarm");_internals129.mkdirSync(swarmDir,{recursive:!0});let finalPath=path199.join(swarmDir,"issue-trace-state.json"),tmpPath=path199.join(swarmDir,`issue-trace-state.tmp.${process.pid}.${Date.now()}.json`);_internals129.writeFileSync(tmpPath,JSON.stringify(state,null,2),"utf-8");try{_internals129.renameSync(tmpPath,finalPath)}catch{try{_internals129.unlinkSync(finalPath)}catch{}try{_internals129.renameSync(tmpPath,finalPath)}catch(retryErr){try{_internals129.unlinkSync(tmpPath)}catch{}throw retryErr}}}function readSpecIssueNumber(directory){try{let filePath=path199.join(directory,".swarm","spec.md"),raw=_internals129.readFileSync(filePath,"utf-8"),sectionStart=raw.indexOf("## Source Issue");if(sectionStart===-1)return null;let nextHeading=raw.indexOf(`
|
|
5982
5982
|
## `,sectionStart+14),sectionEnd=nextHeading===-1?raw.length:nextHeading,section=raw.slice(sectionStart,sectionEnd),numberMatch=section.match(/-\s+Number:\s*(\d+)/);if(numberMatch)return parseInt(numberMatch[1],10);let urlMatch=section.match(/-\s+URL:.*\/issues\/(\d+)/);if(urlMatch)return parseInt(urlMatch[1],10);return null}catch{return null}}async function readPlanPhaseStatus(directory){let plan=await _internals129.loadPlanFromLedger(directory);if(!plan||plan.phases.length===0)return{allComplete:!1};return{allComplete:plan.phases.every((phase)=>isPhaseComplete(phase.status))}}function specExists(directory){return _internals129.existsSync(path199.join(directory,".swarm","spec.md"))}function planExists(directory){return _internals129.existsSync(path199.join(directory,".swarm","plan.json"))}var _internals130={readIssueReference,readTraceState,writeTraceState,readSpecIssueNumber,readPlanPhaseStatus,specExists,planExists,isPlanCriticApproved},cachedApproval=null;async function boundedApprovalCheck(directory,timeoutMs){try{let ledgerPath=path200.join(directory,".swarm","plan-ledger.jsonl"),currentSize=-1;try{currentSize=fs114.statSync(ledgerPath).size}catch{let timeout=new Promise((resolve71)=>{setTimeout(()=>resolve71(!1),timeoutMs)});return await Promise.race([_internals130.isPlanCriticApproved(directory),timeout])}if(cachedApproval&&cachedApproval.dir===directory&&cachedApproval.size===currentSize)return cachedApproval.result;let timer;try{let timeout=new Promise((resolve71)=>{timer=setTimeout(()=>resolve71(!1),timeoutMs)}),result=await Promise.race([_internals130.isPlanCriticApproved(directory),timeout]);return cachedApproval={dir:directory,size:currentSize,result},result}finally{if(timer!==void 0)clearTimeout(timer)}}catch{return!1}}function createIssueTraceHook(_config,directory,approvalTimeoutMs=5000){return{messagesTransform:async(_input,output)=>{try{let issueRef=_internals130.readIssueReference(directory);if(!issueRef||issueRef.flags.trace!==!0)return;let traceState=_internals130.readTraceState(directory),_specExists=_internals130.specExists(directory),_specIssueNumber=_internals130.readSpecIssueNumber(directory),_planExists=_internals130.planExists(directory),_criticApproved=await boundedApprovalCheck(directory,approvalTimeoutMs),_allPhasesComplete=(await _internals130.readPlanPhaseStatus(directory)).allComplete,result=computeNextMode({issueReference:issueRef,traceState,workflowArtifacts:{specExists:_specExists,specIssueNumber:_specIssueNumber,planExists:_planExists,criticApproved:_criticApproved,allPhasesComplete:_allPhasesComplete}});if(result.nextMode===null&&result.directive===null)return;let finalDirective=result.directive?result.directive.replace("#N",`#${issueRef.number}`):null,messagesToAdd=[];if(result.nextMode!==null)messagesToAdd.push({role:"system",content:[{type:"text",text:`[MODE: ${result.nextMode}]`}]});if(finalDirective!==null)messagesToAdd.push({role:"system",content:[{type:"text",text:finalDirective}]});_internals130.writeTraceState(directory,{issueNumber:traceState.issueNumber,lastTransition:result.nextLastTransition,completed:result.nextCompleted});let out=output;if(out.messages)out.messages.push(...messagesToAdd)}catch{}}}}init_schema();init_state2();init_logger();import{appendFile as appendFile22,mkdir as mkdir46}from"node:fs/promises";import*as path201 from"node:path";var HIGH_RISK_TOOLS=new Set(["save_plan","update_task_status","phase_complete","task","Task","skill_regenerate","skill_retire"]),DEFAULT_MAX_GATE_DENIALS=5,DEFAULT_GATE_STALENESS_MS=600000;async function knowledgeApplicationGateBefore(directory,input,config3){if(!config3.enabled)return;let toolName=typeof input.tool==="string"?input.tool:"";if(!(config3.high_risk_tools?new Set(config3.high_risk_tools):HIGH_RISK_TOOLS).has(toolName))return;let agentRaw=typeof input.agent==="string"?input.agent:"";if(!agentRaw)return;if(stripKnownSwarmPrefix(agentRaw)!=="architect")return;let sessionID=typeof input.sessionID==="string"?input.sessionID:void 0;if(!sessionID){if(config3.mode==="enforce")throw Error("KNOWLEDGE_ENFORCE_GATE_DENY: missing sessionID on tool.execute.before; refusing to evaluate critical-directive ack state");_internals131.writeWarnEvent(directory,{timestamp:new Date().toISOString(),event:"knowledge_application_gate_warn",tool:toolName,agent:agentRaw,reason:"missing_sessionID",mode:config3.mode}).catch(()=>{});return}let cached3=swarmState.currentCriticalShownIds.get(sessionID);if(!cached3||cached3.ids.length===0){clearGateDenialCount(sessionID);return}let ackedIds=new Set;for(let id of cached3.ids)for(let result of["applied","ignored","violated"]){let key=buildAckDedupKey(sessionID,id,result);if(swarmState.knowledgeAckDedup.has(key)){ackedIds.add(id);break}}let unacked=cached3.ids.filter((id)=>!ackedIds.has(id));if(unacked.length===0){clearGateDenialCount(sessionID);return}if(config3.mode==="enforce"&&config3.critical_requires_ack){let maxDenials=config3.max_gate_denials??DEFAULT_MAX_GATE_DENIALS,stalenessMs=config3.gate_staleness_ms??DEFAULT_GATE_STALENESS_MS,age=Date.now()-cached3.generatedAt;if(age>stalenessMs){for(let id of unacked)addKnowledgeAckDedup(buildAckDedupKey(sessionID,id,"applied"));clearCriticalShownIds(sessionID),clearGateDenialCount(sessionID),await writeWarnEvent2(directory,{timestamp:new Date().toISOString(),event:"knowledge_application_gate_staleness_clear",tool:toolName,agent:agentRaw,sessionID,cleared_ids:unacked,age_ms:age,staleness_threshold_ms:stalenessMs}).catch((err)=>{warn(`[knowledge-application-gate] staleness-clear audit write failed: ${err instanceof Error?err.message:String(err)}`)});return}let directiveKey=buildGateDenialDirectiveKey(cached3.ids),denials=incrementGateDenialCount(sessionID,directiveKey);if(denials>maxDenials){for(let id of unacked)addKnowledgeAckDedup(buildAckDedupKey(sessionID,id,"applied"));clearCriticalShownIds(sessionID),clearGateDenialCount(sessionID),await writeWarnEvent2(directory,{timestamp:new Date().toISOString(),event:"knowledge_application_gate_denial_limit_clear",tool:toolName,agent:agentRaw,sessionID,cleared_ids:unacked,denial_count:denials,max_gate_denials:maxDenials}).catch((err)=>{warn(`[knowledge-application-gate] denial-limit-clear audit write failed: ${err instanceof Error?err.message:String(err)}`)});return}let ids=unacked.join(", ");throw Error(`KNOWLEDGE_ENFORCE_GATE_DENY: ${toolName} blocked — critical knowledge directive(s) ${ids} require KNOWLEDGE_APPLIED:<id>, KNOWLEDGE_IGNORED:<id> reason=..., or KNOWLEDGE_VIOLATED:<id> reason=... before this action.`)}writeWarnEvent2(directory,{timestamp:new Date().toISOString(),event:"knowledge_application_gate_warn",tool:toolName,agent:agentRaw,sessionID,unacknowledged_critical_ids:unacked}).catch(()=>{})}async function writeWarnEvent2(directory,record3){let filePath=path201.join(directory,".swarm","events.jsonl");await mkdir46(path201.dirname(filePath),{recursive:!0}),await appendFile22(filePath,`${JSON.stringify(record3)}
|
|
5983
5983
|
`,"utf-8")}async function knowledgeApplicationTransformScan(directory,output,sessionID){if(!output?.messages)return;if(!sessionID)return;let target;for(let i=output.messages.length-1;i>=0;i--){let m=output.messages[i],agent=m.info?.agent;if(typeof agent==="string"&&stripKnownSwarmPrefix(agent)==="architect"){target=m;break}}if(!target)return;let text=(target.parts??[]).map((p)=>typeof p.text==="string"?p.text:"").join(`
|
|
5984
|
-
`);if(!text)return;let acks=parseAcknowledgments(text);if(acks.length===0)return;let ctx={sessionId:sessionID};for(let ack of acks){let key=buildAckDedupKey(sessionID,ack.id,ack.result);if(swarmState.knowledgeAckDedup.has(key))continue;addKnowledgeAckDedup(key);try{await recordAcknowledgment(directory,ack,ctx)}catch(err){warn(`[knowledge-application-gate] transform-scan record failed: ${err instanceof Error?err.message:String(err)}`)}}}var _internals131={knowledgeApplicationGateBefore,knowledgeApplicationTransformScan,HIGH_RISK_TOOLS,writeWarnEvent:writeWarnEvent2};init_knowledge_curator();init_micro_reflector();init_normalize_tool_name();init_pr_subscriptions();init_utils();init_stored_input_args();init_normalize_tool_name();var MAX_OUTPUT_SCAN_BYTES=65536,PR_URL_PATTERN=/https:\/\/github\.com\/([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+)\/pull\/(\d+)/,_internals132={subscribe,log};function extractPrUrl(text){let match=PR_URL_PATTERN.exec(text.slice(0,MAX_OUTPUT_SCAN_BYTES));if(!match)return null;let owner=match[1],repo=match[2],prNumber=Number.parseInt(match[3],10);if(!Number.isSafeInteger(prNumber)||prNumber<=0)return null;return{repoFullName:`${owner}/${repo}`,prNumber,prUrl:`https://github.com/${owner}/${repo}/pull/${prNumber}`}}function createPrAutoSubscribeHook(directory,config3){return{toolAfter:async(input,output)=>{try{if(!config3.enabled||!config3.auto_subscribe_on_pr_create)return;let sessionID=typeof input.sessionID==="string"?input.sessionID.trim():"";if(!sessionID)return;let tool3=normalizeToolNameLowerCase(input.tool??"");if(tool3!=="bash"&&tool3!=="shell")return;let args2=(typeof input.callID==="string"?getStoredInputArgs(input.callID):void 0)??input.args??output.args;if(!(typeof args2?.command==="string"?args2.command:"").includes("gh pr create"))return;let outputText2=typeof output.output==="string"?output.output:"";if(!outputText2)return;let prInfo=extractPrUrl(outputText2);if(!prInfo)return;await _internals132.subscribe(directory,{sessionID,prNumber:prInfo.prNumber,repoFullName:prInfo.repoFullName,prUrl:prInfo.prUrl,maxSubscriptions:config3.max_subscriptions}),_internals132.log("[pr-monitor] Auto-subscribed session to created PR",{sessionID,pr:`${prInfo.repoFullName}#${prInfo.prNumber}`})}catch(err){_internals132.log("[pr-monitor] Auto-subscribe failed (non-fatal)",{error:err instanceof Error?err.message:String(err)})}}}}init_pr_workflow_gate();init_pr_workflow_auto_wake();init_pr_workflow_gate();var DEFAULT_WAKE_TIMEOUT_MS=5000,_internals133={readPrWorkflowGateState},DEFAULT_MAX_CONSECUTIVE_UNPRODUCTIVE_WAKES=5,DEFAULT_WAKE_COOLDOWN_MS=30000,MAX_TRACKED_WAKE_SESSIONS=200;function blockedText(mode,options={}){let lines=[`[${mode}
|
|
5985
|
-
`)}function createPrWorkflowResponseGate(options){let wakeTimeoutMs=options.wakeTimeoutMs??DEFAULT_WAKE_TIMEOUT_MS,maxConsecutive=options.maxConsecutiveUnproductiveWakes??DEFAULT_MAX_CONSECUTIVE_UNPRODUCTIVE_WAKES,wakeCooldownMs=options.wakeCooldownMs??DEFAULT_WAKE_COOLDOWN_MS,activeWakeSessions=new Set,wakeBudgets=new Map,session=options.client?.session;function evictIfOverBound(){while(wakeBudgets.size>MAX_TRACKED_WAKE_SESSIONS){let oldestKey=wakeBudgets.keys().next().value;if(oldestKey===void 0)break;wakeBudgets.delete(oldestKey)}}function resetBudget(sessionID){wakeBudgets.delete(sessionID)}return{event:async(input)=>{let wakeDecision=await observePrWorkflowAutoWakeEvent(options.directory,input.event),event2=input.event,sessionID=event2?.properties?.sessionID??event2?.data?.sessionID;if(event2?.type!=="session.idle"||typeof sessionID!=="string"||!sessionID.trim()||wakeDecision.suppressWake||activeWakeSessions.has(sessionID))return;activeWakeSessions.add(sessionID);try{let state=await _internals133.readPrWorkflowGateState(options.directory,sessionID);if(!state){resetBudget(sessionID),clearPrWorkflowAutoWakeState(options.directory,sessionID);return}if(isPrWorkflowAutoWakeSuppressed(options.directory,sessionID))return;if(!session)return;evictIfOverBound();let budget=wakeBudgets.get(sessionID);if(!budget)budget={consecutiveUnproductive:0,lastWakeAt:0,suspended:!1},wakeBudgets.set(sessionID,budget);if(budget.suspended)return;let now=Date.now();if(budget.lastSeenRevision!==void 0&&state.revision>budget.lastSeenRevision)budget.consecutiveUnproductive=0;if(budget.consecutiveUnproductive>0&&budget.lastWakeAt>0&&now-budget.lastWakeAt<wakeCooldownMs)return;let madeProgress=budget.lastSeenRevision===void 0?!0:state.revision>budget.lastSeenRevision,pluginWakeMessageID=markPrWorkflowPluginWake(options.directory,sessionID),promptRejected=!1,timer;try{let args2={path:{id:sessionID},body:{messageID:pluginWakeMessageID,parts:[{type:"text",text:`${blockedText(state.mode,{suspended:!1,maxConsecutive})}
|
|
5986
|
-
Do not stop or summarize. Inspect the durable gate, dispatch or collect the next missing required lane, and continue until complete_pr_workflow succeeds. If the bind/checkout path is genuinely unreachable, call abort_pr_workflow instead of looping.`}]}},call=session.promptAsync?session.promptAsync(args2):session.prompt(args2),result=await Promise.race([call,new Promise((_resolve,reject2)=>{timer=setTimeout(()=>reject2(Error("PR workflow resume prompt timed out")),wakeTimeoutMs)})]);if(result?.error!=null)throw promptRejected=!0,Error(`PR workflow resume prompt failed: ${String(result.error)}`)}finally{if(timer)clearTimeout(timer);if(promptRejected)cancelPrWorkflowPluginWake(options.directory,sessionID,pluginWakeMessageID);let postWakeState=await _internals133.readPrWorkflowGateState(options.directory,sessionID);if(budget.lastWakeAt=now,postWakeState===null)resetBudget(sessionID);else{let currentRevision=postWakeState.revision,effectiveMadeProgress=madeProgress||budget.lastSeenRevision!==void 0&¤tRevision>budget.lastSeenRevision;if(budget.lastSeenRevision=currentRevision,!effectiveMadeProgress){if(budget.consecutiveUnproductive+=1,budget.consecutiveUnproductive>=maxConsecutive)budget.suspended=!0}else budget.consecutiveUnproductive=0}}}finally{activeWakeSessions.delete(sessionID)}},textComplete:async(input,output)=>{if(!input.sessionID?.trim())return;let state=await _internals133.readPrWorkflowGateState(options.directory,input.sessionID);if(!state){resetBudget(input.sessionID),clearPrWorkflowAutoWakeState(options.directory,input.sessionID);return}let budget=wakeBudgets.get(input.sessionID);output.text=blockedText(state.mode,{suspended:budget?.suspended??!1,userInterrupted:isPrWorkflowAutoWakeSuppressed(options.directory,input.sessionID),maxConsecutive})},_inspectWakeBudget:(sessionID)=>wakeBudgets.get(sessionID)}}init_pending_delegations();init_pr_workflow_gate();var MAX_PARENT_DEPTH=16,MAX_TRACKED_SESSION_PARENTS=512;function rememberBounded2(parents,childSessionID,parentSessionID){parents.delete(childSessionID),parents.set(childSessionID,parentSessionID);while(parents.size>MAX_TRACKED_SESSION_PARENTS){let oldest=parents.keys().next().value;if(typeof oldest!=="string")break;parents.delete(oldest)}}function createPrWorkflowSessionResolver(options){let session=options.client?.session,parents=new Map;return{observeEvent:(input)=>{let event=input.event;if(event?.type!=="session.created"&&event?.type!=="session.updated")return;let child=event.properties?.info?.id,parent=event.properties?.info?.parentID;if(typeof child==="string"&&child.trim()&&typeof parent==="string"&&parent.trim())rememberBounded2(parents,child.trim(),parent.trim())},resolve:async(sessionID)=>{let original=sessionID.trim();if(!original)return sessionID;let current=original,visited=new Set;for(let depth=0;depth<MAX_PARENT_DEPTH;depth+=1){if(visited.has(current))break;if(visited.add(current),await readPrWorkflowGateState(options.directory,current))return current;let parent=parents.get(current);if(!parent)parent=findByCorrelationId(options.directory,current)?.parentSessionId;if(!parent&&session?.get){let result=await session.get({path:{id:current},query:{directory:options.directory}});if(result?.error==null){let candidate=result?.data?.parentID;if(typeof candidate==="string"&&candidate.trim())parent=candidate.trim()}}if(!parent)return original;rememberBounded2(parents,current,parent),current=parent}return original}}}init_schema();init_bun_compat();init_logger();var import_picomatch2=__toESM(require_picomatch2(),1);import{existsSync as existsSync104,readdirSync as readdirSync30,readFileSync as readFileSync77,statSync as statSync41}from"node:fs";import*as path202 from"node:path";var PREDICATE_TIMEOUT_MS=15000,GREP_MAX_FILES=1e4,GREP_MAX_BYTES_PER_FILE=1e6,GREP_SKIP_DIRECTORIES=new Set([".git",".swarm","node_modules","dist","coverage"]),TOOL_BINARY_ALLOWLIST=new Set(["rg","grep","git","biome","eslint","tsc","ruff"]);function validateRepoRelativeGlob(directory,value){let v=value.trim();if(!v)return null;if(v.includes("\x00"))return null;if(v.startsWith("/")||/^[A-Za-z]:[\\/]/.test(v)||v.startsWith("\\"))return null;if(v.split(/[/\\]/).some((s)=>s===".."))return null;let globStart=v.search(/[*?{[]/),concrete=globStart===-1?v:v.slice(0,globStart);if(concrete){let baseDir=path202.resolve(directory),resolved=path202.resolve(baseDir,concrete),rel=path202.relative(baseDir,resolved);if(rel.startsWith("..")||path202.isAbsolute(rel))return null}return v}function findBinaryInPath(binary){let exeName=process.platform==="win32"?`${binary}.exe`:binary;for(let dir of(process.env.PATH??"").split(path202.delimiter)){if(!dir)continue;let candidate=path202.join(dir,exeName);if(existsSync104(candidate))return candidate}return null}function safeChildEnv(){let env={};if(process.env.PATH)env.PATH=process.env.PATH;if(process.env.HOME)env.HOME=process.env.HOME;if(process.env.SystemRoot)env.SystemRoot=process.env.SystemRoot;if(process.env.TEMP)env.TEMP=process.env.TEMP;if(process.env.TMP)env.TMP=process.env.TMP;return env}async function runArgv(argv,cwd){let proc=bunSpawn(argv,{stdin:"ignore",stdout:"pipe",stderr:"pipe",cwd,env:safeChildEnv()}),finished=!1;try{let timeout=new Promise((resolve72)=>setTimeout(()=>resolve72("timeout"),PREDICATE_TIMEOUT_MS));if(await Promise.race([proc.exited,timeout])==="timeout")return{exitCode:null,stdout:"",stderr:"",timedOut:!0};let[stdout,stderr]=await Promise.all([proc.stdout.text().catch(()=>""),proc.stderr.text().catch(()=>"")]);return finished=!0,{exitCode:proc.exitCode,stdout,stderr,timedOut:!1}}finally{if(!finished)try{proc.kill()}catch{}}}async function runGrepPredicate(rest,directory){let lastColon=rest.lastIndexOf(":");if(lastColon<=0||lastColon===rest.length-1)return{result:"error",detail:"grep: expected <regex>:<path-glob>"};let regex=rest.slice(0,lastColon),rawGlob=rest.slice(lastColon+1),glob=validateRepoRelativeGlob(directory,rawGlob);if(glob===null)return{result:"error",detail:`grep: unsafe or empty path-glob "${rawGlob}"`};let pattern;try{pattern=new RegExp(regex,"m")}catch(err){return{result:"error",detail:`grep: invalid regex ${err instanceof Error?err.message:String(err)}`}}let matcher=import_picomatch2.default(glob,{dot:!0}),visited=0,matches=0,walk=(dir)=>{if(visited>=GREP_MAX_FILES)return;let entries;try{entries=readdirSync30(dir,{withFileTypes:!0})}catch{return}for(let entry of entries){if(visited>=GREP_MAX_FILES)return;let fullPath=path202.join(dir,entry.name),relPath=path202.relative(directory,fullPath).replace(/\\/g,"/");if(entry.isDirectory()){if(!GREP_SKIP_DIRECTORIES.has(entry.name))walk(fullPath);continue}if(!entry.isFile())continue;if(visited++,!matcher(relPath))continue;try{if(statSync41(fullPath).size>GREP_MAX_BYTES_PER_FILE)continue;let found=readFileSync77(fullPath,"utf-8").match(pattern);if(found)matches+=found.length}catch{}}};if(walk(directory),visited>=GREP_MAX_FILES)return{result:"error",detail:`grep: file scan exceeded ${GREP_MAX_FILES} files`};if(matches===0)return{result:"pass",detail:"grep: zero matches"};return{result:"fail",detail:`grep: ${matches} match(es) found`}}async function runToolPredicate(rest,directory){let raw=rest.trim();if(!raw)return{result:"error",detail:"tool: empty command"};if(raw.includes("\x00"))return{result:"error",detail:"tool: null byte in command"};let argvParts=raw.split(/\s+/).filter((p)=>p.length>0);if(argvParts.length===0)return{result:"error",detail:"tool: empty command"};let binary=argvParts[0];if(binary.includes("/")||binary.includes("\\"))return{result:"error",detail:`tool: path-qualified binary "${binary}" is not allowed`};if(!TOOL_BINARY_ALLOWLIST.has(binary))return{result:"error",detail:`tool: binary "${binary}" is not on the allowlist`};let resolved=findBinaryInPath(binary);if(!resolved)return{result:"error",detail:`tool: binary "${binary}" not found`};let res=await runArgv([resolved,...argvParts.slice(1)],directory);if(res.timedOut)return{result:"error",detail:"tool: timed out"};if(res.exitCode===0)return{result:"pass",detail:"tool: exit 0"};return{result:"fail",detail:`tool: exit ${res.exitCode} ${res.stderr.slice(0,200)}`}}async function changedPaths(directory){let git2=findBinaryInPath("git");if(!git2)return null;let res=await runArgv([git2,"status","--porcelain","-z"],directory);if(res.timedOut||res.exitCode!==0)return null;let out=new Set;for(let entry of res.stdout.split("\x00")){if(entry.length<=3)continue;let p=entry.slice(3);if(p)out.add(path202.normalize(p))}return out}async function runFileModifiedPredicate(rest,directory,expectModified){let label=expectModified?"file_modified":"file_not_modified",safe=validateRepoRelativeGlob(directory,rest);if(safe===null)return{result:"error",detail:`${label}: unsafe or empty path "${rest}"`};let changed=await changedPaths(directory);if(changed===null)return{result:"error",detail:`${label}: git unavailable or failed`};let target=path202.normalize(safe),isChanged=changed.has(target);return{result:(expectModified?isChanged:!isChanged)?"pass":"fail",detail:`${label}: ${target} ${isChanged?"changed":"unchanged"}`}}async function runDirectivePredicate(predicate,directory){try{if(typeof predicate!=="string"||!predicate.trim())return{result:"error",detail:"predicate: empty"};let trimmed=predicate.trim(),firstColon=trimmed.indexOf(":");if(firstColon<=0)return{result:"error",detail:"predicate: missing handler prefix (expected <handler>:...)"};let handler=trimmed.slice(0,firstColon),rest=trimmed.slice(firstColon+1);switch(handler){case"grep":return await runGrepPredicate(rest,directory);case"tool":return await runToolPredicate(rest,directory);case"file_not_modified":return await runFileModifiedPredicate(rest,directory,!1);case"file_modified":return await runFileModifiedPredicate(rest,directory,!0);default:return{result:"error",detail:`predicate: unknown handler "${handler}"`}}}catch(err){return warn(`[directive-predicate-runner] unexpected error: ${err instanceof Error?err.message:String(err)}`),{result:"error",detail:"predicate: unexpected error (fail-closed)"}}}init_knowledge_escalator();init_knowledge_events();init_skill_propagation_gate();var VERDICT_PATTERN=/\b(VERIFIED|VIOLATED|N\/A)\s*:\s*([A-Za-z0-9._-]{1,80})(?:\s+(?:evidence|reason)\s*=\s*([^\n\r]+?))?(?=$|[\n\r]|\s+(?:VERIFIED|VIOLATED|N\/A)\b)/gi;function parseReviewerDirectiveCompliance(text){if(!text||typeof text!=="string")return[];let out=[];for(let m of text.matchAll(VERDICT_PATTERN)){let verb=m[1].toUpperCase(),id=m[2],evidence=m[3]?.trim().slice(0,280),verdict=verb==="VERIFIED"?"verified":verb==="VIOLATED"?"violated":"n_a";out.push({id,verdict,evidence})}return out}function verdictToEventType(v){return v==="verified"?"applied":v==="violated"?"violated":"n_a"}async function reconcileReviewerVerdicts(params){let result={emitted:[],omittedCriticals:[]};try{let verifyById=new Map(params.directivesToVerify.map((d)=>[d.id,d]));if(verifyById.size===0)return result;let verdicts=parseReviewerDirectiveCompliance(params.transcript),addressed=new Set,violatedIds=new Set,traceId=newTraceId(),sessionId=params.sessionId??"unknown",agent=params.agent??"reviewer";for(let v of verdicts){let directive=verifyById.get(v.id);if(!directive)continue;addressed.add(v.id);let type=verdictToEventType(v.verdict),predicateCheck;if(v.verdict==="violated"&&directive.verification_predicate){let outcome=await runDirectivePredicate(directive.verification_predicate,params.directory);predicateCheck={predicate:directive.verification_predicate,result:outcome.result,detail:outcome.detail}}if(await recordKnowledgeEvent(params.directory,{type,trace_id:traceId,knowledge_id:v.id,session_id:sessionId,task_id:params.taskId,phase:params.phase,agent,source:"reviewer",reason:v.evidence,predicate_check:predicateCheck}),type==="violated")violatedIds.add(v.id);result.emitted.push({id:v.id,type,source:"reviewer"})}for(let d of params.directivesToVerify){if(d.priority!=="critical")continue;if(addressed.has(d.id))continue;result.omittedCriticals.push(d.id),await recordKnowledgeEvent(params.directory,{type:"violated",trace_id:traceId,knowledge_id:d.id,session_id:sessionId,task_id:params.taskId,phase:params.phase,agent,source:"reviewer",reason:"reviewer_omitted"}),violatedIds.add(d.id),result.emitted.push({id:d.id,type:"violated",source:"reviewer"})}if(violatedIds.size>0)await escalateViolatedEntries(params.directory,[...violatedIds])}catch{}return result}function isTaskTool6(tool3){return tool3==="Task"||tool3==="task"}async function collectReviewerVerdictsAfter(directory,input,output){if(!isTaskTool6(input.tool))return;let parsedArgs=parseDelegationArgs(input.args);if(!parsedArgs)return;if(stripKnownSwarmPrefix(parsedArgs.targetAgent).toLowerCase()!=="reviewer")return;let argsRecord=input.args&&typeof input.args==="object"?input.args:null,prompt=argsRecord&&typeof argsRecord.prompt==="string"?argsRecord.prompt:"";if(!prompt)return;let transcript=typeof output.output==="string"?output.output:"";if(!transcript)return;let directivesToVerify=parseDirectivesToVerifyBlock(prompt);if(directivesToVerify.length===0)return;let sessionId=typeof input.sessionID==="string"?input.sessionID:void 0;await reconcileReviewerVerdicts({directory,transcript,directivesToVerify,sessionId,agent:"reviewer"})}init_constants();init_schema();init_scope_binding();init_scope_persistence();init_state2();init_normalize_tool_name();init_pr_workflow_gate();init_write_target_resolver();import*as path203 from"node:path";var WRITE_TOOLS2=new Set(WRITE_TOOL_NAMES);function createScopeGuardHook(config3,directory,injectAdvisory){let enabled=config3.enabled??!0,_skipInTurbo=config3.skip_in_turbo??!1;return{toolBefore:async(input,output)=>{if(!enabled)return;let toolName=normalizeToolName(input.tool);if(!WRITE_TOOLS2.has(toolName))return;let sessionId=input.sessionID,activeAgent=swarmState.activeAgent.get(sessionId),session=swarmState.agentSessions.get(sessionId),agentName=activeAgent??session?.agentName??"unknown",agentRole=stripKnownSwarmPrefix(agentName);if(agentRole===ORCHESTRATOR_NAME)return;if(agentRole!=="coder")return;let targets=_internals134.resolveWriteTargets(toolName,output.args,{directory});if(targets.status==="unverifiable")throw Error(`WRITE TARGET UNVERIFIABLE: ${agentName} invoked ${toolName}: ${targets.reason}`);if(targets.paths.length===0)return;let taskId=_internals134.resolveTaskId(session),binding=taskId?_internals134.resolveAuthorizedScopeBinding({directory,taskId,activeSessionId:sessionId}):_internals134.resolveAuthorizedScopeBindingForSession({directory,activeSessionId:sessionId});if(!binding){if(binding=_internals134.getAuthorizedPrFeedbackScopeBinding({directory,activeSessionId:sessionId,taskId:taskId??void 0})??_internals134.resolveAuthorizedPrFeedbackScopeBindingFromDisk({directory,activeSessionId:sessionId,taskId:taskId??void 0}),binding&&!await _internals134.validatePrFeedbackScopeBinding(directory,binding))binding=null}if(!taskId&&binding&&session)taskId=binding.taskId,session.currentTaskId=binding.taskId,session.declaredCoderScope=[...binding.files];let declaredScope=binding?.files??null;if(!declaredScope||declaredScope.length===0)throw Error(`SCOPE_NOT_DECLARED: ${agentName} cannot invoke ${toolName} without a validated scope for task ${taskId??"unknown"}.`);for(let rawPath of targets.paths){let filePath=sanitizePath(rawPath);if(!isFileInScope(filePath,declaredScope,directory))reportScopeViolation(agentName,filePath,taskId,session,injectAdvisory,swarmState,declaredScope)}}}}function isFileInScope(filePath,scopeEntries,directory){let dir=directory??process.cwd(),resolvedFile=path203.resolve(dir,filePath);return scopeEntries.filter((scope)=>scope.length>0).some((scope)=>{let resolvedScope=path203.resolve(dir,scope);if(resolvedFile===resolvedScope)return!0;let rel=path203.relative(resolvedScope,resolvedFile);return rel.length>0&&!rel.startsWith("..")&&!path203.isAbsolute(rel)})}function sanitizePath(raw){let result="";for(let i=0;i<raw.length;i++){let c=raw.charCodeAt(i);if(c<=31||c===127||c>=128&&c<=159){result+="_";continue}result+=raw[i]}return result.replace(/\[[\d;]*m/g,"")}var _internals134={sanitizePath,resolveWriteTargets:resolveWriteTargets2,resolveAuthorizedScopeBinding,resolveAuthorizedScopeBindingForSession,getAuthorizedPrFeedbackScopeBinding,resolveAuthorizedPrFeedbackScopeBindingFromDisk,validatePrFeedbackScopeBinding,resolveTaskId:(session)=>session?.currentTaskId??null};function reportScopeViolation(agentName,filePath,taskId,session,injectAdvisory,state,scopeEntries){let violationMessage=`SCOPE VIOLATION: ${agentName} attempted to modify '${filePath}' which is not in declared scope for task ${taskId??"unknown"}. Declared scope: [${scopeEntries.slice(0,3).join(", ")}${scopeEntries.length>3?"...":""}]`;if(session)session.lastScopeViolation=violationMessage,session.scopeViolationDetected=!0;if(injectAdvisory)for(let[archSessionId,archSession]of state.agentSessions){let archAgent=state.activeAgent.get(archSessionId)??archSession.agentName;if(stripKnownSwarmPrefix(archAgent)===ORCHESTRATOR_NAME){try{injectAdvisory(archSessionId,`[SCOPE GUARD] ${violationMessage}`)}catch{}break}}throw Error(violationMessage)}init_constants();init_schema();init_state2();init_normalize_tool_name();function createSelfReviewHook(config3,injectAdvisory){let enabled=config3.enabled??!0,skipInTurbo=config3.skip_in_turbo??!0;return{toolAfter:async(input,output)=>{if(!enabled)return;if(normalizeToolName(input.tool)!=="update_task_status")return;let args2=output.args;if(args2?.status!=="in_progress")return;let taskId=typeof args2?.task_id==="string"?args2.task_id:"unknown",sessionId=input.sessionID,agentName=swarmState.activeAgent.get(sessionId)??swarmState.agentSessions.get(sessionId)?.agentName??"";if(stripKnownSwarmPrefix(agentName)!==ORCHESTRATOR_NAME)return;if(skipInTurbo){let session=swarmState.agentSessions.get(sessionId);if(session&&session.turboMode===!0)return}let advisory=[`[SELF-REVIEW] Task ${taskId} is now delegated to coder.`,"After coder completes, review for:"," • Broken conditionals (inverted if/else, wrong comparisons)"," • Off-by-one errors (array bounds, loop indices)"," • Assumptions contradicting existing codebase patterns"," • Missing error handling (uncaught exceptions, unhandled promises)"," • Scope creep (changes outside the declared task spec)","Delegate to critic with self-review focus before marking complete."].join(`
|
|
5984
|
+
`);if(!text)return;let acks=parseAcknowledgments(text);if(acks.length===0)return;let ctx={sessionId:sessionID};for(let ack of acks){let key=buildAckDedupKey(sessionID,ack.id,ack.result);if(swarmState.knowledgeAckDedup.has(key))continue;addKnowledgeAckDedup(key);try{await recordAcknowledgment(directory,ack,ctx)}catch(err){warn(`[knowledge-application-gate] transform-scan record failed: ${err instanceof Error?err.message:String(err)}`)}}}var _internals131={knowledgeApplicationGateBefore,knowledgeApplicationTransformScan,HIGH_RISK_TOOLS,writeWarnEvent:writeWarnEvent2};init_knowledge_curator();init_micro_reflector();init_normalize_tool_name();init_pr_subscriptions();init_utils();init_stored_input_args();init_normalize_tool_name();var MAX_OUTPUT_SCAN_BYTES=65536,PR_URL_PATTERN=/https:\/\/github\.com\/([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+)\/pull\/(\d+)/,_internals132={subscribe,log};function extractPrUrl(text){let match=PR_URL_PATTERN.exec(text.slice(0,MAX_OUTPUT_SCAN_BYTES));if(!match)return null;let owner=match[1],repo=match[2],prNumber=Number.parseInt(match[3],10);if(!Number.isSafeInteger(prNumber)||prNumber<=0)return null;return{repoFullName:`${owner}/${repo}`,prNumber,prUrl:`https://github.com/${owner}/${repo}/pull/${prNumber}`}}function createPrAutoSubscribeHook(directory,config3){return{toolAfter:async(input,output)=>{try{if(!config3.enabled||!config3.auto_subscribe_on_pr_create)return;let sessionID=typeof input.sessionID==="string"?input.sessionID.trim():"";if(!sessionID)return;let tool3=normalizeToolNameLowerCase(input.tool??"");if(tool3!=="bash"&&tool3!=="shell")return;let args2=(typeof input.callID==="string"?getStoredInputArgs(input.callID):void 0)??input.args??output.args;if(!(typeof args2?.command==="string"?args2.command:"").includes("gh pr create"))return;let outputText2=typeof output.output==="string"?output.output:"";if(!outputText2)return;let prInfo=extractPrUrl(outputText2);if(!prInfo)return;await _internals132.subscribe(directory,{sessionID,prNumber:prInfo.prNumber,repoFullName:prInfo.repoFullName,prUrl:prInfo.prUrl,maxSubscriptions:config3.max_subscriptions}),_internals132.log("[pr-monitor] Auto-subscribed session to created PR",{sessionID,pr:`${prInfo.repoFullName}#${prInfo.prNumber}`})}catch(err){_internals132.log("[pr-monitor] Auto-subscribe failed (non-fatal)",{error:err instanceof Error?err.message:String(err)})}}}}init_pr_workflow_gate();init_pr_workflow_auto_wake();init_pr_workflow_gate();var DEFAULT_WAKE_TIMEOUT_MS=5000,_internals133={readPrWorkflowGateState},DEFAULT_MAX_CONSECUTIVE_UNPRODUCTIVE_WAKES=5,DEFAULT_WAKE_COOLDOWN_MS=30000,MAX_TRACKED_WAKE_SESSIONS=200;function blockedText(mode,options={}){let lines=[`[${mode} WORKFLOW ACTIVE]`,`The ${mode} workflow gate is still active. Continue with the required structured lanes, evidence, and controller tools until \`complete_pr_workflow\` succeeds.`,`If the bind/checkout path is unreachable — for example a compound \`git fetch && git checkout\` was rejected as read-only shell syntax, the PR head cannot be fetched, or the working tree is on the wrong branch — call \`abort_pr_workflow\` (mode: "${mode}", reason: "<one-line cause>") to clear the gate, or ask the user to run \`/swarm abort-pr-workflow\`.`];if(options.suspended){let max=options.maxConsecutive;lines.push(`Auto-resume is suspended after ${max??"the configured number of"} consecutive unproductive retries (the durable gate \`revision\` did not advance). The session will not be re-awoken automatically. Run \`/swarm abort-pr-workflow\` or call \`abort_pr_workflow\` to clear the gate, or complete the workflow with \`complete_pr_workflow\` to publish normally.`)}if(options.userInterrupted)lines.push("Auto-resume is paused after a user interruption. The durable workflow gate is preserved, but the plugin will not re-awaken this session. Send a new message to continue, or run `/swarm abort-pr-workflow` to clear the workflow.");return lines.join(`
|
|
5985
|
+
`)}function workflowBanner(mode,options={}){let lines=[`--- [${mode} WORKFLOW ACTIVE — output below is not a terminal verdict; \`complete_pr_workflow\` clears the gate on success; if the bind/checkout path is unreachable call \`abort_pr_workflow\` or run \`/swarm abort-pr-workflow\`] ---`];if(options.suspended){let max=options.maxConsecutive;lines.push(`[Auto-resume is suspended after ${max??"the configured number of"} consecutive unproductive retries. Run \`/swarm abort-pr-workflow\` or call \`abort_pr_workflow\` to clear the gate, or complete the workflow with \`complete_pr_workflow\`.]`)}if(options.userInterrupted)lines.push("[Auto-resume paused after a user interruption. Send a new message to continue, or run `/swarm abort-pr-workflow` to clear the workflow.]");return lines.join(" ")}function createPrWorkflowResponseGate(options){let wakeTimeoutMs=options.wakeTimeoutMs??DEFAULT_WAKE_TIMEOUT_MS,maxConsecutive=options.maxConsecutiveUnproductiveWakes??DEFAULT_MAX_CONSECUTIVE_UNPRODUCTIVE_WAKES,wakeCooldownMs=options.wakeCooldownMs??DEFAULT_WAKE_COOLDOWN_MS,activeWakeSessions=new Set,wakeBudgets=new Map,session=options.client?.session;function evictIfOverBound(){while(wakeBudgets.size>MAX_TRACKED_WAKE_SESSIONS){let oldestKey=wakeBudgets.keys().next().value;if(oldestKey===void 0)break;wakeBudgets.delete(oldestKey)}}function resetBudget(sessionID){wakeBudgets.delete(sessionID)}return{event:async(input)=>{let wakeDecision=await observePrWorkflowAutoWakeEvent(options.directory,input.event),event2=input.event,sessionID=event2?.properties?.sessionID??event2?.data?.sessionID;if(event2?.type!=="session.idle"||typeof sessionID!=="string"||!sessionID.trim()||wakeDecision.suppressWake||activeWakeSessions.has(sessionID))return;activeWakeSessions.add(sessionID);try{let state=await _internals133.readPrWorkflowGateState(options.directory,sessionID);if(!state){resetBudget(sessionID),clearPrWorkflowAutoWakeState(options.directory,sessionID);return}if(isPrWorkflowAutoWakeSuppressed(options.directory,sessionID))return;if(!session)return;evictIfOverBound();let budget=wakeBudgets.get(sessionID);if(!budget)budget={consecutiveUnproductive:0,lastWakeAt:0,suspended:!1},wakeBudgets.set(sessionID,budget);if(budget.suspended)return;let now=Date.now();if(budget.lastSeenRevision!==void 0&&state.revision>budget.lastSeenRevision)budget.consecutiveUnproductive=0;if(budget.consecutiveUnproductive>0&&budget.lastWakeAt>0&&now-budget.lastWakeAt<wakeCooldownMs)return;let madeProgress=budget.lastSeenRevision===void 0?!0:state.revision>budget.lastSeenRevision,pluginWakeMessageID=markPrWorkflowPluginWake(options.directory,sessionID),promptRejected=!1,timer;try{let args2={path:{id:sessionID},body:{messageID:pluginWakeMessageID,parts:[{type:"text",text:`${blockedText(state.mode,{suspended:!1,maxConsecutive})}
|
|
5986
|
+
Do not stop or summarize. Inspect the durable gate, dispatch or collect the next missing required lane, and continue until complete_pr_workflow succeeds. If the bind/checkout path is genuinely unreachable, call abort_pr_workflow instead of looping.`}]}},call=session.promptAsync?session.promptAsync(args2):session.prompt(args2),result=await Promise.race([call,new Promise((_resolve,reject2)=>{timer=setTimeout(()=>reject2(Error("PR workflow resume prompt timed out")),wakeTimeoutMs)})]);if(result?.error!=null)throw promptRejected=!0,Error(`PR workflow resume prompt failed: ${String(result.error)}`)}finally{if(timer)clearTimeout(timer);if(promptRejected)cancelPrWorkflowPluginWake(options.directory,sessionID,pluginWakeMessageID);let postWakeState=await _internals133.readPrWorkflowGateState(options.directory,sessionID);if(budget.lastWakeAt=now,postWakeState===null)resetBudget(sessionID);else{let currentRevision=postWakeState.revision,effectiveMadeProgress=madeProgress||budget.lastSeenRevision!==void 0&¤tRevision>budget.lastSeenRevision;if(budget.lastSeenRevision=currentRevision,!effectiveMadeProgress){if(budget.consecutiveUnproductive+=1,budget.consecutiveUnproductive>=maxConsecutive)budget.suspended=!0}else budget.consecutiveUnproductive=0}}}finally{activeWakeSessions.delete(sessionID)}},textComplete:async(input,output)=>{if(!input.sessionID?.trim())return;let state=await _internals133.readPrWorkflowGateState(options.directory,input.sessionID);if(!state){resetBudget(input.sessionID),clearPrWorkflowAutoWakeState(options.directory,input.sessionID);return}let budget=wakeBudgets.get(input.sessionID),banner=workflowBanner(state.mode,{suspended:budget?.suspended??!1,userInterrupted:isPrWorkflowAutoWakeSuppressed(options.directory,input.sessionID),maxConsecutive});output.text=`${banner}
|
|
5987
|
+
|
|
5988
|
+
${output.text}`},_inspectWakeBudget:(sessionID)=>wakeBudgets.get(sessionID)}}init_pending_delegations();init_pr_workflow_gate();var MAX_PARENT_DEPTH=16,MAX_TRACKED_SESSION_PARENTS=512;function rememberBounded2(parents,childSessionID,parentSessionID){parents.delete(childSessionID),parents.set(childSessionID,parentSessionID);while(parents.size>MAX_TRACKED_SESSION_PARENTS){let oldest=parents.keys().next().value;if(typeof oldest!=="string")break;parents.delete(oldest)}}function createPrWorkflowSessionResolver(options){let session=options.client?.session,parents=new Map;return{observeEvent:(input)=>{let event=input.event;if(event?.type!=="session.created"&&event?.type!=="session.updated")return;let child=event.properties?.info?.id,parent=event.properties?.info?.parentID;if(typeof child==="string"&&child.trim()&&typeof parent==="string"&&parent.trim())rememberBounded2(parents,child.trim(),parent.trim())},resolve:async(sessionID)=>{let original=sessionID.trim();if(!original)return sessionID;let current=original,visited=new Set;for(let depth=0;depth<MAX_PARENT_DEPTH;depth+=1){if(visited.has(current))break;if(visited.add(current),await readPrWorkflowGateState(options.directory,current))return current;let parent=parents.get(current);if(!parent)parent=findByCorrelationId(options.directory,current)?.parentSessionId;if(!parent&&session?.get){let result=await session.get({path:{id:current},query:{directory:options.directory}});if(result?.error==null){let candidate=result?.data?.parentID;if(typeof candidate==="string"&&candidate.trim())parent=candidate.trim()}}if(!parent)return original;rememberBounded2(parents,current,parent),current=parent}return original}}}init_schema();init_bun_compat();init_logger();var import_picomatch2=__toESM(require_picomatch2(),1);import{existsSync as existsSync104,readdirSync as readdirSync30,readFileSync as readFileSync77,statSync as statSync41}from"node:fs";import*as path202 from"node:path";var PREDICATE_TIMEOUT_MS=15000,GREP_MAX_FILES=1e4,GREP_MAX_BYTES_PER_FILE=1e6,GREP_SKIP_DIRECTORIES=new Set([".git",".swarm","node_modules","dist","coverage"]),TOOL_BINARY_ALLOWLIST=new Set(["rg","grep","git","biome","eslint","tsc","ruff"]);function validateRepoRelativeGlob(directory,value){let v=value.trim();if(!v)return null;if(v.includes("\x00"))return null;if(v.startsWith("/")||/^[A-Za-z]:[\\/]/.test(v)||v.startsWith("\\"))return null;if(v.split(/[/\\]/).some((s)=>s===".."))return null;let globStart=v.search(/[*?{[]/),concrete=globStart===-1?v:v.slice(0,globStart);if(concrete){let baseDir=path202.resolve(directory),resolved=path202.resolve(baseDir,concrete),rel=path202.relative(baseDir,resolved);if(rel.startsWith("..")||path202.isAbsolute(rel))return null}return v}function findBinaryInPath(binary){let exeName=process.platform==="win32"?`${binary}.exe`:binary;for(let dir of(process.env.PATH??"").split(path202.delimiter)){if(!dir)continue;let candidate=path202.join(dir,exeName);if(existsSync104(candidate))return candidate}return null}function safeChildEnv(){let env={};if(process.env.PATH)env.PATH=process.env.PATH;if(process.env.HOME)env.HOME=process.env.HOME;if(process.env.SystemRoot)env.SystemRoot=process.env.SystemRoot;if(process.env.TEMP)env.TEMP=process.env.TEMP;if(process.env.TMP)env.TMP=process.env.TMP;return env}async function runArgv(argv,cwd){let proc=bunSpawn(argv,{stdin:"ignore",stdout:"pipe",stderr:"pipe",cwd,env:safeChildEnv()}),finished=!1;try{let timeout=new Promise((resolve72)=>setTimeout(()=>resolve72("timeout"),PREDICATE_TIMEOUT_MS));if(await Promise.race([proc.exited,timeout])==="timeout")return{exitCode:null,stdout:"",stderr:"",timedOut:!0};let[stdout,stderr]=await Promise.all([proc.stdout.text().catch(()=>""),proc.stderr.text().catch(()=>"")]);return finished=!0,{exitCode:proc.exitCode,stdout,stderr,timedOut:!1}}finally{if(!finished)try{proc.kill()}catch{}}}async function runGrepPredicate(rest,directory){let lastColon=rest.lastIndexOf(":");if(lastColon<=0||lastColon===rest.length-1)return{result:"error",detail:"grep: expected <regex>:<path-glob>"};let regex=rest.slice(0,lastColon),rawGlob=rest.slice(lastColon+1),glob=validateRepoRelativeGlob(directory,rawGlob);if(glob===null)return{result:"error",detail:`grep: unsafe or empty path-glob "${rawGlob}"`};let pattern;try{pattern=new RegExp(regex,"m")}catch(err){return{result:"error",detail:`grep: invalid regex ${err instanceof Error?err.message:String(err)}`}}let matcher=import_picomatch2.default(glob,{dot:!0}),visited=0,matches=0,walk=(dir)=>{if(visited>=GREP_MAX_FILES)return;let entries;try{entries=readdirSync30(dir,{withFileTypes:!0})}catch{return}for(let entry of entries){if(visited>=GREP_MAX_FILES)return;let fullPath=path202.join(dir,entry.name),relPath=path202.relative(directory,fullPath).replace(/\\/g,"/");if(entry.isDirectory()){if(!GREP_SKIP_DIRECTORIES.has(entry.name))walk(fullPath);continue}if(!entry.isFile())continue;if(visited++,!matcher(relPath))continue;try{if(statSync41(fullPath).size>GREP_MAX_BYTES_PER_FILE)continue;let found=readFileSync77(fullPath,"utf-8").match(pattern);if(found)matches+=found.length}catch{}}};if(walk(directory),visited>=GREP_MAX_FILES)return{result:"error",detail:`grep: file scan exceeded ${GREP_MAX_FILES} files`};if(matches===0)return{result:"pass",detail:"grep: zero matches"};return{result:"fail",detail:`grep: ${matches} match(es) found`}}async function runToolPredicate(rest,directory){let raw=rest.trim();if(!raw)return{result:"error",detail:"tool: empty command"};if(raw.includes("\x00"))return{result:"error",detail:"tool: null byte in command"};let argvParts=raw.split(/\s+/).filter((p)=>p.length>0);if(argvParts.length===0)return{result:"error",detail:"tool: empty command"};let binary=argvParts[0];if(binary.includes("/")||binary.includes("\\"))return{result:"error",detail:`tool: path-qualified binary "${binary}" is not allowed`};if(!TOOL_BINARY_ALLOWLIST.has(binary))return{result:"error",detail:`tool: binary "${binary}" is not on the allowlist`};let resolved=findBinaryInPath(binary);if(!resolved)return{result:"error",detail:`tool: binary "${binary}" not found`};let res=await runArgv([resolved,...argvParts.slice(1)],directory);if(res.timedOut)return{result:"error",detail:"tool: timed out"};if(res.exitCode===0)return{result:"pass",detail:"tool: exit 0"};return{result:"fail",detail:`tool: exit ${res.exitCode} ${res.stderr.slice(0,200)}`}}async function changedPaths(directory){let git2=findBinaryInPath("git");if(!git2)return null;let res=await runArgv([git2,"status","--porcelain","-z"],directory);if(res.timedOut||res.exitCode!==0)return null;let out=new Set;for(let entry of res.stdout.split("\x00")){if(entry.length<=3)continue;let p=entry.slice(3);if(p)out.add(path202.normalize(p))}return out}async function runFileModifiedPredicate(rest,directory,expectModified){let label=expectModified?"file_modified":"file_not_modified",safe=validateRepoRelativeGlob(directory,rest);if(safe===null)return{result:"error",detail:`${label}: unsafe or empty path "${rest}"`};let changed=await changedPaths(directory);if(changed===null)return{result:"error",detail:`${label}: git unavailable or failed`};let target=path202.normalize(safe),isChanged=changed.has(target);return{result:(expectModified?isChanged:!isChanged)?"pass":"fail",detail:`${label}: ${target} ${isChanged?"changed":"unchanged"}`}}async function runDirectivePredicate(predicate,directory){try{if(typeof predicate!=="string"||!predicate.trim())return{result:"error",detail:"predicate: empty"};let trimmed=predicate.trim(),firstColon=trimmed.indexOf(":");if(firstColon<=0)return{result:"error",detail:"predicate: missing handler prefix (expected <handler>:...)"};let handler=trimmed.slice(0,firstColon),rest=trimmed.slice(firstColon+1);switch(handler){case"grep":return await runGrepPredicate(rest,directory);case"tool":return await runToolPredicate(rest,directory);case"file_not_modified":return await runFileModifiedPredicate(rest,directory,!1);case"file_modified":return await runFileModifiedPredicate(rest,directory,!0);default:return{result:"error",detail:`predicate: unknown handler "${handler}"`}}}catch(err){return warn(`[directive-predicate-runner] unexpected error: ${err instanceof Error?err.message:String(err)}`),{result:"error",detail:"predicate: unexpected error (fail-closed)"}}}init_knowledge_escalator();init_knowledge_events();init_skill_propagation_gate();var VERDICT_PATTERN=/\b(VERIFIED|VIOLATED|N\/A)\s*:\s*([A-Za-z0-9._-]{1,80})(?:\s+(?:evidence|reason)\s*=\s*([^\n\r]+?))?(?=$|[\n\r]|\s+(?:VERIFIED|VIOLATED|N\/A)\b)/gi;function parseReviewerDirectiveCompliance(text){if(!text||typeof text!=="string")return[];let out=[];for(let m of text.matchAll(VERDICT_PATTERN)){let verb=m[1].toUpperCase(),id=m[2],evidence=m[3]?.trim().slice(0,280),verdict=verb==="VERIFIED"?"verified":verb==="VIOLATED"?"violated":"n_a";out.push({id,verdict,evidence})}return out}function verdictToEventType(v){return v==="verified"?"applied":v==="violated"?"violated":"n_a"}async function reconcileReviewerVerdicts(params){let result={emitted:[],omittedCriticals:[]};try{let verifyById=new Map(params.directivesToVerify.map((d)=>[d.id,d]));if(verifyById.size===0)return result;let verdicts=parseReviewerDirectiveCompliance(params.transcript),addressed=new Set,violatedIds=new Set,traceId=newTraceId(),sessionId=params.sessionId??"unknown",agent=params.agent??"reviewer";for(let v of verdicts){let directive=verifyById.get(v.id);if(!directive)continue;addressed.add(v.id);let type=verdictToEventType(v.verdict),predicateCheck;if(v.verdict==="violated"&&directive.verification_predicate){let outcome=await runDirectivePredicate(directive.verification_predicate,params.directory);predicateCheck={predicate:directive.verification_predicate,result:outcome.result,detail:outcome.detail}}if(await recordKnowledgeEvent(params.directory,{type,trace_id:traceId,knowledge_id:v.id,session_id:sessionId,task_id:params.taskId,phase:params.phase,agent,source:"reviewer",reason:v.evidence,predicate_check:predicateCheck}),type==="violated")violatedIds.add(v.id);result.emitted.push({id:v.id,type,source:"reviewer"})}for(let d of params.directivesToVerify){if(d.priority!=="critical")continue;if(addressed.has(d.id))continue;result.omittedCriticals.push(d.id),await recordKnowledgeEvent(params.directory,{type:"violated",trace_id:traceId,knowledge_id:d.id,session_id:sessionId,task_id:params.taskId,phase:params.phase,agent,source:"reviewer",reason:"reviewer_omitted"}),violatedIds.add(d.id),result.emitted.push({id:d.id,type:"violated",source:"reviewer"})}if(violatedIds.size>0)await escalateViolatedEntries(params.directory,[...violatedIds])}catch{}return result}function isTaskTool6(tool3){return tool3==="Task"||tool3==="task"}async function collectReviewerVerdictsAfter(directory,input,output){if(!isTaskTool6(input.tool))return;let parsedArgs=parseDelegationArgs(input.args);if(!parsedArgs)return;if(stripKnownSwarmPrefix(parsedArgs.targetAgent).toLowerCase()!=="reviewer")return;let argsRecord=input.args&&typeof input.args==="object"?input.args:null,prompt=argsRecord&&typeof argsRecord.prompt==="string"?argsRecord.prompt:"";if(!prompt)return;let transcript=typeof output.output==="string"?output.output:"";if(!transcript)return;let directivesToVerify=parseDirectivesToVerifyBlock(prompt);if(directivesToVerify.length===0)return;let sessionId=typeof input.sessionID==="string"?input.sessionID:void 0;await reconcileReviewerVerdicts({directory,transcript,directivesToVerify,sessionId,agent:"reviewer"})}init_constants();init_schema();init_scope_binding();init_scope_persistence();init_state2();init_normalize_tool_name();init_pr_workflow_gate();init_write_target_resolver();import*as path203 from"node:path";var WRITE_TOOLS2=new Set(WRITE_TOOL_NAMES);function createScopeGuardHook(config3,directory,injectAdvisory){let enabled=config3.enabled??!0,_skipInTurbo=config3.skip_in_turbo??!1;return{toolBefore:async(input,output)=>{if(!enabled)return;let toolName=normalizeToolName(input.tool);if(!WRITE_TOOLS2.has(toolName))return;let sessionId=input.sessionID,activeAgent=swarmState.activeAgent.get(sessionId),session=swarmState.agentSessions.get(sessionId),agentName=activeAgent??session?.agentName??"unknown",agentRole=stripKnownSwarmPrefix(agentName);if(agentRole===ORCHESTRATOR_NAME)return;if(agentRole!=="coder")return;let targets=_internals134.resolveWriteTargets(toolName,output.args,{directory});if(targets.status==="unverifiable")throw Error(`WRITE TARGET UNVERIFIABLE: ${agentName} invoked ${toolName}: ${targets.reason}`);if(targets.paths.length===0)return;let taskId=_internals134.resolveTaskId(session),binding=taskId?_internals134.resolveAuthorizedScopeBinding({directory,taskId,activeSessionId:sessionId}):_internals134.resolveAuthorizedScopeBindingForSession({directory,activeSessionId:sessionId});if(!binding){if(binding=_internals134.getAuthorizedPrFeedbackScopeBinding({directory,activeSessionId:sessionId,taskId:taskId??void 0})??_internals134.resolveAuthorizedPrFeedbackScopeBindingFromDisk({directory,activeSessionId:sessionId,taskId:taskId??void 0}),binding&&!await _internals134.validatePrFeedbackScopeBinding(directory,binding))binding=null}if(!taskId&&binding&&session)taskId=binding.taskId,session.currentTaskId=binding.taskId,session.declaredCoderScope=[...binding.files];let declaredScope=binding?.files??null;if(!declaredScope||declaredScope.length===0)throw Error(`SCOPE_NOT_DECLARED: ${agentName} cannot invoke ${toolName} without a validated scope for task ${taskId??"unknown"}.`);for(let rawPath of targets.paths){let filePath=sanitizePath(rawPath);if(!isFileInScope(filePath,declaredScope,directory))reportScopeViolation(agentName,filePath,taskId,session,injectAdvisory,swarmState,declaredScope)}}}}function isFileInScope(filePath,scopeEntries,directory){let dir=directory??process.cwd(),resolvedFile=path203.resolve(dir,filePath);return scopeEntries.filter((scope)=>scope.length>0).some((scope)=>{let resolvedScope=path203.resolve(dir,scope);if(resolvedFile===resolvedScope)return!0;let rel=path203.relative(resolvedScope,resolvedFile);return rel.length>0&&!rel.startsWith("..")&&!path203.isAbsolute(rel)})}function sanitizePath(raw){let result="";for(let i=0;i<raw.length;i++){let c=raw.charCodeAt(i);if(c<=31||c===127||c>=128&&c<=159){result+="_";continue}result+=raw[i]}return result.replace(/\[[\d;]*m/g,"")}var _internals134={sanitizePath,resolveWriteTargets:resolveWriteTargets2,resolveAuthorizedScopeBinding,resolveAuthorizedScopeBindingForSession,getAuthorizedPrFeedbackScopeBinding,resolveAuthorizedPrFeedbackScopeBindingFromDisk,validatePrFeedbackScopeBinding,resolveTaskId:(session)=>session?.currentTaskId??null};function reportScopeViolation(agentName,filePath,taskId,session,injectAdvisory,state,scopeEntries){let violationMessage=`SCOPE VIOLATION: ${agentName} attempted to modify '${filePath}' which is not in declared scope for task ${taskId??"unknown"}. Declared scope: [${scopeEntries.slice(0,3).join(", ")}${scopeEntries.length>3?"...":""}]`;if(session)session.lastScopeViolation=violationMessage,session.scopeViolationDetected=!0;if(injectAdvisory)for(let[archSessionId,archSession]of state.agentSessions){let archAgent=state.activeAgent.get(archSessionId)??archSession.agentName;if(stripKnownSwarmPrefix(archAgent)===ORCHESTRATOR_NAME){try{injectAdvisory(archSessionId,`[SCOPE GUARD] ${violationMessage}`)}catch{}break}}throw Error(violationMessage)}init_constants();init_schema();init_state2();init_normalize_tool_name();function createSelfReviewHook(config3,injectAdvisory){let enabled=config3.enabled??!0,skipInTurbo=config3.skip_in_turbo??!0;return{toolAfter:async(input,output)=>{if(!enabled)return;if(normalizeToolName(input.tool)!=="update_task_status")return;let args2=output.args;if(args2?.status!=="in_progress")return;let taskId=typeof args2?.task_id==="string"?args2.task_id:"unknown",sessionId=input.sessionID,agentName=swarmState.activeAgent.get(sessionId)??swarmState.agentSessions.get(sessionId)?.agentName??"";if(stripKnownSwarmPrefix(agentName)!==ORCHESTRATOR_NAME)return;if(skipInTurbo){let session=swarmState.agentSessions.get(sessionId);if(session&&session.turboMode===!0)return}let advisory=[`[SELF-REVIEW] Task ${taskId} is now delegated to coder.`,"After coder completes, review for:"," • Broken conditionals (inverted if/else, wrong comparisons)"," • Off-by-one errors (array bounds, loop indices)"," • Assumptions contradicting existing codebase patterns"," • Missing error handling (uncaught exceptions, unhandled promises)"," • Scope creep (changes outside the declared task spec)","Delegate to critic with self-review focus before marking complete."].join(`
|
|
5987
5989
|
`);try{injectAdvisory(sessionId,advisory)}catch{}}}}init_skill_propagation_gate();init_skill_scoring();init_skill_usage_log();import*as path204 from"node:path";var SKILL_INJECTION_THRESHOLD=0.5,SKILL_INJECTION_TOP_N=5;function injectSkillsIntoDelegation(directory,args2,recommendedSkills,targetAgent,sessionID,options={}){if(!recommendedSkills||recommendedSkills.length===0)return{injected:!1,injectedSkills:[]};let promptRaw=args2.prompt;if(typeof promptRaw!=="string")return{injected:!1,injectedSkills:[]};let parsedDelegation=parseDelegationArgs(args2);if(!parsedDelegation)return{injected:!1,injectedSkills:[]};if(parsedDelegation.skillsField.trim())return{injected:!1,injectedSkills:[]};let qualified=recommendedSkills.filter((s)=>s.score>=SKILL_INJECTION_THRESHOLD);if(qualified.length===0){if(args2.prompt=`SKILLS: none
|
|
5988
5990
|
|
|
5989
5991
|
${promptRaw}`,!options.quiet)console.warn("[skill-propagation-gate] No skills above threshold 0.5 — injected SKILLS: none");try{writeWarnEvent(directory,{type:"skill_injection_decision",timestamp:new Date().toISOString(),decision:"none",target_agent:targetAgent,sessionID,reason:"no_skill_above_threshold",threshold:SKILL_INJECTION_THRESHOLD,considered:recommendedSkills.map((s)=>({skillPath:s.skillPath,score:s.score}))})}catch{}return{injected:!0,injectedSkills:[]}}let topSkills=qualified.slice(0,SKILL_INJECTION_TOP_N),newPrompt=`${`SKILLS: ${topSkills.map((s)=>{let desc=readSkillMetadata(s.skillPath,directory).description||"";if(!desc||desc==="No description provided")desc=path204.basename(path204.dirname(s.skillPath));return desc=desc.replace(/,/g,";"),`file:${s.skillPath} (-- ${desc})`}).join(", ")}`}
|