opencode-swarm 7.143.2 → 7.143.3

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.
Files changed (43) hide show
  1. package/dist/cli/{config-doctor-xadt4kv5.js → config-doctor-ddbwxt14.js} +2 -2
  2. package/dist/cli/{core-vpefadja.js → core-gfk2tsre.js} +1 -1
  3. package/dist/cli/{curator-wahbxxw9.js → curator-hkcd03bx.js} +17 -17
  4. package/dist/cli/{curator-llm-factory-xjw5j2jj.js → curator-llm-factory-z23scnwb.js} +17 -17
  5. package/dist/cli/{evidence-summary-service-m0jes2yb.js → evidence-summary-service-cbhsye6e.js} +6 -6
  6. package/dist/cli/{gate-evidence-sf9hbhm0.js → gate-evidence-5xd9j34y.js} +2 -2
  7. package/dist/cli/{guardrail-explain-9vdjkz5x.js → guardrail-explain-49vn7rv6.js} +18 -18
  8. package/dist/cli/{guardrail-log-xr0cv07v.js → guardrail-log-ghymef5s.js} +3 -3
  9. package/dist/cli/{hive-promoter-ften3m3h.js → hive-promoter-akf3x240.js} +17 -17
  10. package/dist/cli/{index-6q3wx600.js → index-1et48zgf.js} +1 -1
  11. package/dist/cli/{index-qswsp6s3.js → index-1y0rggw0.js} +1 -1
  12. package/dist/cli/{index-jvbqryky.js → index-30yyh3m0.js} +3 -3
  13. package/dist/cli/{index-nvt1152n.js → index-3qw0bsgr.js} +1 -1
  14. package/dist/cli/{index-yw4atzww.js → index-4mr3ga48.js} +1 -1
  15. package/dist/cli/{index-2pxq133w.js → index-64pk7525.js} +1 -1
  16. package/dist/cli/{index-x0ja3n3g.js → index-6cgp4ska.js} +2 -2
  17. package/dist/cli/{index-700yppfy.js → index-86tn52b3.js} +1 -1
  18. package/dist/cli/{index-6hwedxn7.js → index-9py8e0dk.js} +3 -3
  19. package/dist/cli/{index-4g1bnzma.js → index-a6rnw33a.js} +2 -2
  20. package/dist/cli/{index-je3jmcc1.js → index-ds7j4hth.js} +3 -3
  21. package/dist/cli/{index-kjgma6hg.js → index-e1feasna.js} +1 -1
  22. package/dist/cli/{index-yr997mhn.js → index-e3g0t29w.js} +1 -1
  23. package/dist/cli/{index-fq0b44vq.js → index-etxy4vz9.js} +4 -4
  24. package/dist/cli/{index-6f80e8r5.js → index-m7gss7zy.js} +167 -118
  25. package/dist/cli/{index-kc9tfc7e.js → index-qykq6vge.js} +3 -3
  26. package/dist/cli/{index-h5fmwg5b.js → index-tj18fe58.js} +19 -19
  27. package/dist/cli/{index-7e91cs99.js → index-vatqcjnd.js} +5 -5
  28. package/dist/cli/{index-8hxbjgyk.js → index-vdkywste.js} +1 -1
  29. package/dist/cli/{index-r0j1sh38.js → index-x90gktjx.js} +1 -1
  30. package/dist/cli/{index-xacfcpyn.js → index-xq2effek.js} +2 -2
  31. package/dist/cli/index.js +17 -17
  32. package/dist/cli/{knowledge-escalator-9xesv2xx.js → knowledge-escalator-mgg6kvva.js} +6 -6
  33. package/dist/cli/{knowledge-events-s8nvbdyk.js → knowledge-events-yjmkrrv2.js} +4 -4
  34. package/dist/cli/{knowledge-store-2zt0b10b.js → knowledge-store-647twyjp.js} +1 -1
  35. package/dist/cli/{knowledge-validator-nt955tw0.js → knowledge-validator-0nsax3n6.js} +2 -2
  36. package/dist/cli/{scan-cursor-emrg35t0.js → scan-cursor-vgmzg5ys.js} +2 -2
  37. package/dist/cli/{schema-tpbz8f0x.js → schema-mzh2tam4.js} +1 -1
  38. package/dist/cli/{scope-persistence-1hf839ys.js → scope-persistence-m4ah4fay.js} +4 -4
  39. package/dist/cli/{skill-generator-fja22m4q.js → skill-generator-eyf32w7h.js} +7 -7
  40. package/dist/cli/{worktree-isolation-gnqvy10j.js → worktree-isolation-grxn94v9.js} +17 -17
  41. package/dist/index.js +67 -59
  42. package/dist/session/snapshot-writer.d.ts +12 -0
  43. 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.143.2",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",".opencode/skills/orchestrating-subagents",".opencode/skills/durable-session-state","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","check:runtime-src-refs":"bun run scripts/check-runtime-src-refs.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","check:events":"bun run scripts/check-event-contract.ts","check:test-file-cap":"bun run scripts/check-test-file-cap.ts","check:gate-portability":"bun run scripts/check-gate-portability.ts"},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","critic_finding_validator"],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_finding_validator","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_finding_validator","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","critic_finding_validator"],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_finding_validator","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","critic_finding_validator","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_finding_validator","critic_oversight"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},sast_scan:{description:"static analysis security scan",agents:["architect","reviewer","critic_finding_validator","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","critic_finding_validator"]},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_finding_validator","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_finding_validator","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"]},approve_plan_critic:{description:"record a MANUAL plan_critic_gate approval snapshot to unblock the ratchet-tighter critic_pre_plan execution gate when the critic already returned APPROVED but the mechanical recorder failed to persist it (issue #2012)",agents:["architect"]},prepare_pr_workflow_checkout:{description:"prepare an auditable PR workflow checkout or restore its exact original branch/HEAD and preserved stash after terminal cleanup",agents:["architect"]},record_implementation_review:{description:"record fresh-context reviewer + critic APPROVE verdicts for the implementation diff so the /swarm issue --trace workflow can satisfy its review gate before commit-pr handoff",agents:["architect"]},record_issue_publication:{description:"record a publication receipt so the /swarm issue --trace workflow reaches its terminal published state after the PR is created/updated",agents:["architect"]},record_issue_reproduction:{description:"record the reproduction outcome for the current traced issue so the /swarm issue --trace workflow can satisfy its reproduction gate and transition to PLAN",agents:["architect"]},record_recurrence_sweep:{description:"record the recurrence sweep (defect class, predicates, hit dispositions, guardrail proof) so the /swarm issue --trace workflow can satisfy its recurrence gate before commit-pr handoff",agents:["architect"]},rebind_pr_feedback_head:{description:"rebind a PR_FEEDBACK workflow to a new verified remote PR head after merge/rebase/conflict repair, invalidating ancestry-bound receipts so the mechanical ladder re-runs",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_finding_validator","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"]},plan_conflict_check:{description:"read-only advisory check (#1656): compute a pairwise file-conflict matrix for N proposed parallel task groups using declared scopes and optional git co-change; returns a verdict (all_disjoint / conflicts_present / unknown_scopes), per-pair evidence, and a suggested serialization order. Writes nothing — the execution gate independently recomputes the verdict inline at dispatch time via the same helper. Call BEFORE attempting parallel dispatch to confirm disjointness.",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","critic_finding_validator","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_finding_validator","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","critic_finding_validator","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_finding_validator","critic","coder","test_engineer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},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"]},consensus_mine:{description:"mine cross-run consensus from existing .swarm evidence into an immutable proposals-only report; also deletes its own reports past consensus.report_retention, appends to the shared recommendation dedup ledger (in the shared cohort root, outside this project, when a knowledge link is active), and mirrors proposals into pending swarm-memory proposals when memory is enabled",agents:["architect","curator_phase","curator_postmortem"]},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_finding_validator","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_finding_validator","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"}},pr_workflow_status:{description:"Read-only architect observation of local git state (HEAD, branch, clean/dirty with a bounded changed-file list, remotes) plus a session-pinned PR workflow gate summary. Use to observe state under the fail-closed PR_REVIEW/PR_FEEDBACK gate. Never executes PR-controlled scripts and never reads another session gate.",agents:["architect"],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_finding_validator","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","critic_finding_validator"]},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_finding_validator","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 or exact future plan identity: 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 and never creates state.",agents:["architect"]},set_qa_gates:{description:"configure the QA gate profile for the current plan or bootstrap an exact future plan with swarm_id and plan_title. Architect-only. The initial selection may set explicit true/false values over defaults; later changes are ratchet-tighter and rejected once 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, plus adopt_legacy_binding_only for exact-binding recovery without mutating gates.",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_finding_validator","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_finding_validator","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. Inline output for a settled lane is delivered only once: later polls of the same lane set output_omitted_repeat: true and omit output, but still include output_ref for recovery via retrieve_lane_output.",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,SUMMARIZER_EXEMPT_TOOL_NAMES,DEFAULT_MODELS,DEFAULT_AGENT_CONFIGS,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.143.3",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",".opencode/skills/orchestrating-subagents",".opencode/skills/durable-session-state","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","check:runtime-src-refs":"bun run scripts/check-runtime-src-refs.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","check:events":"bun run scripts/check-event-contract.ts","check:test-file-cap":"bun run scripts/check-test-file-cap.ts","check:gate-portability":"bun run scripts/check-gate-portability.ts"},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","critic_finding_validator"],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_finding_validator","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_finding_validator","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","critic_finding_validator"],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_finding_validator","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","critic_finding_validator","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_finding_validator","critic_oversight"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},sast_scan:{description:"static analysis security scan",agents:["architect","reviewer","critic_finding_validator","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","critic_finding_validator"]},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_finding_validator","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_finding_validator","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"]},approve_plan_critic:{description:"record a MANUAL plan_critic_gate approval snapshot to unblock the ratchet-tighter critic_pre_plan execution gate when the critic already returned APPROVED but the mechanical recorder failed to persist it (issue #2012)",agents:["architect"]},prepare_pr_workflow_checkout:{description:"prepare an auditable PR workflow checkout or restore its exact original branch/HEAD and preserved stash after terminal cleanup",agents:["architect"]},record_implementation_review:{description:"record fresh-context reviewer + critic APPROVE verdicts for the implementation diff so the /swarm issue --trace workflow can satisfy its review gate before commit-pr handoff",agents:["architect"]},record_issue_publication:{description:"record a publication receipt so the /swarm issue --trace workflow reaches its terminal published state after the PR is created/updated",agents:["architect"]},record_issue_reproduction:{description:"record the reproduction outcome for the current traced issue so the /swarm issue --trace workflow can satisfy its reproduction gate and transition to PLAN",agents:["architect"]},record_recurrence_sweep:{description:"record the recurrence sweep (defect class, predicates, hit dispositions, guardrail proof) so the /swarm issue --trace workflow can satisfy its recurrence gate before commit-pr handoff",agents:["architect"]},rebind_pr_feedback_head:{description:"rebind a PR_FEEDBACK workflow to a new verified remote PR head after merge/rebase/conflict repair, invalidating ancestry-bound receipts so the mechanical ladder re-runs",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_finding_validator","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"]},plan_conflict_check:{description:"read-only advisory check (#1656): compute a pairwise file-conflict matrix for N proposed parallel task groups using declared scopes and optional git co-change; returns a verdict (all_disjoint / conflicts_present / unknown_scopes), per-pair evidence, and a suggested serialization order. Writes nothing — the execution gate independently recomputes the verdict inline at dispatch time via the same helper. Call BEFORE attempting parallel dispatch to confirm disjointness.",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","critic_finding_validator","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_finding_validator","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","critic_finding_validator","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_finding_validator","critic","coder","test_engineer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},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"]},consensus_mine:{description:"mine cross-run consensus from existing .swarm evidence into an immutable proposals-only report; also deletes its own reports past consensus.report_retention, appends to the shared recommendation dedup ledger (in the shared cohort root, outside this project, when a knowledge link is active), and mirrors proposals into pending swarm-memory proposals when memory is enabled",agents:["architect","curator_phase","curator_postmortem"]},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_finding_validator","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_finding_validator","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"}},pr_workflow_status:{description:"Read-only architect observation of local git state (HEAD, branch, clean/dirty with a bounded changed-file list, remotes) plus a session-pinned PR workflow gate summary. Use to observe state under the fail-closed PR_REVIEW/PR_FEEDBACK gate. Never executes PR-controlled scripts and never reads another session gate.",agents:["architect"],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_finding_validator","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","critic_finding_validator"]},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_finding_validator","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 or exact future plan identity: 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 and never creates state.",agents:["architect"]},set_qa_gates:{description:"configure the QA gate profile for the current plan or bootstrap an exact future plan with swarm_id and plan_title. Architect-only. The initial selection may set explicit true/false values over defaults; later changes are ratchet-tighter and rejected once 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, plus adopt_legacy_binding_only for exact-binding recovery without mutating gates.",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_finding_validator","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_finding_validator","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. Inline output for a settled lane is delivered only once: later polls of the same lane set output_omitted_repeat: true and omit output, but still include output_ref for recovery via retrieve_lane_output.",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,SUMMARIZER_EXEMPT_TOOL_NAMES,DEFAULT_MODELS,DEFAULT_AGENT_CONFIGS,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
 
@@ -1976,7 +1976,7 @@ ${stackPrefix}`;return INFRASTRUCTURE_FAILURE_PATTERNS.some((pattern)=>pattern.t
1976
1976
  `),idx=lineNum-1,window2=[getLine(lines,idx-1),getLine(lines,idx),getLine(lines,idx+1)].join(`
1977
1977
  `),hash4=crypto10.createHash("sha256").update(window2).digest("hex").slice(0,16);return{fingerprint:`${relFile}|${finding.rule_id}|${hash4}|#${occurrenceIndex}`,stable:!0}}catch{return{fingerprint:`${relFile}|${finding.rule_id}|L${lineNum}|UNSTABLE|#${occurrenceIndex}`,stable:!1}}}function assignOccurrenceIndices(findings,directory){let countMap=new Map;return findings.map((finding)=>{let relFile=normalizeFindingPath(directory,finding.location.file),lineNum=finding.location.line,baseKey;try{if(relFile.startsWith(".."))throw Error("escapes workspace");let lines=fs69.readFileSync(finding.location.file,"utf-8").split(`
1978
1978
  `),idx=lineNum-1,window2=[getLine(lines,idx-1),getLine(lines,idx),getLine(lines,idx+1)].join(`
1979
- `),hash4=crypto10.createHash("sha256").update(window2).digest("hex").slice(0,16);baseKey=`${relFile}|${finding.rule_id}|${hash4}`}catch{baseKey=`${relFile}|${finding.rule_id}|L${lineNum}|UNSTABLE`}let occIdx=countMap.get(baseKey)??0;countMap.set(baseKey,occIdx+1);let fp=_internals106.fingerprintFinding(finding,directory,occIdx);return{finding,index:occIdx,stable:fp.stable,fingerprint:fp.fingerprint}})}async function waitForLockRetry(delayMs,abortSignal){if(abortSignal?.aborted)return!1;return await new Promise((resolve57)=>{let settled=!1,finish=(value)=>{if(settled)return;settled=!0,clearTimeout(timeout),abortSignal?.removeEventListener("abort",onAbort),resolve57(value)},onAbort=()=>finish(!1),timeout=setTimeout(()=>finish(!0),delayMs);if(abortSignal?.addEventListener("abort",onAbort,{once:!0}),abortSignal?.aborted)onAbort()})}async function acquireLock2(lockPath,abortSignal){for(let attempt=0;attempt<=LOCK_RETRY_DELAYS_MS.length;attempt++){if(abortSignal?.aborted)return null;try{let fd=fs69.openSync(lockPath,"wx");return fs69.closeSync(fd),invalidateCachedArtifact(lockPath),()=>{try{fs69.unlinkSync(lockPath)}catch{}}}catch{if(attempt<LOCK_RETRY_DELAYS_MS.length){if(!await waitForLockRetry(LOCK_RETRY_DELAYS_MS[attempt],abortSignal))return null}}}return()=>{}}function validatePhase(phase){if(!Number.isInteger(phase)||phase<1)return"Invalid phase: must be a positive integer";return null}async function captureOrMergeBaseline(directory,phase,findings,engine,scannedFiles,opts){let phaseError=validatePhase(phase);if(phaseError)return{status:"error",message:phaseError};if(!scannedFiles||scannedFiles.length===0)return{status:"error",message:"capture_baseline requires non-empty changed_files"};let baselinePath,tempPath,lockPath;try{baselinePath=validateSwarmPath(directory,baselineRelPath(phase)),tempPath=validateSwarmPath(directory,tempRelPath(phase)),lockPath=validateSwarmPath(directory,lockRelPath(phase))}catch(e){return{status:"error",message:e instanceof Error?e.message:"Path validation failed"}}if(opts?.abortSignal?.aborted)return{status:"error",message:"SAST baseline capture cancelled"};fs69.mkdirSync(path135.dirname(baselinePath),{recursive:!0}),fs69.mkdirSync(path135.dirname(tempPath),{recursive:!0});let releaseLock=await acquireLock2(lockPath,opts?.abortSignal);if(!releaseLock)return{status:"error",message:"SAST baseline capture cancelled"};if(opts?.abortSignal?.aborted)return releaseLock(),{status:"error",message:"SAST baseline capture cancelled"};try{let existing=null;try{let raw=fs69.readFileSync(baselinePath,"utf-8"),parsed=JSON.parse(raw);if(parsed.schema_version===BASELINE_SCHEMA_VERSION)existing=parsed}catch{}let scannedRelFiles=new Set(scannedFiles.map((f)=>normalizeFindingPath(directory,f))),indexed=_internals106.assignOccurrenceIndices(findings,directory);if(existing&&!opts?.force){let prunedFingerprints=existing.fingerprints.filter((fp)=>{let relFile=fp.slice(0,fp.indexOf("|"));return!scannedRelFiles.has(relFile)}),prunedSnapshot=existing.findings_snapshot.filter((f)=>{return!scannedRelFiles.has(normalizeFindingPath(directory,f.location.file))}),prunedFilesIndexed=existing.files_indexed.filter((f)=>!scannedRelFiles.has(f)),mergedFingerprints=[...prunedFingerprints,...indexed.map((i)=>i.fingerprint)],mergedSnapshot=[...prunedSnapshot,...indexed.map((i)=>i.finding)],mergedFilesIndexed=[...prunedFilesIndexed,...Array.from(scannedRelFiles)],truncated2=mergedSnapshot.length>MAX_BASELINE_FINDINGS,cappedSnapshot2=truncated2?mergedSnapshot.slice(-MAX_BASELINE_FINDINGS):mergedSnapshot,cappedFingerprints2=truncated2?mergedFingerprints.slice(-MAX_BASELINE_FINDINGS):mergedFingerprints,cappedFilesIndexed=mergedFilesIndexed;if(truncated2){let survivingFiles=new Set;for(let finding of cappedSnapshot2){let relFile=normalizeFindingPath(directory,finding.location.file);survivingFiles.add(relFile)}cappedFilesIndexed=Array.from(survivingFiles)}let now3=new Date().toISOString(),bundle2={schema_version:BASELINE_SCHEMA_VERSION,phase,created_at:existing.created_at,updated_at:now3,engine,files_indexed:cappedFilesIndexed,fingerprints:cappedFingerprints2,findings_snapshot:cappedSnapshot2,truncated:truncated2},json4=JSON.stringify(bundle2,null,2);if(json4.length>MAX_BASELINE_BYTES)return{status:"error",message:`Baseline would exceed size cap (${json4.length} bytes > ${MAX_BASELINE_BYTES})`};if(opts?.abortSignal?.aborted)return{status:"error",message:"SAST baseline capture cancelled"};if(fs69.writeFileSync(tempPath,json4,"utf-8"),opts?.abortSignal?.aborted)return fs69.rmSync(tempPath,{force:!0}),{status:"error",message:"SAST baseline capture cancelled"};return fs69.renameSync(tempPath,baselinePath),invalidateCachedArtifact(baselinePath),{status:"merged",path:baselinePath,fingerprint_count:cappedFingerprints2.length}}let newFingerprints=indexed.map((i)=>i.fingerprint),newSnapshot=indexed.map((i)=>i.finding),truncated=newSnapshot.length>MAX_BASELINE_FINDINGS,cappedSnapshot=truncated?newSnapshot.slice(0,MAX_BASELINE_FINDINGS):newSnapshot,cappedFingerprints=truncated?newFingerprints.slice(0,MAX_BASELINE_FINDINGS):newFingerprints,now2=new Date().toISOString(),bundle={schema_version:BASELINE_SCHEMA_VERSION,phase,created_at:now2,updated_at:now2,engine,files_indexed:Array.from(scannedRelFiles),fingerprints:cappedFingerprints,findings_snapshot:cappedSnapshot,truncated},json3=JSON.stringify(bundle,null,2);if(json3.length>MAX_BASELINE_BYTES)return{status:"error",message:`Baseline would exceed size cap (${json3.length} bytes > ${MAX_BASELINE_BYTES})`};if(opts?.abortSignal?.aborted)return{status:"error",message:"SAST baseline capture cancelled"};if(fs69.writeFileSync(tempPath,json3,"utf-8"),opts?.abortSignal?.aborted)return fs69.rmSync(tempPath,{force:!0}),{status:"error",message:"SAST baseline capture cancelled"};return fs69.renameSync(tempPath,baselinePath),invalidateCachedArtifact(baselinePath),{status:"written",path:baselinePath,fingerprint_count:cappedFingerprints.length}}finally{releaseLock()}}function loadBaseline(directory,phase){let phaseError=validatePhase(phase);if(phaseError)return{status:"invalid_schema",errors:[phaseError]};let baselinePath;try{baselinePath=validateSwarmPath(directory,baselineRelPath(phase))}catch(e){return{status:"invalid_schema",errors:[e instanceof Error?e.message:"Path validation failed"]}}try{let raw=fs69.readFileSync(baselinePath,"utf-8"),parsed=JSON.parse(raw);if(parsed.schema_version!==BASELINE_SCHEMA_VERSION)return{status:"invalid_schema",errors:[`Unknown schema version: ${String(parsed.schema_version)}`]};if(!Array.isArray(parsed.fingerprints))return{status:"invalid_schema",errors:["Missing or invalid fingerprints array"]};return{status:"found",fingerprints:new Set(parsed.fingerprints),bundle:parsed}}catch(e){if(e.code==="ENOENT")return{status:"not_found"};return{status:"invalid_schema",errors:[e instanceof Error?e.message:"Failed to read baseline"]}}}var BASELINE_SCHEMA_VERSION="1.0.0",MAX_BASELINE_FINDINGS=2000,MAX_BASELINE_BYTES=2097152,LOCK_RETRY_DELAYS_MS,_internals106;var init_sast_baseline=__esm(()=>{init_utils2();init_swarm_artifact_cache();LOCK_RETRY_DELAYS_MS=[50,100,200,400,800];_internals106={fingerprintFinding,assignOccurrenceIndices,captureOrMergeBaseline,loadBaseline}});import*as fs70 from"node:fs";import*as path136 from"node:path";import{extname as extname10}from"node:path";function shouldSkipFile(filePath){try{let stats2=fs70.statSync(filePath);if(stats2.size>MAX_FILE_SIZE_BYTES2)return{skip:!0,reason:"file too large"};if(stats2.size===0)return{skip:!0,reason:"empty file"};let fd=fs70.openSync(filePath,"r"),buffer=Buffer.alloc(8192),bytesRead=fs70.readSync(fd,buffer,0,8192,0);if(fs70.closeSync(fd),bytesRead>0){let nullCount=0;for(let i=0;i<bytesRead;i++)if(buffer[i]===0)nullCount++;if(nullCount/bytesRead>0.1)return{skip:!0,reason:"binary file"}}return{skip:!1}}catch{return{skip:!0,reason:"cannot read file"}}}function meetsThreshold(severity,threshold){let severityLevel=SEVERITY_ORDER[severity]??0,thresholdLevel=SEVERITY_ORDER[threshold]??1;return severityLevel>=thresholdLevel}function countBySeverity(findings){let counts={critical:0,high:0,medium:0,low:0};for(let finding of findings){let severity=finding.severity.toLowerCase();if(severity in counts)counts[severity]++}return counts}function safeSemgrepDiagnostic(message){let diagnostic=message.trim();if(diagnostic==="Semgrep process timed out"||diagnostic==="Semgrep execution cancelled"||diagnostic==="Semgrep is not installed or not available on PATH"||diagnostic==="Semgrep returned invalid JSON output"||diagnostic==="Semgrep process failed to start or terminate safely"||diagnostic==="Semgrep execution failed unexpectedly")return diagnostic;if(/^Semgrep exited with code -?\d+$/.test(diagnostic))return diagnostic;if(/^Semgrep reported \d+ scan errors?$/.test(diagnostic))return diagnostic;if(diagnostic.startsWith("Semgrep output exceeded"))return"Semgrep output exceeded its bounded limit; results incomplete";return"Semgrep execution failed"}function cancelledScanResult(findings,filesScanned){let finalFindings=findings.slice(0,MAX_FINDINGS);return{verdict:"fail",error:"SAST scan cancelled",findings:finalFindings,summary:{engine:"tier_a",files_scanned:filesScanned,findings_count:finalFindings.length,findings_by_severity:countBySeverity(finalFindings)}}}function scanFileWithTierA(filePath,language){try{let content=fs70.readFileSync(filePath,"utf-8");return executeRulesSync(filePath,content,language).map((f)=>({rule_id:f.rule_id,severity:f.severity,message:f.message,location:{file:f.location.file,line:f.location.line,column:f.location.column},remediation:f.remediation}))}catch{return[]}}async function sastScan(input,directory,config3){let{changed_files,severity_threshold="medium",capture_baseline=!1,phase,offline_only=!1,abort_signal}=input;if(config3?.gates?.sast_scan?.enabled===!1)return{verdict:"pass",findings:[],summary:{engine:"tier_a",files_scanned:0,findings_count:0,findings_by_severity:{critical:0,high:0,medium:0,low:0}}};let allFindings=[],filesScanned=0,_filesSkipped=0,scannedFilePaths=[];if(abort_signal?.aborted)return cancelledScanResult(allFindings,filesScanned);let semgrepAvailable=!offline_only&&await _internals107.checkSemgrepAvailable(directory,abort_signal),engine=semgrepAvailable?"tier_a+tier_b":"tier_a",filesByLanguage=new Map,semgrepError=abort_signal?.aborted?"SAST scan cancelled":void 0;for(let filePath of changed_files){if(abort_signal?.aborted)return cancelledScanResult(allFindings,filesScanned);if(typeof filePath!=="string"||!filePath){_filesSkipped++;continue}let resolvedPath=path136.isAbsolute(filePath)?filePath:path136.resolve(directory,filePath),resolvedDirectory=path136.resolve(directory);if(!resolvedPath.startsWith(resolvedDirectory+path136.sep)&&resolvedPath!==resolvedDirectory){_filesSkipped++;continue}if(!fs70.existsSync(resolvedPath)){_filesSkipped++;continue}if(shouldSkipFile(resolvedPath).skip){_filesSkipped++;continue}let ext=extname10(resolvedPath).toLowerCase(),profile=getProfileForFile(resolvedPath),langDef=getLanguageForExtension(ext);if(!profile&&!langDef){_filesSkipped++;continue}let language=profile?.id??langDef.id;if(profile?profile.sast.nativeRuleSet!==null:!!langDef){let tierAFindings=scanFileWithTierA(resolvedPath,language);allFindings.push(...tierAFindings)}if(semgrepAvailable){if(profile&&profile.sast.nativeRuleSet===null&&profile.sast.semgrepSupport!=="none"){let bucketKey=`auto:${profile.id}`,existing=filesByLanguage.get(bucketKey)||[];existing.push(resolvedPath),filesByLanguage.set(bucketKey,existing)}else if(!(profile&&profile.sast.nativeRuleSet===null&&profile.sast.semgrepSupport==="none")){let existing=filesByLanguage.get(language)||[];existing.push(resolvedPath),filesByLanguage.set(language,existing)}}if(filesScanned++,scannedFilePaths.push(resolvedPath),filesScanned>=MAX_FILES_SCANNED){warn(`SAST Scan: Reached maximum files limit (${MAX_FILES_SCANNED}), stopping`);break}}if(semgrepAvailable&&filesByLanguage.size>0)try{for(let[bucketKey,bucketFiles]of filesByLanguage.entries()){if(abort_signal?.aborted){semgrepError="SAST scan cancelled";break}if(bucketFiles.length===0)continue;let semgrepResult;if(bucketKey.startsWith("auto:")){let lang=bucketKey.slice(5);semgrepResult=await _internals107.runSemgrep({files:bucketFiles,lang,useAutoConfig:!0,cwd:directory,abortSignal:abort_signal})}else semgrepResult=await _internals107.runSemgrep({files:bucketFiles,cwd:directory,abortSignal:abort_signal});if(semgrepResult.error){semgrepError=safeSemgrepDiagnostic(semgrepResult.error);break}if(semgrepResult.findings.length>0){let semgrepFindings=semgrepResult.findings.map((f)=>({rule_id:f.rule_id,severity:f.severity,message:f.message,location:{file:f.location.file,line:f.location.line,column:f.location.column},remediation:f.remediation})),existingKeys=new Set(allFindings.map((f)=>`${f.rule_id}:${f.location.file}:${f.location.line}`));for(let finding of semgrepFindings){let key=`${finding.rule_id}:${finding.location.file}:${finding.location.line}`;if(!existingKeys.has(key))allFindings.push(finding),existingKeys.add(key)}}}}catch{semgrepError="Semgrep execution failed"}if(abort_signal?.aborted)return cancelledScanResult(allFindings,filesScanned);if(semgrepError){let finalFindings2=allFindings.slice(0,MAX_FINDINGS),summary2={engine:"tier_a",files_scanned:filesScanned,findings_count:finalFindings2.length,findings_by_severity:countBySeverity(finalFindings2)};if(warn(`SAST Scan: Semgrep execution failed closed: ${semgrepError}`),abort_signal?.aborted)return cancelledScanResult(allFindings,filesScanned);return await saveEvidence(directory,"sast_scan",{task_id:"sast_scan",type:"sast",timestamp:new Date().toISOString(),agent:"sast_scan",verdict:"fail",summary:`Semgrep execution failed: ${semgrepError}`,...summary2,findings:finalFindings2,baseline_used:!1},abort_signal),{verdict:"fail",error:`Semgrep execution failed: ${semgrepError}`,findings:finalFindings2,summary:summary2}}if(capture_baseline){if(phase===void 0||!Number.isInteger(phase)||phase<1)return{verdict:"fail",findings:allFindings.slice(0,MAX_FINDINGS),summary:{engine,files_scanned:filesScanned,findings_count:Math.min(allFindings.length,MAX_FINDINGS),findings_by_severity:countBySeverity(allFindings.slice(0,MAX_FINDINGS))}};if(scannedFilePaths.length===0){let finalFindings3=allFindings.slice(0,MAX_FINDINGS);return{verdict:"fail",error:"capture_baseline requires changed_files to produce a non-empty baseline",findings:finalFindings3,summary:{engine,files_scanned:filesScanned,findings_count:finalFindings3.length,findings_by_severity:countBySeverity(finalFindings3)}}}let captureFindings=allFindings.slice(0,MAX_BASELINE_FINDINGS);if(abort_signal?.aborted)return cancelledScanResult(allFindings,filesScanned);let captureResult=await captureOrMergeBaseline(directory,phase,captureFindings,engine,scannedFilePaths,{abortSignal:abort_signal}),captureStatus=captureResult.status==="written"?"baseline_captured":captureResult.status==="merged"?"baseline_merged":void 0;if(captureResult.status==="error")warn(`SAST Baseline: capture failed — ${captureResult.message}`);let finalFindings2=allFindings.slice(0,MAX_FINDINGS),summary2={engine,files_scanned:filesScanned,findings_count:finalFindings2.length,findings_by_severity:countBySeverity(finalFindings2)};if(abort_signal?.aborted)return cancelledScanResult(allFindings,filesScanned);return await saveEvidence(directory,"sast_scan",{task_id:"sast_scan",type:"sast",timestamp:new Date().toISOString(),agent:"sast_scan",verdict:"pass",summary:`Baseline capture: scanned ${filesScanned} files, recorded ${captureFindings.length} finding(s)`,...summary2,findings:finalFindings2,baseline_used:!1},abort_signal),{verdict:"pass",findings:finalFindings2,summary:summary2,status:captureStatus,finding_count:captureResult.status!=="error"?captureResult.fingerprint_count:void 0,baseline_used:!1}}let newFindings,preExistingFindings,baselineUsed=!1,truncatedPreExisting=!1;if(phase!==void 0&&Number.isInteger(phase)&&phase>=1){let baselineResult=loadBaseline(directory,phase);if(baselineResult.status==="found"){baselineUsed=!0;let baselineSet=baselineResult.fingerprints,indexed=assignOccurrenceIndices(allFindings,directory),rawNew=[],rawPreExisting=[];for(let{finding,stable,fingerprint:fingerprint2}of indexed)if(!stable||!baselineSet.has(fingerprint2))rawNew.push(finding);else rawPreExisting.push(finding);newFindings=rawNew.slice(0,MAX_FINDINGS);let preExistingBudget=Math.max(0,MAX_FINDINGS-newFindings.length);preExistingFindings=rawPreExisting.slice(0,preExistingBudget),truncatedPreExisting=rawPreExisting.length>preExistingBudget}else if(baselineResult.status==="invalid_schema")warn(`SAST Baseline: could not load baseline for phase ${phase} — ${baselineResult.errors.join(", ")}. Falling back to legacy behavior.`)}let finalFindings;if(!baselineUsed){if(finalFindings=allFindings,allFindings.length>MAX_FINDINGS)finalFindings=allFindings.slice(0,MAX_FINDINGS),warn(`SAST Scan: Found ${allFindings.length} findings, limiting to ${MAX_FINDINGS}`)}else finalFindings=[...newFindings??[],...preExistingFindings??[]].slice(0,MAX_FINDINGS);let findingsBySeverity=countBySeverity(finalFindings),verdictSource=baselineUsed?newFindings??[]:finalFindings,verdict="pass";for(let finding of verdictSource)if(meetsThreshold(finding.severity,severity_threshold)){verdict="fail";break}if(filesScanned===0)verdict="fail";let summary={engine,files_scanned:filesScanned,findings_count:finalFindings.length,findings_by_severity:findingsBySeverity};if(abort_signal?.aborted)return cancelledScanResult(allFindings,filesScanned);await saveEvidence(directory,"sast_scan",{task_id:"sast_scan",type:"sast",timestamp:new Date().toISOString(),agent:"sast_scan",verdict,summary:`Scanned ${filesScanned} files, found ${finalFindings.length} finding(s) using ${engine}`,...summary,findings:finalFindings,...baselineUsed&&{new_findings:newFindings,pre_existing_findings:preExistingFindings,baseline_used:!0}},abort_signal);let result={verdict,findings:finalFindings,summary};if(baselineUsed){if(result.new_findings=newFindings,result.pre_existing_findings=preExistingFindings,result.baseline_used=!0,truncatedPreExisting)result.truncated_pre_existing=!0}return result}var MAX_FILE_SIZE_BYTES2=524288,MAX_FILES_SCANNED=1000,MAX_FINDINGS=100,SEVERITY_ORDER,sast_scan,_internals107;var init_sast_scan=__esm(()=>{init_zod();init_manager2();init_detector();init_registry();init_rules();init_semgrep();init_utils();init_create_tool();init_sast_baseline();SEVERITY_ORDER={low:0,medium:1,high:2,critical:3};sast_scan=createSwarmTool({allowWorkingDirectoryOverride:!0,description:"Static Application Security Testing (SAST) scan. Scans files for security vulnerabilities using built-in rules (Tier A) and optional Semgrep (Tier B). Supports phase-scoped baseline diffing: set capture_baseline:true before first coder delegation to snapshot pre-existing findings; subsequent scans with the same phase only fail on NEW findings.",args:{directory:exports_external.string().describe("Directory to scan for security vulnerabilities"),changed_files:exports_external.array(exports_external.string()).optional().describe("List of files to scan (leave empty to scan none)"),severity_threshold:exports_external.enum(["low","medium","high","critical"]).optional().default("medium").describe("Minimum severity that causes failure"),capture_baseline:exports_external.boolean().optional().describe("When true, capture/merge a phase-scoped baseline of pre-existing findings. Requires phase. Subsequent scans with phase only fail on NEW findings."),phase:exports_external.number().int().min(1).optional().describe("Current phase number (positive integer >= 1). Required with capture_baseline. Enables baseline diff when provided on non-capture scans.")},execute:async(args2,directory,ctx)=>{let safeArgs;try{if(args2&&typeof args2==="object"){let{phase:rawPhase,capture_baseline:rawCapture}=args2;safeArgs={directory:args2.directory,changed_files:args2.changed_files,severity_threshold:args2.severity_threshold,phase:typeof rawPhase==="number"&&Number.isInteger(rawPhase)&&rawPhase>=1?rawPhase:void 0,capture_baseline:typeof rawCapture==="boolean"?rawCapture:void 0}}else safeArgs={directory:void 0,changed_files:void 0,severity_threshold:void 0,capture_baseline:void 0,phase:void 0}}catch{safeArgs={directory:void 0,changed_files:void 0,severity_threshold:void 0,capture_baseline:void 0,phase:void 0}}if(safeArgs.directory===void 0)return JSON.stringify({verdict:"fail",findings:[],summary:{engine:"tier_a",files_scanned:0,findings_count:0,findings_by_severity:{critical:0,high:0,medium:0,low:0}}},null,2);let input={changed_files:safeArgs.changed_files??[],severity_threshold:safeArgs.severity_threshold??"medium",capture_baseline:safeArgs.capture_baseline,phase:safeArgs.phase,abort_signal:ctx?.abort},result=await _internals107.sastScan(input,directory);return JSON.stringify(result,null,2)}}),_internals107={sastScan,sast_scan,checkSemgrepAvailable:(directory,abortSignal)=>checkSemgrepAvailable(directory,abortSignal),isSemgrepAvailable:()=>isSemgrepAvailable(),runSemgrep:(options)=>runSemgrep(options)}});import*as crypto11 from"node:crypto";import*as fs71 from"node:fs";import*as os21 from"node:os";import*as path137 from"node:path";async function git(projectRoot,args2,abortSignal){let executable=_internals108.resolveExecutableFromPath(["git"]);if(!executable)throw Error("git executable not found");let result=await _internals108.runExternalTool({executable,args:["-C",projectRoot,...args2],cwd:projectRoot,timeoutMs:GIT_TIMEOUT_MS7,maxStdoutBytes:MAX_GIT_OUTPUT_BYTES2,maxStderrBytes:MAX_GIT_OUTPUT_BYTES2,abortSignal});if(result.status!=="completed"||result.exitCode!==0)throw Error(`git ${args2[0]??""} failed: ${result.message??result.stderr.trim()??result.status}`);return{stdout:result.stdout,stderr:result.stderr}}async function captureWorkingTreeFingerprint(projectRoot,abortSignal){let canonicalRoot=fs71.realpathSync(projectRoot),head2=await git(canonicalRoot,["rev-parse","HEAD"],abortSignal),porcelain=await git(canonicalRoot,["status","--porcelain=v1","-z","--untracked-files=all","--",".",":(exclude).swarm/**"],abortSignal);return{head:head2.stdout.trim(),porcelainHash:crypto11.createHash("sha256").update(porcelain.stdout).digest("hex")}}async function createDisposableWorktree(projectRoot,baseRef,abortSignal){let canonicalRoot=fs71.realpathSync(projectRoot);if(!/^[A-Fa-f0-9]{40,64}$/.test(baseRef))throw Error("Evaluation baseRef must be a full commit hash");let parent=path137.join(_internals108.tmpdir(),WORKTREE_PARENT);fs71.mkdirSync(parent,{recursive:!0});let canonicalParent=fs71.realpathSync(parent),worktreePath=path137.join(canonicalParent,crypto11.randomUUID());return await git(canonicalRoot,["worktree","add","--detach",worktreePath,baseRef],abortSignal),{path:fs71.realpathSync(worktreePath),baseSha:baseRef}}async function removeDisposableWorktree(projectRoot,worktreePath){let canonicalRoot=fs71.realpathSync(projectRoot),expectedParent=fs71.realpathSync(path137.join(_internals108.tmpdir(),WORKTREE_PARENT)),resolved=path137.resolve(worktreePath),relative31=path137.relative(expectedParent,resolved);if(!relative31||relative31===".."||relative31.startsWith(`..${path137.sep}`)||path137.isAbsolute(relative31))throw Error("Refusing to remove a worktree outside the evaluation root");let cleanupErrors=[];try{await git(canonicalRoot,["worktree","remove","--force",resolved])}catch(error93){cleanupErrors.push(`git-remove: ${error93 instanceof Error?error93.message:String(error93)}`)}try{_internals108.rmSync(resolved,{recursive:!0,force:!0})}catch(error93){cleanupErrors.push(`filesystem-remove: ${error93 instanceof Error?error93.message:String(error93)}`)}try{await git(canonicalRoot,["worktree","prune","--expire","now"])}catch(error93){cleanupErrors.push(`git-prune: ${error93 instanceof Error?error93.message:String(error93)}`)}let pathPresent=_internals108.existsSync(resolved),registrationPresent;try{let listed=await git(canonicalRoot,["worktree","list","--porcelain","-z"]),normalizedTarget=normalizeWorktreePath(resolved);registrationPresent=listed.stdout.split("\x00").filter((field)=>field.startsWith("worktree ")).some((field)=>normalizeWorktreePath(field.slice(9))===normalizedTarget)}catch(error93){cleanupErrors.push(`git-list: ${error93 instanceof Error?error93.message:String(error93)}`)}if(pathPresent||registrationPresent!==!1)throw new DisposableWorktreeCleanupError(resolved,pathPresent,registrationPresent,cleanupErrors)}function normalizeWorktreePath(value){let resolved=path137.resolve(value);return process.platform==="win32"?resolved.toLowerCase():resolved}async function withDisposableWorktree(args2){let before=await _internals108.captureWorkingTreeFingerprint(args2.projectRoot,args2.abortSignal),worktree;try{return worktree=await _internals108.createDisposableWorktree(args2.projectRoot,args2.baseRef,args2.abortSignal),await args2.run(worktree)}finally{let cleanupFailure;if(worktree)try{await _internals108.removeDisposableWorktree(args2.projectRoot,worktree.path)}catch(error93){cleanupFailure=error93}let after=await _internals108.captureWorkingTreeFingerprint(args2.projectRoot);if(before.head!==after.head||before.porcelainHash!==after.porcelainHash)throw Error("Evaluation changed the active working tree");if(cleanupFailure)throw cleanupFailure}}var GIT_TIMEOUT_MS7=30000,MAX_GIT_OUTPUT_BYTES2=4194304,WORKTREE_PARENT="opencode-swarm-evaluation",DisposableWorktreeCleanupError,_internals108;var init_disposable_worktree=__esm(()=>{init_external_tool_runner();DisposableWorktreeCleanupError=class DisposableWorktreeCleanupError extends Error{worktreePath;pathPresent;registrationPresent;cleanupErrors;code="evaluation-worktree-cleanup-failed";constructor(worktreePath,pathPresent,registrationPresent,cleanupErrors){super(`Evaluation worktree cleanup could not be verified for ${worktreePath} (pathPresent=${pathPresent}, registrationPresent=${String(registrationPresent)})`);this.worktreePath=worktreePath;this.pathPresent=pathPresent;this.registrationPresent=registrationPresent;this.cleanupErrors=cleanupErrors;this.name="DisposableWorktreeCleanupError"}};_internals108={runExternalTool,resolveExecutableFromPath,tmpdir:os21.tmpdir,rmSync:fs71.rmSync,existsSync:fs71.existsSync,captureWorkingTreeFingerprint,createDisposableWorktree,removeDisposableWorktree}});import*as crypto12 from"node:crypto";import*as fs72 from"node:fs";import*as os22 from"node:os";import*as path138 from"node:path";function errorCell(args2){return{v:1,taskId:args2.task.id,candidateId:args2.candidateId,defectType:args2.task.category,gate:args2.gate,model:args2.model,repetition:args2.repetition,outcome:args2.outcome??"infrastructure_failure",retries:args2.retries??0,cost:args2.cost??{source:"unavailable"},durationMs:Date.now()-args2.startedAt,failureClassification:"infrastructure_failure",failureCode:args2.failureCode}}function parseModelVerdict(text){return ModelVerdictSchema.parse(JSON.parse(text.trim()))}function modelPrompt(task,instruction,variant,fixtureDir){return["You are executing a read-only production gate audit against a curated defect fixture.",`Defect id: ${task.id}`,`Category: ${task.category}`,variant==="defect"?instruction:"This is a reviewed clean control. Report caught=false unless you find a concrete defect in the supplied implementation.",`Inspect ONLY the files under: ${fixtureDir}`,"Do not modify them and do not inspect files outside that directory.","Return exactly one JSON object and no markdown:",'{"v":1,"caught":true|false,"reason":"concise evidence"}'].join(`
1979
+ `),hash4=crypto10.createHash("sha256").update(window2).digest("hex").slice(0,16);baseKey=`${relFile}|${finding.rule_id}|${hash4}`}catch{baseKey=`${relFile}|${finding.rule_id}|L${lineNum}|UNSTABLE`}let occIdx=countMap.get(baseKey)??0;countMap.set(baseKey,occIdx+1);let fp=_internals106.fingerprintFinding(finding,directory,occIdx);return{finding,index:occIdx,stable:fp.stable,fingerprint:fp.fingerprint}})}async function waitForLockRetry(delayMs,abortSignal){if(abortSignal?.aborted)return!1;return await new Promise((resolve57)=>{let settled=!1,finish=(value)=>{if(settled)return;settled=!0,clearTimeout(timeout),abortSignal?.removeEventListener("abort",onAbort),resolve57(value)},onAbort=()=>finish(!1),timeout=setTimeout(()=>finish(!0),delayMs);if(abortSignal?.addEventListener("abort",onAbort,{once:!0}),abortSignal?.aborted)onAbort()})}async function acquireLock2(lockPath,abortSignal){for(let attempt=0;attempt<=LOCK_RETRY_DELAYS_MS.length;attempt++){if(abortSignal?.aborted)return null;try{let fd=fs69.openSync(lockPath,"wx");return fs69.closeSync(fd),invalidateCachedArtifact(lockPath),()=>{try{fs69.unlinkSync(lockPath)}catch{}}}catch{if(attempt<LOCK_RETRY_DELAYS_MS.length){if(!await waitForLockRetry(LOCK_RETRY_DELAYS_MS[attempt],abortSignal))return null}}}return()=>{}}function validatePhase(phase){if(!Number.isInteger(phase)||phase<1)return"Invalid phase: must be a positive integer";return null}async function captureOrMergeBaseline(directory,phase,findings,engine,scannedFiles,opts){let phaseError=validatePhase(phase);if(phaseError)return{status:"error",message:phaseError};if(!scannedFiles||scannedFiles.length===0)return{status:"error",message:"capture_baseline requires non-empty changed_files"};let baselinePath,tempPath,lockPath;try{baselinePath=validateSwarmPath(directory,baselineRelPath(phase)),tempPath=validateSwarmPath(directory,tempRelPath(phase)),lockPath=validateSwarmPath(directory,lockRelPath(phase))}catch(e){return{status:"error",message:e instanceof Error?e.message:"Path validation failed"}}if(opts?.abortSignal?.aborted)return{status:"error",message:"SAST baseline capture cancelled"};fs69.mkdirSync(path135.dirname(baselinePath),{recursive:!0}),fs69.mkdirSync(path135.dirname(tempPath),{recursive:!0});let releaseLock=await acquireLock2(lockPath,opts?.abortSignal);if(!releaseLock)return{status:"error",message:"SAST baseline capture cancelled"};if(opts?.abortSignal?.aborted)return releaseLock(),{status:"error",message:"SAST baseline capture cancelled"};try{let existing=null;try{let raw=fs69.readFileSync(baselinePath,"utf-8"),parsed=JSON.parse(raw);if(parsed.schema_version===BASELINE_SCHEMA_VERSION)existing=parsed}catch{}let scannedRelFiles=new Set(scannedFiles.map((f)=>normalizeFindingPath(directory,f))),indexed=_internals106.assignOccurrenceIndices(findings,directory);if(existing&&!opts?.force){let prunedFingerprints=existing.fingerprints.filter((fp)=>{let relFile=fp.slice(0,fp.indexOf("|"));return!scannedRelFiles.has(relFile)}),prunedSnapshot=existing.findings_snapshot.filter((f)=>{return!scannedRelFiles.has(normalizeFindingPath(directory,f.location.file))}),prunedFilesIndexed=existing.files_indexed.filter((f)=>!scannedRelFiles.has(f)),mergedFingerprints=[...prunedFingerprints,...indexed.map((i)=>i.fingerprint)],mergedSnapshot=[...prunedSnapshot,...indexed.map((i)=>i.finding)],mergedFilesIndexed=[...prunedFilesIndexed,...Array.from(scannedRelFiles)],truncated2=mergedSnapshot.length>MAX_BASELINE_FINDINGS,cappedSnapshot2=truncated2?mergedSnapshot.slice(-MAX_BASELINE_FINDINGS):mergedSnapshot,cappedFingerprints2=truncated2?mergedFingerprints.slice(-MAX_BASELINE_FINDINGS):mergedFingerprints,cappedFilesIndexed=mergedFilesIndexed;if(truncated2){let survivingFiles=new Set;for(let finding of cappedSnapshot2){let relFile=normalizeFindingPath(directory,finding.location.file);survivingFiles.add(relFile)}cappedFilesIndexed=Array.from(survivingFiles)}let now3=new Date().toISOString(),bundle2={schema_version:BASELINE_SCHEMA_VERSION,phase,created_at:existing.created_at,updated_at:now3,engine,files_indexed:cappedFilesIndexed,fingerprints:cappedFingerprints2,findings_snapshot:cappedSnapshot2,truncated:truncated2},json4=JSON.stringify(bundle2,null,2);if(json4.length>MAX_BASELINE_BYTES)return{status:"error",message:`Baseline would exceed size cap (${json4.length} bytes > ${MAX_BASELINE_BYTES})`};if(opts?.abortSignal?.aborted)return{status:"error",message:"SAST baseline capture cancelled"};if(fs69.writeFileSync(tempPath,json4,"utf-8"),opts?.abortSignal?.aborted)return fs69.rmSync(tempPath,{force:!0}),{status:"error",message:"SAST baseline capture cancelled"};return fs69.renameSync(tempPath,baselinePath),invalidateCachedArtifact(baselinePath),{status:"merged",path:baselinePath,fingerprint_count:cappedFingerprints2.length}}let newFingerprints=indexed.map((i)=>i.fingerprint),newSnapshot=indexed.map((i)=>i.finding),truncated=newSnapshot.length>MAX_BASELINE_FINDINGS,cappedSnapshot=truncated?newSnapshot.slice(0,MAX_BASELINE_FINDINGS):newSnapshot,cappedFingerprints=truncated?newFingerprints.slice(0,MAX_BASELINE_FINDINGS):newFingerprints,now2=new Date().toISOString(),bundle={schema_version:BASELINE_SCHEMA_VERSION,phase,created_at:now2,updated_at:now2,engine,files_indexed:Array.from(scannedRelFiles),fingerprints:cappedFingerprints,findings_snapshot:cappedSnapshot,truncated},json3=JSON.stringify(bundle,null,2);if(json3.length>MAX_BASELINE_BYTES)return{status:"error",message:`Baseline would exceed size cap (${json3.length} bytes > ${MAX_BASELINE_BYTES})`};if(opts?.abortSignal?.aborted)return{status:"error",message:"SAST baseline capture cancelled"};if(fs69.writeFileSync(tempPath,json3,"utf-8"),opts?.abortSignal?.aborted)return fs69.rmSync(tempPath,{force:!0}),{status:"error",message:"SAST baseline capture cancelled"};return fs69.renameSync(tempPath,baselinePath),invalidateCachedArtifact(baselinePath),{status:"written",path:baselinePath,fingerprint_count:cappedFingerprints.length}}finally{releaseLock()}}function loadBaseline(directory,phase){let phaseError=validatePhase(phase);if(phaseError)return{status:"invalid_schema",errors:[phaseError]};let baselinePath;try{baselinePath=validateSwarmPath(directory,baselineRelPath(phase))}catch(e){return{status:"invalid_schema",errors:[e instanceof Error?e.message:"Path validation failed"]}}try{let raw=fs69.readFileSync(baselinePath,"utf-8"),parsed=JSON.parse(raw);if(parsed.schema_version!==BASELINE_SCHEMA_VERSION)return{status:"invalid_schema",errors:[`Unknown schema version: ${String(parsed.schema_version)}`]};if(!Array.isArray(parsed.fingerprints))return{status:"invalid_schema",errors:["Missing or invalid fingerprints array"]};return{status:"found",fingerprints:new Set(parsed.fingerprints),bundle:parsed}}catch(e){if(e.code==="ENOENT")return{status:"not_found"};return{status:"invalid_schema",errors:[e instanceof Error?e.message:"Failed to read baseline"]}}}var BASELINE_SCHEMA_VERSION="1.0.0",MAX_BASELINE_FINDINGS=2000,MAX_BASELINE_BYTES=2097152,LOCK_RETRY_DELAYS_MS,_internals106;var init_sast_baseline=__esm(()=>{init_utils2();init_swarm_artifact_cache();LOCK_RETRY_DELAYS_MS=[50,100,200,400,800];_internals106={fingerprintFinding,assignOccurrenceIndices,captureOrMergeBaseline,loadBaseline}});import*as fs70 from"node:fs";import*as path136 from"node:path";import{extname as extname10}from"node:path";function shouldSkipFile(filePath){try{let stats2=fs70.statSync(filePath);if(stats2.size>MAX_FILE_SIZE_BYTES2)return{skip:!0,reason:"file too large"};if(stats2.size===0)return{skip:!0,reason:"empty file"};let fd=fs70.openSync(filePath,"r"),buffer=Buffer.alloc(8192),bytesRead=fs70.readSync(fd,buffer,0,8192,0);if(fs70.closeSync(fd),bytesRead>0){let nullCount=0;for(let i=0;i<bytesRead;i++)if(buffer[i]===0)nullCount++;if(nullCount/bytesRead>0.1)return{skip:!0,reason:"binary file"}}return{skip:!1}}catch{return{skip:!0,reason:"cannot read file"}}}function meetsThreshold(severity,threshold){let severityLevel=SEVERITY_ORDER[severity]??0,thresholdLevel=SEVERITY_ORDER[threshold]??1;return severityLevel>=thresholdLevel}function countBySeverity(findings){let counts={critical:0,high:0,medium:0,low:0};for(let finding of findings){let severity=finding.severity.toLowerCase();if(severity in counts)counts[severity]++}return counts}function safeSemgrepDiagnostic(message){let diagnostic=message.trim();if(diagnostic==="Semgrep process timed out"||diagnostic==="Semgrep execution cancelled"||diagnostic==="Semgrep is not installed or not available on PATH"||diagnostic==="Semgrep returned invalid JSON output"||diagnostic==="Semgrep process failed to start or terminate safely"||diagnostic==="Semgrep execution failed unexpectedly")return diagnostic;if(/^Semgrep exited with code -?\d+$/.test(diagnostic))return diagnostic;if(/^Semgrep reported \d+ scan errors?$/.test(diagnostic))return diagnostic;if(diagnostic.startsWith("Semgrep output exceeded"))return"Semgrep output exceeded its bounded limit; results incomplete";return"Semgrep execution failed"}function cancelledScanResult(findings,filesScanned){let finalFindings=findings.slice(0,MAX_FINDINGS);return{verdict:"fail",error:"SAST scan cancelled",findings:finalFindings,summary:{engine:"tier_a",files_scanned:filesScanned,findings_count:finalFindings.length,findings_by_severity:countBySeverity(finalFindings)}}}function scanFileWithTierA(filePath,language){try{let content=fs70.readFileSync(filePath,"utf-8");return executeRulesSync(filePath,content,language).map((f)=>({rule_id:f.rule_id,severity:f.severity,message:f.message,location:{file:f.location.file,line:f.location.line,column:f.location.column},remediation:f.remediation}))}catch{return[]}}async function sastScan(input,directory,config3){let{changed_files,severity_threshold="medium",capture_baseline=!1,phase,offline_only=!1,abort_signal}=input;if(config3?.gates?.sast_scan?.enabled===!1)return{verdict:"pass",findings:[],summary:{engine:"tier_a",files_scanned:0,findings_count:0,findings_by_severity:{critical:0,high:0,medium:0,low:0}}};let allFindings=[],filesScanned=0,_filesSkipped=0,scannedFilePaths=[];if(abort_signal?.aborted)return cancelledScanResult(allFindings,filesScanned);let semgrepAvailable=!offline_only&&await _internals107.checkSemgrepAvailable(directory,abort_signal),engine=semgrepAvailable?"tier_a+tier_b":"tier_a",filesByLanguage=new Map,semgrepError=abort_signal?.aborted?"SAST scan cancelled":void 0;for(let filePath of changed_files){if(abort_signal?.aborted)return cancelledScanResult(allFindings,filesScanned);if(typeof filePath!=="string"||!filePath){_filesSkipped++;continue}let resolvedPath=path136.isAbsolute(filePath)?filePath:path136.resolve(directory,filePath),resolvedDirectory=path136.resolve(directory);if(!resolvedPath.startsWith(resolvedDirectory+path136.sep)&&resolvedPath!==resolvedDirectory){_filesSkipped++;continue}if(!fs70.existsSync(resolvedPath)){_filesSkipped++;continue}if(shouldSkipFile(resolvedPath).skip){_filesSkipped++;continue}let ext=extname10(resolvedPath).toLowerCase(),profile=getProfileForFile(resolvedPath),langDef=getLanguageForExtension(ext);if(!profile&&!langDef){_filesSkipped++;continue}let language=profile?.id??langDef.id;if(profile?profile.sast.nativeRuleSet!==null:!!langDef){let tierAFindings=scanFileWithTierA(resolvedPath,language);allFindings.push(...tierAFindings)}if(semgrepAvailable){if(profile&&profile.sast.nativeRuleSet===null&&profile.sast.semgrepSupport!=="none"){let bucketKey=`auto:${profile.id}`,existing=filesByLanguage.get(bucketKey)||[];existing.push(resolvedPath),filesByLanguage.set(bucketKey,existing)}else if(!(profile&&profile.sast.nativeRuleSet===null&&profile.sast.semgrepSupport==="none")){let existing=filesByLanguage.get(language)||[];existing.push(resolvedPath),filesByLanguage.set(language,existing)}}if(filesScanned++,scannedFilePaths.push(resolvedPath),filesScanned>=MAX_FILES_SCANNED){warn(`SAST Scan: Reached maximum files limit (${MAX_FILES_SCANNED}), stopping`);break}}if(semgrepAvailable&&filesByLanguage.size>0)try{for(let[bucketKey,bucketFiles]of filesByLanguage.entries()){if(abort_signal?.aborted){semgrepError="SAST scan cancelled";break}if(bucketFiles.length===0)continue;let semgrepResult;if(bucketKey.startsWith("auto:")){let lang=bucketKey.slice(5);semgrepResult=await _internals107.runSemgrep({files:bucketFiles,lang,useAutoConfig:!0,cwd:directory,abortSignal:abort_signal})}else semgrepResult=await _internals107.runSemgrep({files:bucketFiles,cwd:directory,abortSignal:abort_signal});if(semgrepResult.error){semgrepError=safeSemgrepDiagnostic(semgrepResult.error);break}if(semgrepResult.findings.length>0){let semgrepFindings=semgrepResult.findings.map((f)=>({rule_id:f.rule_id,severity:f.severity,message:f.message,location:{file:f.location.file,line:f.location.line,column:f.location.column},remediation:f.remediation})),existingKeys=new Set(allFindings.map((f)=>`${f.rule_id}:${f.location.file}:${f.location.line}`));for(let finding of semgrepFindings){let key=`${finding.rule_id}:${finding.location.file}:${finding.location.line}`;if(!existingKeys.has(key))allFindings.push(finding),existingKeys.add(key)}}}}catch{semgrepError="Semgrep execution failed"}if(abort_signal?.aborted)return cancelledScanResult(allFindings,filesScanned);if(semgrepError){let finalFindings2=allFindings.slice(0,MAX_FINDINGS),summary2={engine:"tier_a",files_scanned:filesScanned,findings_count:finalFindings2.length,findings_by_severity:countBySeverity(finalFindings2)};if(warn(`SAST Scan: Semgrep execution failed closed: ${semgrepError}`),abort_signal?.aborted)return cancelledScanResult(allFindings,filesScanned);return await saveEvidence(directory,"sast_scan",{task_id:"sast_scan",type:"sast",timestamp:new Date().toISOString(),agent:"sast_scan",verdict:"fail",summary:`Semgrep execution failed: ${semgrepError}`,...summary2,findings:finalFindings2,baseline_used:!1},abort_signal),{verdict:"fail",error:`Semgrep execution failed: ${semgrepError}`,findings:finalFindings2,summary:summary2}}if(capture_baseline){if(phase===void 0||!Number.isInteger(phase)||phase<1)return{verdict:"fail",findings:allFindings.slice(0,MAX_FINDINGS),summary:{engine,files_scanned:filesScanned,findings_count:Math.min(allFindings.length,MAX_FINDINGS),findings_by_severity:countBySeverity(allFindings.slice(0,MAX_FINDINGS))}};if(scannedFilePaths.length===0){let finalFindings3=allFindings.slice(0,MAX_FINDINGS);return{verdict:"fail",error:"capture_baseline requires changed_files to produce a non-empty baseline",findings:finalFindings3,summary:{engine,files_scanned:filesScanned,findings_count:finalFindings3.length,findings_by_severity:countBySeverity(finalFindings3)}}}let captureFindings=allFindings.slice(0,MAX_BASELINE_FINDINGS);if(abort_signal?.aborted)return cancelledScanResult(allFindings,filesScanned);let captureResult=await captureOrMergeBaseline(directory,phase,captureFindings,engine,scannedFilePaths,{abortSignal:abort_signal}),captureStatus=captureResult.status==="written"?"baseline_captured":captureResult.status==="merged"?"baseline_merged":void 0;if(captureResult.status==="error")warn(`SAST Baseline: capture failed — ${captureResult.message}`);let finalFindings2=allFindings.slice(0,MAX_FINDINGS),summary2={engine,files_scanned:filesScanned,findings_count:finalFindings2.length,findings_by_severity:countBySeverity(finalFindings2)};if(abort_signal?.aborted)return cancelledScanResult(allFindings,filesScanned);return await saveEvidence(directory,"sast_scan",{task_id:"sast_scan",type:"sast",timestamp:new Date().toISOString(),agent:"sast_scan",verdict:"pass",summary:`Baseline capture: scanned ${filesScanned} files, recorded ${captureFindings.length} finding(s)`,...summary2,findings:finalFindings2,baseline_used:!1},abort_signal),{verdict:"pass",findings:finalFindings2,summary:summary2,status:captureStatus,finding_count:captureResult.status!=="error"?captureResult.fingerprint_count:void 0,baseline_used:!1}}let newFindings,preExistingFindings,baselineUsed=!1,truncatedPreExisting=!1;if(phase!==void 0&&Number.isInteger(phase)&&phase>=1){let baselineResult=loadBaseline(directory,phase);if(baselineResult.status==="found"){baselineUsed=!0;let baselineSet=baselineResult.fingerprints,indexed=assignOccurrenceIndices(allFindings,directory),rawNew=[],rawPreExisting=[];for(let{finding,stable,fingerprint:fingerprint2}of indexed)if(!stable||!baselineSet.has(fingerprint2))rawNew.push(finding);else rawPreExisting.push(finding);newFindings=rawNew.slice(0,MAX_FINDINGS);let preExistingBudget=Math.max(0,MAX_FINDINGS-newFindings.length);preExistingFindings=rawPreExisting.slice(0,preExistingBudget),truncatedPreExisting=rawPreExisting.length>preExistingBudget}else if(baselineResult.status==="invalid_schema")warn(`SAST Baseline: could not load baseline for phase ${phase} — ${baselineResult.errors.join(", ")}. Falling back to legacy behavior.`)}let finalFindings;if(!baselineUsed){if(finalFindings=allFindings,allFindings.length>MAX_FINDINGS)finalFindings=allFindings.slice(0,MAX_FINDINGS),warn(`SAST Scan: Found ${allFindings.length} findings, limiting to ${MAX_FINDINGS}`)}else finalFindings=[...newFindings??[],...preExistingFindings??[]].slice(0,MAX_FINDINGS);let findingsBySeverity=countBySeverity(finalFindings),verdictSource=baselineUsed?newFindings??[]:finalFindings,verdict="pass";for(let finding of verdictSource)if(meetsThreshold(finding.severity,severity_threshold)){verdict="fail";break}let zeroCoverageError;if(filesScanned===0)verdict="fail",zeroCoverageError="SAST requires at least one file to scan; zero files were scanned";let summary={engine,files_scanned:filesScanned,findings_count:finalFindings.length,findings_by_severity:findingsBySeverity};if(abort_signal?.aborted)return cancelledScanResult(allFindings,filesScanned);await saveEvidence(directory,"sast_scan",{task_id:"sast_scan",type:"sast",timestamp:new Date().toISOString(),agent:"sast_scan",verdict,summary:`Scanned ${filesScanned} files, found ${finalFindings.length} finding(s) using ${engine}`,...summary,findings:finalFindings,...baselineUsed&&{new_findings:newFindings,pre_existing_findings:preExistingFindings,baseline_used:!0}},abort_signal);let result={verdict,findings:finalFindings,summary,...zeroCoverageError?{error:zeroCoverageError}:{}};if(baselineUsed){if(result.new_findings=newFindings,result.pre_existing_findings=preExistingFindings,result.baseline_used=!0,truncatedPreExisting)result.truncated_pre_existing=!0}return result}var MAX_FILE_SIZE_BYTES2=524288,MAX_FILES_SCANNED=1000,MAX_FINDINGS=100,SEVERITY_ORDER,sast_scan,_internals107;var init_sast_scan=__esm(()=>{init_zod();init_manager2();init_detector();init_registry();init_rules();init_semgrep();init_utils();init_create_tool();init_sast_baseline();SEVERITY_ORDER={low:0,medium:1,high:2,critical:3};sast_scan=createSwarmTool({allowWorkingDirectoryOverride:!0,description:"Static Application Security Testing (SAST) scan. Scans files for security vulnerabilities using built-in rules (Tier A) and optional Semgrep (Tier B). Supports phase-scoped baseline diffing: set capture_baseline:true before first coder delegation to snapshot pre-existing findings; subsequent scans with the same phase only fail on NEW findings.",args:{directory:exports_external.string().describe("Directory to scan for security vulnerabilities"),changed_files:exports_external.array(exports_external.string()).optional().describe("List of files to scan (leave empty to scan none)"),severity_threshold:exports_external.enum(["low","medium","high","critical"]).optional().default("medium").describe("Minimum severity that causes failure"),capture_baseline:exports_external.boolean().optional().describe("When true, capture/merge a phase-scoped baseline of pre-existing findings. Requires phase. Subsequent scans with phase only fail on NEW findings."),phase:exports_external.number().int().min(1).optional().describe("Current phase number (positive integer >= 1). Required with capture_baseline. Enables baseline diff when provided on non-capture scans.")},execute:async(args2,directory,ctx)=>{let safeArgs;try{if(args2&&typeof args2==="object"){let{phase:rawPhase,capture_baseline:rawCapture}=args2;safeArgs={directory:args2.directory,changed_files:args2.changed_files,severity_threshold:args2.severity_threshold,phase:typeof rawPhase==="number"&&Number.isInteger(rawPhase)&&rawPhase>=1?rawPhase:void 0,capture_baseline:typeof rawCapture==="boolean"?rawCapture:void 0}}else safeArgs={directory:void 0,changed_files:void 0,severity_threshold:void 0,capture_baseline:void 0,phase:void 0}}catch{safeArgs={directory:void 0,changed_files:void 0,severity_threshold:void 0,capture_baseline:void 0,phase:void 0}}if(safeArgs.directory===void 0)return JSON.stringify({verdict:"fail",findings:[],summary:{engine:"tier_a",files_scanned:0,findings_count:0,findings_by_severity:{critical:0,high:0,medium:0,low:0}}},null,2);let input={changed_files:safeArgs.changed_files??[],severity_threshold:safeArgs.severity_threshold??"medium",capture_baseline:safeArgs.capture_baseline,phase:safeArgs.phase,abort_signal:ctx?.abort},result=await _internals107.sastScan(input,directory);return JSON.stringify(result,null,2)}}),_internals107={sastScan,sast_scan,checkSemgrepAvailable:(directory,abortSignal)=>checkSemgrepAvailable(directory,abortSignal),isSemgrepAvailable:()=>isSemgrepAvailable(),runSemgrep:(options)=>runSemgrep(options)}});import*as crypto11 from"node:crypto";import*as fs71 from"node:fs";import*as os21 from"node:os";import*as path137 from"node:path";async function git(projectRoot,args2,abortSignal){let executable=_internals108.resolveExecutableFromPath(["git"]);if(!executable)throw Error("git executable not found");let result=await _internals108.runExternalTool({executable,args:["-C",projectRoot,...args2],cwd:projectRoot,timeoutMs:GIT_TIMEOUT_MS7,maxStdoutBytes:MAX_GIT_OUTPUT_BYTES2,maxStderrBytes:MAX_GIT_OUTPUT_BYTES2,abortSignal});if(result.status!=="completed"||result.exitCode!==0)throw Error(`git ${args2[0]??""} failed: ${result.message??result.stderr.trim()??result.status}`);return{stdout:result.stdout,stderr:result.stderr}}async function captureWorkingTreeFingerprint(projectRoot,abortSignal){let canonicalRoot=fs71.realpathSync(projectRoot),head2=await git(canonicalRoot,["rev-parse","HEAD"],abortSignal),porcelain=await git(canonicalRoot,["status","--porcelain=v1","-z","--untracked-files=all","--",".",":(exclude).swarm/**"],abortSignal);return{head:head2.stdout.trim(),porcelainHash:crypto11.createHash("sha256").update(porcelain.stdout).digest("hex")}}async function createDisposableWorktree(projectRoot,baseRef,abortSignal){let canonicalRoot=fs71.realpathSync(projectRoot);if(!/^[A-Fa-f0-9]{40,64}$/.test(baseRef))throw Error("Evaluation baseRef must be a full commit hash");let parent=path137.join(_internals108.tmpdir(),WORKTREE_PARENT);fs71.mkdirSync(parent,{recursive:!0});let canonicalParent=fs71.realpathSync(parent),worktreePath=path137.join(canonicalParent,crypto11.randomUUID());return await git(canonicalRoot,["worktree","add","--detach",worktreePath,baseRef],abortSignal),{path:fs71.realpathSync(worktreePath),baseSha:baseRef}}async function removeDisposableWorktree(projectRoot,worktreePath){let canonicalRoot=fs71.realpathSync(projectRoot),expectedParent=fs71.realpathSync(path137.join(_internals108.tmpdir(),WORKTREE_PARENT)),resolved=path137.resolve(worktreePath),relative31=path137.relative(expectedParent,resolved);if(!relative31||relative31===".."||relative31.startsWith(`..${path137.sep}`)||path137.isAbsolute(relative31))throw Error("Refusing to remove a worktree outside the evaluation root");let cleanupErrors=[];try{await git(canonicalRoot,["worktree","remove","--force",resolved])}catch(error93){cleanupErrors.push(`git-remove: ${error93 instanceof Error?error93.message:String(error93)}`)}try{_internals108.rmSync(resolved,{recursive:!0,force:!0})}catch(error93){cleanupErrors.push(`filesystem-remove: ${error93 instanceof Error?error93.message:String(error93)}`)}try{await git(canonicalRoot,["worktree","prune","--expire","now"])}catch(error93){cleanupErrors.push(`git-prune: ${error93 instanceof Error?error93.message:String(error93)}`)}let pathPresent=_internals108.existsSync(resolved),registrationPresent;try{let listed=await git(canonicalRoot,["worktree","list","--porcelain","-z"]),normalizedTarget=normalizeWorktreePath(resolved);registrationPresent=listed.stdout.split("\x00").filter((field)=>field.startsWith("worktree ")).some((field)=>normalizeWorktreePath(field.slice(9))===normalizedTarget)}catch(error93){cleanupErrors.push(`git-list: ${error93 instanceof Error?error93.message:String(error93)}`)}if(pathPresent||registrationPresent!==!1)throw new DisposableWorktreeCleanupError(resolved,pathPresent,registrationPresent,cleanupErrors)}function normalizeWorktreePath(value){let resolved=path137.resolve(value);return process.platform==="win32"?resolved.toLowerCase():resolved}async function withDisposableWorktree(args2){let before=await _internals108.captureWorkingTreeFingerprint(args2.projectRoot,args2.abortSignal),worktree;try{return worktree=await _internals108.createDisposableWorktree(args2.projectRoot,args2.baseRef,args2.abortSignal),await args2.run(worktree)}finally{let cleanupFailure;if(worktree)try{await _internals108.removeDisposableWorktree(args2.projectRoot,worktree.path)}catch(error93){cleanupFailure=error93}let after=await _internals108.captureWorkingTreeFingerprint(args2.projectRoot);if(before.head!==after.head||before.porcelainHash!==after.porcelainHash)throw Error("Evaluation changed the active working tree");if(cleanupFailure)throw cleanupFailure}}var GIT_TIMEOUT_MS7=30000,MAX_GIT_OUTPUT_BYTES2=4194304,WORKTREE_PARENT="opencode-swarm-evaluation",DisposableWorktreeCleanupError,_internals108;var init_disposable_worktree=__esm(()=>{init_external_tool_runner();DisposableWorktreeCleanupError=class DisposableWorktreeCleanupError extends Error{worktreePath;pathPresent;registrationPresent;cleanupErrors;code="evaluation-worktree-cleanup-failed";constructor(worktreePath,pathPresent,registrationPresent,cleanupErrors){super(`Evaluation worktree cleanup could not be verified for ${worktreePath} (pathPresent=${pathPresent}, registrationPresent=${String(registrationPresent)})`);this.worktreePath=worktreePath;this.pathPresent=pathPresent;this.registrationPresent=registrationPresent;this.cleanupErrors=cleanupErrors;this.name="DisposableWorktreeCleanupError"}};_internals108={runExternalTool,resolveExecutableFromPath,tmpdir:os21.tmpdir,rmSync:fs71.rmSync,existsSync:fs71.existsSync,captureWorkingTreeFingerprint,createDisposableWorktree,removeDisposableWorktree}});import*as crypto12 from"node:crypto";import*as fs72 from"node:fs";import*as os22 from"node:os";import*as path138 from"node:path";function errorCell(args2){return{v:1,taskId:args2.task.id,candidateId:args2.candidateId,defectType:args2.task.category,gate:args2.gate,model:args2.model,repetition:args2.repetition,outcome:args2.outcome??"infrastructure_failure",retries:args2.retries??0,cost:args2.cost??{source:"unavailable"},durationMs:Date.now()-args2.startedAt,failureClassification:"infrastructure_failure",failureCode:args2.failureCode}}function parseModelVerdict(text){return ModelVerdictSchema.parse(JSON.parse(text.trim()))}function modelPrompt(task,instruction,variant,fixtureDir){return["You are executing a read-only production gate audit against a curated defect fixture.",`Defect id: ${task.id}`,`Category: ${task.category}`,variant==="defect"?instruction:"This is a reviewed clean control. Report caught=false unless you find a concrete defect in the supplied implementation.",`Inspect ONLY the files under: ${fixtureDir}`,"Do not modify them and do not inspect files outside that directory.","Return exactly one JSON object and no markdown:",'{"v":1,"caught":true|false,"reason":"concise evidence"}'].join(`
1980
1980
  `)}function fullFileMutationPatch(baseline,defect){let before=baseline.replace(/\r\n/g,`
1981
1981
  `).replace(/\n$/,"").split(`
1982
1982
  `),after=defect.replace(/\r\n/g,`
@@ -1992,8 +1992,8 @@ ${args2.stdout}`.trim();return{timestamp:new Date(args2.startedAt).toISOString()
1992
1992
  `)}function formatContinuationPrompt(data){let lines=[];if(lines.push("## Resume Swarm"),lines.push(""),data.currentPhase)lines.push(`**Phase**: ${data.currentPhase}`);if(data.currentTask)lines.push(`**Current Task**: ${data.currentTask}`);let nextTask;if(data.incompleteTasks.length>0){if(nextTask=data.incompleteTasks.find((t)=>t!==data.currentTask),nextTask)lines.push(`**Next Task**: ${nextTask}`)}if(data.pendingQA){if(lines.push(""),lines.push(`**Pending QA Blocker**: ${data.pendingQA.taskId}`),data.pendingQA.lastFailure)lines.push(` - Last failure: ${data.pendingQA.lastFailure}`)}if(data.recentDecisions.length>0){let last3=data.recentDecisions.slice(-3);lines.push(""),lines.push("**Recent Decisions (do not revisit)**:");for(let decision of last3)lines.push(`- ${decision}`)}if(data.incompleteTasks.length>2){let remaining=data.incompleteTasks.filter((t)=>t!==data.currentTask&&t!==nextTask);if(remaining.length>0)lines.push(""),lines.push(`**Remaining Tasks**: ${remaining.slice(0,8).join(", ")}${remaining.length>8?` (+${remaining.length-8} more)`:""}`)}if(lines.push(""),lines.push("**To resume**:"),lines.push("1. Read `.swarm/handoff.md` for full context"),lines.push("2. Use `knowledge_recall` to recall relevant lessons before starting"),data.pendingQA)lines.push(`3. Resolve QA blocker on task ${data.pendingQA.taskId} before continuing`);else if(data.currentTask)lines.push(`3. Continue work on task ${data.currentTask}`);else if(nextTask)lines.push(`3. Begin work on task ${nextTask}`);else lines.push("3. Review the plan and pick up the next incomplete task");return lines.push("4. Do not re-implement completed tasks or revisit settled decisions"),`\`\`\`markdown
1993
1993
  ${lines.join(`
1994
1994
  `)}
1995
- \`\`\``}var RTL_OVERRIDE_PATTERN,MAX_TASK_ID_LENGTH=100,MAX_DECISION_LENGTH=500,MAX_INCOMPLETE_TASKS=20,_internals109;var init_handoff_service=__esm(()=>{init_utils2();init_manager();init_utils();RTL_OVERRIDE_PATTERN=/[\u202e\u202d\u202c\u200f]/g;_internals109={getHandoffData,formatHandoffMarkdown,formatContinuationPrompt,escapeHtml,sanitizeString:sanitizeString3,validatePlanPhases,extractCurrentPhaseFromPlan:extractCurrentPhaseFromPlan2,parseSessionState,extractDecisions:extractDecisions2,extractPhaseMetrics}});import{closeSync as closeSync13,fsyncSync as fsyncSync5,mkdirSync as mkdirSync39,openSync as openSync13,renameSync as renameSync23}from"node:fs";import*as path140 from"node:path";function serializeAgentSession(s){let gateLog={},rawGateLog=s.gateLog??new Map;for(let[taskId,gates]of rawGateLog)gateLog[taskId]=Array.from(gates??[]);let reviewerCallCount={},rawReviewerCallCount=s.reviewerCallCount??new Map;for(let[phase,count]of rawReviewerCallCount)reviewerCallCount[String(phase)]=count;let partialGateWarningsIssuedForTask=Array.from(s.partialGateWarningsIssuedForTask??new Set),completionGateWarnedForTask=Array.from(s.completionGateWarnedForTask??new Set),catastrophicPhaseWarnings=Array.from(s.catastrophicPhaseWarnings??new Set),phaseAgentsDispatched=Array.from(s.phaseAgentsDispatched??new Set),lastCompletedPhaseAgentsDispatched=Array.from(s.lastCompletedPhaseAgentsDispatched??new Set),stageBCompletion={};if(s.stageBCompletion)for(let[taskId,agents]of s.stageBCompletion)stageBCompletion[taskId]=Array.from(agents);let modifiedFilesByTask=Object.create(null);for(let[taskId,files]of s.modifiedFilesByTask??new Map)modifiedFilesByTask[taskId]=[...files];let windows={},rawWindows=s.windows??{};for(let[key,win]of Object.entries(rawWindows))windows[key]={id:win.id,agentName:win.agentName,startedAtMs:win.startedAtMs,toolCalls:win.toolCalls,consecutiveErrors:win.consecutiveErrors,hardLimitHit:win.hardLimitHit,lastSuccessTimeMs:win.lastSuccessTimeMs,recentToolCalls:win.recentToolCalls,warningIssued:win.warningIssued,warningReason:win.warningReason,transientRetryCount:win.transientRetryCount??0};return{agentName:s.agentName,lastToolCallTime:s.lastToolCallTime,lastAgentEventTime:s.lastAgentEventTime,delegationActive:s.delegationActive,activeInvocationId:s.activeInvocationId,lastInvocationIdByAgent:s.lastInvocationIdByAgent??{},windows,lastCompactionHint:s.lastCompactionHint??0,architectWriteCount:s.architectWriteCount??0,lastCoderDelegationTaskId:s.lastCoderDelegationTaskId??null,currentTaskId:s.currentTaskId??null,turboMode:s.turboMode??!1,...s.turboStrategy!==void 0&&{turboStrategy:s.turboStrategy},leanTurboActive:s.leanTurboActive??!1,...s.leanTurboCurrentPhase!==void 0&&{leanTurboCurrentPhase:s.leanTurboCurrentPhase},epicModeActive:s.epicModeActive??!1,gateLog,reviewerCallCount,lastGateFailure:s.lastGateFailure??null,partialGateWarningsIssuedForTask,completionGateWarnedForTask,selfFixAttempted:s.selfFixAttempted??!1,selfCodingWarnedAtCount:s.selfCodingWarnedAtCount??0,catastrophicPhaseWarnings,lastPhaseCompleteTimestamp:s.lastPhaseCompleteTimestamp??0,lastPhaseCompletePhase:s.lastPhaseCompletePhase??0,phaseAgentsDispatched,lastCompletedPhaseAgentsDispatched,qaSkipCount:s.qaSkipCount??0,qaSkipTaskIds:s.qaSkipTaskIds??[],pendingAdvisoryMessages:s.pendingAdvisoryMessages??[],taskWorkflowStates:Object.fromEntries(s.taskWorkflowStates??new Map),...Object.keys(modifiedFilesByTask).length>0&&{modifiedFilesByTask},...s.scopeViolationDetected!==void 0&&{scopeViolationDetected:s.scopeViolationDetected},model_fallback_index:s.model_fallback_index??0,modelFallbackExhausted:s.modelFallbackExhausted??!1,coderRevisions:s.coderRevisions??0,revisionLimitHit:s.revisionLimitHit??!1,fullAutoMode:s.fullAutoMode??!1,fullAutoInteractionCount:s.fullAutoInteractionCount??0,fullAutoDeadlockCount:s.fullAutoDeadlockCount??0,fullAutoLastQuestionHash:s.fullAutoLastQuestionHash??null,sessionRehydratedAt:s.sessionRehydratedAt??0,...Object.keys(stageBCompletion).length>0&&{stageBCompletion},...s.maxConcurrencyOverride!==void 0&&{maxConcurrencyOverride:s.maxConcurrencyOverride},...s.autoProceedOverride!==void 0&&{autoProceedOverride:s.autoProceedOverride},...s.autoProceedNudgeDone!==void 0&&{autoProceedNudgeDone:s.autoProceedNudgeDone},...s.cachedCohortId!==void 0&&{cachedCohortId:s.cachedCohortId},...s.lastObservedModel!==void 0&&{lastObservedModel:s.lastObservedModel},...s.lastObservedProviderID!==void 0&&{lastObservedProviderID:s.lastObservedProviderID}}}async function writeSnapshot2(directory,state){try{let snapshot={version:3,writtenAt:Date.now(),workflowSchema:TASK_WORKFLOW_SCHEMA_MARKER,toolAggregates:Object.fromEntries(state.toolAggregates),activeAgent:Object.fromEntries(state.activeAgent),delegationChains:Object.fromEntries(state.delegationChains),agentSessions:{}};for(let[sessionId,sessionState]of state.agentSessions)snapshot.agentSessions[sessionId]=serializeAgentSession(sessionState);let content=JSON.stringify(snapshot,null,2),resolvedPath=validateSwarmPath(directory,"session/state.json"),dir=path140.dirname(resolvedPath);mkdirSync39(dir,{recursive:!0});let tempPath=`${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;await bunWrite(tempPath,content);try{let fd=openSync13(tempPath,"r+");try{fsyncSync5(fd)}finally{closeSync13(fd)}}catch{}renameSync23(tempPath,resolvedPath),invalidateCachedArtifact(resolvedPath)}catch(error93){log("[snapshot-writer] write failed",{error:error93 instanceof Error?error93.message:String(error93)})}}function createSnapshotWriterHook(directory){return(_input,_output)=>{return _writeInFlight=_writeInFlight.then(()=>_internals110.writeSnapshot(directory,swarmState),()=>_internals110.writeSnapshot(directory,swarmState)),_writeInFlight}}async function flushPendingSnapshot(directory){_writeInFlight=_writeInFlight.then(()=>_internals110.writeSnapshot(directory,swarmState),()=>_internals110.writeSnapshot(directory,swarmState)),await _writeInFlight}var _writeInFlight,_internals110;var init_snapshot_writer=__esm(()=>{init_gate_evidence();init_utils2();init_state2();init_utils();init_bun_compat();init_swarm_artifact_cache();_writeInFlight=Promise.resolve();_internals110={writeSnapshot:writeSnapshot2,createSnapshotWriterHook,flushPendingSnapshot}});import crypto13 from"node:crypto";import{renameSync as renameSync24,unlinkSync as unlinkSync20}from"node:fs";function formatSessionScopedHandoffMarkdown(markdown,sessionID){if(!sessionID)return markdown;return`${HANDOFF_SOURCE_SESSION_PREFIX} ${encodeURIComponent(sessionID)} -->
1996
- ${markdown}`}async function handleHandoffCommand(directory,_args,sessionID){let handoffData=await getHandoffData(directory),markdown=formatHandoffMarkdown(handoffData);try{let resolvedPath=validateSwarmPath(directory,"handoff.md"),tempPath=`${resolvedPath}.tmp.${crypto13.randomUUID()}`;await bunWrite(tempPath,formatSessionScopedHandoffMarkdown(markdown,sessionID));try{renameSync24(tempPath,resolvedPath)}catch(renameErr){try{unlinkSync20(tempPath)}catch{}throw renameErr}invalidateCachedArtifact(resolvedPath);let continuationPrompt=formatContinuationPrompt(handoffData),promptPath=validateSwarmPath(directory,"handoff-prompt.md"),promptTempPath=`${promptPath}.tmp.${crypto13.randomUUID()}`;await bunWrite(promptTempPath,continuationPrompt);try{renameSync24(promptTempPath,promptPath)}catch(renameErr){try{unlinkSync20(promptTempPath)}catch{}throw renameErr}return await writeSnapshot2(directory,swarmState),await flushPendingSnapshot(directory),`## Handoff Brief Written
1995
+ \`\`\``}var RTL_OVERRIDE_PATTERN,MAX_TASK_ID_LENGTH=100,MAX_DECISION_LENGTH=500,MAX_INCOMPLETE_TASKS=20,_internals109;var init_handoff_service=__esm(()=>{init_utils2();init_manager();init_utils();RTL_OVERRIDE_PATTERN=/[\u202e\u202d\u202c\u200f]/g;_internals109={getHandoffData,formatHandoffMarkdown,formatContinuationPrompt,escapeHtml,sanitizeString:sanitizeString3,validatePlanPhases,extractCurrentPhaseFromPlan:extractCurrentPhaseFromPlan2,parseSessionState,extractDecisions:extractDecisions2,extractPhaseMetrics}});import{closeSync as closeSync13,existsSync as existsSync71,fsyncSync as fsyncSync5,mkdirSync as mkdirSync39,openSync as openSync13,unlinkSync as unlinkSync20}from"node:fs";import{rename as fsRename}from"node:fs/promises";import*as path140 from"node:path";async function renameWithTransientRetry(tempPath,targetPath){let lastError;for(let attempt=0;attempt<SNAPSHOT_RENAME_MAX_ATTEMPTS;attempt++)try{await _internals110.rename(tempPath,targetPath);return}catch(error93){lastError=error93;let code=error93.code;if(code==="ENOENT"&&attempt>0&&!existsSync71(tempPath)&&existsSync71(targetPath))return;if(code!=="EEXIST"&&code!=="EBUSY"&&code!=="EPERM")break;if(attempt<SNAPSHOT_RENAME_MAX_ATTEMPTS-1)await new Promise((resolve60)=>setTimeout(resolve60,SNAPSHOT_RENAME_RETRY_DELAY_MS))}throw lastError}function serializeAgentSession(s){let gateLog={},rawGateLog=s.gateLog??new Map;for(let[taskId,gates]of rawGateLog)gateLog[taskId]=Array.from(gates??[]);let reviewerCallCount={},rawReviewerCallCount=s.reviewerCallCount??new Map;for(let[phase,count]of rawReviewerCallCount)reviewerCallCount[String(phase)]=count;let partialGateWarningsIssuedForTask=Array.from(s.partialGateWarningsIssuedForTask??new Set),completionGateWarnedForTask=Array.from(s.completionGateWarnedForTask??new Set),catastrophicPhaseWarnings=Array.from(s.catastrophicPhaseWarnings??new Set),phaseAgentsDispatched=Array.from(s.phaseAgentsDispatched??new Set),lastCompletedPhaseAgentsDispatched=Array.from(s.lastCompletedPhaseAgentsDispatched??new Set),stageBCompletion={};if(s.stageBCompletion)for(let[taskId,agents]of s.stageBCompletion)stageBCompletion[taskId]=Array.from(agents);let modifiedFilesByTask=Object.create(null);for(let[taskId,files]of s.modifiedFilesByTask??new Map)modifiedFilesByTask[taskId]=[...files];let windows={},rawWindows=s.windows??{};for(let[key,win]of Object.entries(rawWindows))windows[key]={id:win.id,agentName:win.agentName,startedAtMs:win.startedAtMs,toolCalls:win.toolCalls,consecutiveErrors:win.consecutiveErrors,hardLimitHit:win.hardLimitHit,lastSuccessTimeMs:win.lastSuccessTimeMs,recentToolCalls:win.recentToolCalls,warningIssued:win.warningIssued,warningReason:win.warningReason,transientRetryCount:win.transientRetryCount??0};return{agentName:s.agentName,lastToolCallTime:s.lastToolCallTime,lastAgentEventTime:s.lastAgentEventTime,delegationActive:s.delegationActive,activeInvocationId:s.activeInvocationId,lastInvocationIdByAgent:s.lastInvocationIdByAgent??{},windows,lastCompactionHint:s.lastCompactionHint??0,architectWriteCount:s.architectWriteCount??0,lastCoderDelegationTaskId:s.lastCoderDelegationTaskId??null,currentTaskId:s.currentTaskId??null,turboMode:s.turboMode??!1,...s.turboStrategy!==void 0&&{turboStrategy:s.turboStrategy},leanTurboActive:s.leanTurboActive??!1,...s.leanTurboCurrentPhase!==void 0&&{leanTurboCurrentPhase:s.leanTurboCurrentPhase},epicModeActive:s.epicModeActive??!1,gateLog,reviewerCallCount,lastGateFailure:s.lastGateFailure??null,partialGateWarningsIssuedForTask,completionGateWarnedForTask,selfFixAttempted:s.selfFixAttempted??!1,selfCodingWarnedAtCount:s.selfCodingWarnedAtCount??0,catastrophicPhaseWarnings,lastPhaseCompleteTimestamp:s.lastPhaseCompleteTimestamp??0,lastPhaseCompletePhase:s.lastPhaseCompletePhase??0,phaseAgentsDispatched,lastCompletedPhaseAgentsDispatched,qaSkipCount:s.qaSkipCount??0,qaSkipTaskIds:s.qaSkipTaskIds??[],pendingAdvisoryMessages:s.pendingAdvisoryMessages??[],taskWorkflowStates:Object.fromEntries(s.taskWorkflowStates??new Map),...Object.keys(modifiedFilesByTask).length>0&&{modifiedFilesByTask},...s.scopeViolationDetected!==void 0&&{scopeViolationDetected:s.scopeViolationDetected},model_fallback_index:s.model_fallback_index??0,modelFallbackExhausted:s.modelFallbackExhausted??!1,coderRevisions:s.coderRevisions??0,revisionLimitHit:s.revisionLimitHit??!1,fullAutoMode:s.fullAutoMode??!1,fullAutoInteractionCount:s.fullAutoInteractionCount??0,fullAutoDeadlockCount:s.fullAutoDeadlockCount??0,fullAutoLastQuestionHash:s.fullAutoLastQuestionHash??null,sessionRehydratedAt:s.sessionRehydratedAt??0,...Object.keys(stageBCompletion).length>0&&{stageBCompletion},...s.maxConcurrencyOverride!==void 0&&{maxConcurrencyOverride:s.maxConcurrencyOverride},...s.autoProceedOverride!==void 0&&{autoProceedOverride:s.autoProceedOverride},...s.autoProceedNudgeDone!==void 0&&{autoProceedNudgeDone:s.autoProceedNudgeDone},...s.cachedCohortId!==void 0&&{cachedCohortId:s.cachedCohortId},...s.lastObservedModel!==void 0&&{lastObservedModel:s.lastObservedModel},...s.lastObservedProviderID!==void 0&&{lastObservedProviderID:s.lastObservedProviderID}}}async function writeSnapshot2(directory,state){try{let snapshot={version:3,writtenAt:Date.now(),workflowSchema:TASK_WORKFLOW_SCHEMA_MARKER,toolAggregates:Object.fromEntries(state.toolAggregates),activeAgent:Object.fromEntries(state.activeAgent),delegationChains:Object.fromEntries(state.delegationChains),agentSessions:{}};for(let[sessionId,sessionState]of state.agentSessions)snapshot.agentSessions[sessionId]=serializeAgentSession(sessionState);let content=JSON.stringify(snapshot,null,2),resolvedPath=validateSwarmPath(directory,"session/state.json"),dir=path140.dirname(resolvedPath);mkdirSync39(dir,{recursive:!0});let tempPath=`${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;await bunWrite(tempPath,content);try{let fd=openSync13(tempPath,"r+");try{fsyncSync5(fd)}finally{closeSync13(fd)}}catch{}try{await renameWithTransientRetry(tempPath,resolvedPath)}finally{try{unlinkSync20(tempPath)}catch{}}invalidateCachedArtifact(resolvedPath)}catch(error93){log("[snapshot-writer] write failed",{error:error93 instanceof Error?error93.message:String(error93)})}}function createSnapshotWriterHook(directory){return(_input,_output)=>{return _writeInFlight=_writeInFlight.then(()=>_internals110.writeSnapshot(directory,swarmState),()=>_internals110.writeSnapshot(directory,swarmState)),_writeInFlight}}async function flushPendingSnapshot(directory){_writeInFlight=_writeInFlight.then(()=>_internals110.writeSnapshot(directory,swarmState),()=>_internals110.writeSnapshot(directory,swarmState)),await _writeInFlight}var _writeInFlight,SNAPSHOT_RENAME_MAX_ATTEMPTS=3,SNAPSHOT_RENAME_RETRY_DELAY_MS=50,_internals110;var init_snapshot_writer=__esm(()=>{init_gate_evidence();init_utils2();init_state2();init_utils();init_bun_compat();init_swarm_artifact_cache();_writeInFlight=Promise.resolve();_internals110={writeSnapshot:writeSnapshot2,createSnapshotWriterHook,flushPendingSnapshot,rename:fsRename}});import crypto13 from"node:crypto";import{renameSync as renameSync23,unlinkSync as unlinkSync21}from"node:fs";function formatSessionScopedHandoffMarkdown(markdown,sessionID){if(!sessionID)return markdown;return`${HANDOFF_SOURCE_SESSION_PREFIX} ${encodeURIComponent(sessionID)} -->
1996
+ ${markdown}`}async function handleHandoffCommand(directory,_args,sessionID){let handoffData=await getHandoffData(directory),markdown=formatHandoffMarkdown(handoffData);try{let resolvedPath=validateSwarmPath(directory,"handoff.md"),tempPath=`${resolvedPath}.tmp.${crypto13.randomUUID()}`;await bunWrite(tempPath,formatSessionScopedHandoffMarkdown(markdown,sessionID));try{renameSync23(tempPath,resolvedPath)}catch(renameErr){try{unlinkSync21(tempPath)}catch{}throw renameErr}invalidateCachedArtifact(resolvedPath);let continuationPrompt=formatContinuationPrompt(handoffData),promptPath=validateSwarmPath(directory,"handoff-prompt.md"),promptTempPath=`${promptPath}.tmp.${crypto13.randomUUID()}`;await bunWrite(promptTempPath,continuationPrompt);try{renameSync23(promptTempPath,promptPath)}catch(renameErr){try{unlinkSync21(promptTempPath)}catch{}throw renameErr}return await writeSnapshot2(directory,swarmState),await flushPendingSnapshot(directory),`## Handoff Brief Written
1997
1997
 
1998
1998
  Brief written to \`.swarm/handoff.md\`.
1999
1999
  Continuation prompt written to \`.swarm/handoff-prompt.md\`.
@@ -2037,9 +2037,9 @@ ${USAGE7}`;try{assertProjectRoot(directory)}catch(error93){return`Error: Failed
2037
2037
  ${USAGE7}`}let swarmDir=path142.join(directory,".swarm"),issueReference={url:result.sanitized,owner:issueInfo.owner,repo:issueInfo.repo,number:issueInfo.number,timestamp:new Date().toISOString(),flags:{...parsed.plan&&{plan:!0},...parsed.trace&&{trace:!0},...parsed.noRepro&&{noRepro:!0}}};if(parsed.noRepro)issueReference.noReproWaiver={waived:!0,reason:"--no-repro flag",timestamp:new Date().toISOString()};let traceState={issueNumber:issueInfo.number,lastTransition:null,status:"in_progress"},oldTraceState=null;try{oldTraceState=_internals112.readFileSync(path142.join(swarmDir,"issue-trace-state.json"),"utf-8")}catch{}try{_internals112.mkdirSync(swarmDir,{recursive:!0}),atomicWriteFileSync2(swarmDir,"issue-trace-state.json",JSON.stringify(traceState,null,2)),atomicWriteFileSync2(swarmDir,"issue-reference.json",JSON.stringify(issueReference,null,2))}catch(e){if(oldTraceState!==null)try{atomicWriteFileSync2(swarmDir,"issue-trace-state.json",oldTraceState)}catch{}else try{_internals112.unlinkSync(path142.join(swarmDir,"issue-trace-state.json"))}catch{}try{_internals112.unlinkSync(path142.join(swarmDir,"issue-reference.json"))}catch{}return`Error: Failed to persist issue reference durably: ${e instanceof Error?e.message:String(e)}
2038
2038
 
2039
2039
  ${USAGE7}`}let flags=[];if(parsed.plan)flags.push("plan=true");if(parsed.trace)flags.push("trace=true");if(parsed.noRepro)flags.push("noRepro=true");let flagsStr=flags.length>0?` ${flags.join(" ")}`:"";return`[MODE: ISSUE_INGEST issue="${result.sanitized}"${flagsStr}]`}var USAGE7,_internals112;var init_issue=__esm(()=>{init_project_boundary();init_url_security();USAGE7=["Usage: /swarm issue <url|owner/repo#N|N> [--plan] [--trace] [--no-repro]","","Ingest a GitHub issue into the swarm workflow."," /swarm issue https://github.com/owner/repo/issues/42"," /swarm issue owner/repo#42"," /swarm issue 42 --plan"," /swarm issue 42 --trace --no-repro","","Flags:"," --plan Transition to plan creation after spec generation"," --trace Run the fix workflow end-to-end (implies --plan); compose commit-pr to publish."," --no-repro Skip reproduction step"].join(`
2040
- `);_internals112={writeFileSync:fs73.writeFileSync,mkdirSync:fs73.mkdirSync,renameSync:fs73.renameSync,unlinkSync:fs73.unlinkSync,readFileSync:fs73.readFileSync,existsSync:fs73.existsSync}});import{randomUUID as randomUUID20}from"node:crypto";import{existsSync as existsSync72,readFileSync as readFileSync54}from"node:fs";import{mkdir as mkdir34,readFile as readFile38,writeFile as writeFile22}from"node:fs/promises";import*as os23 from"node:os";import*as path143 from"node:path";async function migrateKnowledgeToExternal(_directory,_config){let externalSentinelPath=path143.join(_directory,".swarm",".knowledge-external-migrated"),contextPath=path143.join(_directory,".swarm","context.md");if(_internals113.existsSync(externalSentinelPath))return{migrated:!1,entriesMigrated:0,entriesDropped:0,entriesTotal:0,skippedReason:"external-sentinel-exists"};if(!_internals113.existsSync(contextPath))return{migrated:!1,entriesMigrated:0,entriesDropped:0,entriesTotal:0,skippedReason:"no-context-file"};let contextContent=await _internals113.readFile(contextPath,"utf-8");if(contextContent.trim().length===0)return{migrated:!1,entriesMigrated:0,entriesDropped:0,entriesTotal:0,skippedReason:"empty-context"};let lines=contextContent.split(`
2041
- `),entriesCount=0;for(let line of lines)if(line.trimStart().startsWith("- "))entriesCount++;return await _internals113.writeSentinel(externalSentinelPath,entriesCount,entriesCount),{migrated:!0,entriesMigrated:entriesCount,entriesDropped:0,entriesTotal:entriesCount}}async function migrateContextToKnowledge(directory,config3){let sentinelPath=path143.join(directory,".swarm",".knowledge-migrated"),contextPath=path143.join(directory,".swarm","context.md"),knowledgePath=resolveSwarmKnowledgePath(directory);if(existsSync72(sentinelPath))return{migrated:!1,entriesMigrated:0,entriesDropped:0,entriesTotal:0,skippedReason:"sentinel-exists"};if(!existsSync72(contextPath))return{migrated:!1,entriesMigrated:0,entriesDropped:0,entriesTotal:0,skippedReason:"no-context-file"};let contextContent=await readFile38(contextPath,"utf-8");if(contextContent.trim().length===0)return{migrated:!1,entriesMigrated:0,entriesDropped:0,entriesTotal:0,skippedReason:"empty-context"};let rawEntries=_internals113.parseContextMd(contextContent);if(rawEntries.length===0)return await _internals113.writeSentinel(sentinelPath,0,0),{migrated:!0,entriesMigrated:0,entriesDropped:0,entriesTotal:0};let existing=await readKnowledge(knowledgePath),migrated=0,dropped=0,projectName=_internals113.inferProjectName(directory);for(let raw of rawEntries){if(config3.validation_enabled!==!1){let category=raw.categoryHint??_internals113.inferCategoryFromText(raw.text);if(!validateLesson(raw.text,existing.map((e)=>e.lesson),{category,scope:"global",confidence:0.3}).valid){dropped++;continue}}if(findNearDuplicate(raw.text,existing,config3.dedup_threshold??0.6)){dropped++;continue}let inferredTags=inferTags(raw.text),entry={id:randomUUID20(),tier:"swarm",lesson:_internals113.truncateLesson(raw.text),category:raw.categoryHint??_internals113.inferCategoryFromText(raw.text),tags:[...inferredTags,`migration:${raw.sourceSection}`],scope:"global",confidence:0.3,status:"candidate",confirmed_by:[],retrieval_outcomes:{applied_count:0,succeeded_after_count:0,failed_after_count:0},schema_version:config3.schema_version??KNOWLEDGE_SCHEMA_VERSION,created_at:new Date().toISOString(),updated_at:new Date().toISOString(),project_name:projectName,auto_generated:!0};existing.push(entry),migrated++}if(migrated>0)await rewriteKnowledge(knowledgePath,existing);return await _internals113.writeSentinel(sentinelPath,migrated,dropped),log(`[knowledge-migrator] Migrated ${migrated} entries, dropped ${dropped}`),{migrated:!0,entriesMigrated:migrated,entriesDropped:dropped,entriesTotal:rawEntries.length}}async function migrateHiveKnowledgeLegacy(config3){let legacyHivePath=_internals113.resolveLegacyHiveKnowledgePath(),canonicalHivePath=resolveHiveKnowledgePath2(),sentinelPath=path143.join(path143.dirname(canonicalHivePath),".hive-knowledge-migrated");if(existsSync72(sentinelPath))return{migrated:!1,entriesMigrated:0,entriesDropped:0,entriesTotal:0,skippedReason:"sentinel-exists"};if(!existsSync72(legacyHivePath))return{migrated:!1,entriesMigrated:0,entriesDropped:0,entriesTotal:0,skippedReason:"no-context-file"};let legacyEntries=await readKnowledge(legacyHivePath);if(legacyEntries.length===0)return await _internals113.writeSentinel(sentinelPath,0,0),{migrated:!0,entriesMigrated:0,entriesDropped:0,entriesTotal:0};let existingHiveEntries=await readKnowledge(canonicalHivePath),migrated=0,dropped=0,entryErrors=[];for(let legacyEntry of legacyEntries)try{let lesson=legacyEntry.lesson;if(!lesson||typeof lesson!=="string"||lesson.length<15){dropped++;continue}if(findNearDuplicate(lesson,existingHiveEntries,config3.dedup_threshold??0.6)){dropped++;continue}let category=legacyEntry.category||"process",validationResult=validateLesson(lesson,existingHiveEntries.map((e)=>e.lesson),{category,scope:"global",confidence:0.3});if(!validationResult.valid){let errorMsg=`Validation failed for legacy entry: ${validationResult.reason}`;entryErrors.push(errorMsg),warn(`[knowledge-migrator] ${errorMsg}`),dropped++;continue}let confidence=legacyEntry.confidence??0.8,scopeTag=legacyEntry.scope_tag||"global",legacyId=legacyEntry.id,existingIds=new Set(existingHiveEntries.map((e)=>e.id)),resolvedId=legacyId&&existingIds.has(legacyId)?randomUUID20():legacyId||randomUUID20();if(legacyId&&existingIds.has(legacyId))warn(`[knowledge-migrator] Legacy entry ID collision for "${legacyId}", generating new UUID`);let newHiveEntry={id:resolvedId,tier:"hive",lesson:_internals113.truncateLesson(lesson),category,tags:["migration:legacy-hive"],scope:scopeTag,confidence:Math.min(Math.max(confidence,0),1),status:"established",confirmed_by:[],retrieval_outcomes:{applied_count:0,succeeded_after_count:0,failed_after_count:0},schema_version:KNOWLEDGE_SCHEMA_VERSION,created_at:legacyEntry.created_at||new Date().toISOString(),updated_at:legacyEntry.updated_at||new Date().toISOString(),source_project:"legacy-promotion",encounter_score:1};try{await _internals113.appendKnowledge(canonicalHivePath,newHiveEntry),existingHiveEntries.push(newHiveEntry),migrated++}catch(appendError){let errorMsg=`Failed to append entry: ${appendError instanceof Error?appendError.message:String(appendError)}`;entryErrors.push(errorMsg),warn(`[knowledge-migrator] ${errorMsg}`),dropped++}}catch(entryError){let errorMsg=`Unexpected error processing legacy entry: ${entryError instanceof Error?entryError.message:String(entryError)}`;entryErrors.push(errorMsg),warn(`[knowledge-migrator] ${errorMsg}`),dropped++}return await _internals113.writeSentinel(sentinelPath,migrated,dropped),log(`[knowledge-migrator] Migrated ${migrated} legacy hive entries, dropped ${dropped}`),{migrated:!0,entriesMigrated:migrated,entriesDropped:dropped,entriesTotal:legacyEntries.length,...entryErrors.length>0&&{entryErrors}}}function parseContextMd(content){let sections=_internals113.splitIntoSections(content),entries=[],seen=new Set,sectionPatterns=[{pattern:/^#{1,3}\s+lessons?\s+learned/i,sourceSection:"lessons-learned"},{pattern:/^#{1,3}\s+patterns?/i,sourceSection:"patterns"},{pattern:/^#{1,3}\s+sme\s+cache/i,sourceSection:"sme-cache"},{pattern:/^#{1,3}\s+decisions?/i,sourceSection:"decisions"}];for(let section of sections){let match=sectionPatterns.find((sp)=>sp.pattern.test(section.heading));if(!match)continue;let bullets=_internals113.extractBullets(section.body);for(let bullet of bullets){if(bullet.length<15)continue;let normalized=normalize5(bullet);if(seen.has(normalized))continue;seen.add(normalized),entries.push({text:_internals113.truncateLesson(bullet),sourceSection:match.sourceSection,categoryHint:_internals113.inferCategoryFromText(bullet)})}}return entries}function splitIntoSections(content){let sections=[],headingRegex=/^(#{1,3})\s+(.+)/gm,matches=[],match=headingRegex.exec(content);while(match!==null)matches.push({index:match.index,heading:match[0]}),match=headingRegex.exec(content);for(let i=0;i<matches.length;i++){let current=matches[i],next=matches[i+1],bodyStart=current.index+current.heading.length,bodyEnd=next?next.index:content.length,body=content.slice(bodyStart,bodyEnd).trim();sections.push({heading:current.heading,body})}return sections}function extractBullets(body){let bullets=[],bulletRegex=/^\s*[-*]\s+(.+)/;for(let line of body.split(`
2042
- `)){let match=line.match(bulletRegex);if(match)bullets.push(match[1].trim())}return bullets}function inferCategoryFromText(text){let lower=text.toLowerCase();if(/\b(?:test|spec|vitest|jest)\b/.test(lower))return"testing";if(/\b(?:security|auth|token|password|encrypt)\b/.test(lower))return"security";if(/\b(?:performance|latency|cache|throughput)\b/.test(lower))return"performance";if(/\b(?:architecture|design|pattern|structure)\b/.test(lower))return"architecture";if(/\b(?:debug|error|fix|bug|issue)\b/.test(lower))return"debugging";if(/\b(?:tool|config|setup|install|build)\b/.test(lower))return"tooling";if(/\b(?:integrate|api|hook|connect)\b/.test(lower))return"integration";if(/\b(?:process|workflow|step|approach)\b/.test(lower))return"process";return"other"}function truncateLesson2(text){if(text.length<=280)return text;return`${text.slice(0,277)}...`}function inferProjectName(directory){let packageJsonPath=path143.join(directory,"package.json");if(existsSync72(packageJsonPath))try{let pkg=JSON.parse(readFileSync54(packageJsonPath,"utf-8"));if(pkg.name&&typeof pkg.name==="string")return pkg.name}catch{}return path143.basename(directory)}async function writeSentinel(sentinelPath,migrated,dropped){let sentinel={migrated_at:new Date().toISOString(),source_version:"6.16",target_version:"6.17",entries_migrated:migrated,entries_dropped:dropped,schema_version:1,migration_tool:"knowledge-migrator.ts"};await _internals113.mkdir(path143.dirname(sentinelPath),{recursive:!0}),await _internals113.writeFile(sentinelPath,JSON.stringify(sentinel,null,2),"utf-8")}function resolveLegacyHiveKnowledgePath(){let platform=process.platform,home=process.env.HOME||os23.homedir(),dataDir;if(platform==="win32")dataDir=path143.join(process.env.LOCALAPPDATA||path143.join(home,"AppData","Local"),"opencode-swarm","Data");else if(platform==="darwin")dataDir=path143.join(home,"Library","Application Support","opencode-swarm");else dataDir=path143.join(process.env.XDG_DATA_HOME||path143.join(home,".local","share"),"opencode-swarm");return path143.join(dataDir,"hive-knowledge.jsonl")}var _internals113;var init_knowledge_migrator=__esm(()=>{init_logger();init_knowledge_store();init_knowledge_types();init_knowledge_validator();_internals113={appendKnowledge,migrateContextToKnowledge,migrateKnowledgeToExternal,migrateHiveKnowledgeLegacy,parseContextMd,splitIntoSections,extractBullets,inferCategoryFromText,truncateLesson:truncateLesson2,inferProjectName,writeSentinel,resolveLegacyHiveKnowledgePath,existsSync:existsSync72,readFileSync:readFileSync54,readFile:readFile38,mkdir:mkdir34,writeFile:writeFile22}});import{join as join110}from"node:path";function resolveEntryByPrefix(entries,inputId){let exact=entries.find((e)=>e.id===inputId);if(exact)return{entry:exact};let matches=entries.filter((e)=>e.id.startsWith(inputId));if(matches.length===0)return{error:`No entry found matching '${inputId}'.`};if(matches.length===1)return{entry:matches[0]};let candidates=matches.map((e)=>e.id).join(`
2040
+ `);_internals112={writeFileSync:fs73.writeFileSync,mkdirSync:fs73.mkdirSync,renameSync:fs73.renameSync,unlinkSync:fs73.unlinkSync,readFileSync:fs73.readFileSync,existsSync:fs73.existsSync}});import{randomUUID as randomUUID20}from"node:crypto";import{existsSync as existsSync73,readFileSync as readFileSync54}from"node:fs";import{mkdir as mkdir34,readFile as readFile38,writeFile as writeFile22}from"node:fs/promises";import*as os23 from"node:os";import*as path143 from"node:path";async function migrateKnowledgeToExternal(_directory,_config){let externalSentinelPath=path143.join(_directory,".swarm",".knowledge-external-migrated"),contextPath=path143.join(_directory,".swarm","context.md");if(_internals113.existsSync(externalSentinelPath))return{migrated:!1,entriesMigrated:0,entriesDropped:0,entriesTotal:0,skippedReason:"external-sentinel-exists"};if(!_internals113.existsSync(contextPath))return{migrated:!1,entriesMigrated:0,entriesDropped:0,entriesTotal:0,skippedReason:"no-context-file"};let contextContent=await _internals113.readFile(contextPath,"utf-8");if(contextContent.trim().length===0)return{migrated:!1,entriesMigrated:0,entriesDropped:0,entriesTotal:0,skippedReason:"empty-context"};let lines=contextContent.split(`
2041
+ `),entriesCount=0;for(let line of lines)if(line.trimStart().startsWith("- "))entriesCount++;return await _internals113.writeSentinel(externalSentinelPath,entriesCount,entriesCount),{migrated:!0,entriesMigrated:entriesCount,entriesDropped:0,entriesTotal:entriesCount}}async function migrateContextToKnowledge(directory,config3){let sentinelPath=path143.join(directory,".swarm",".knowledge-migrated"),contextPath=path143.join(directory,".swarm","context.md"),knowledgePath=resolveSwarmKnowledgePath(directory);if(existsSync73(sentinelPath))return{migrated:!1,entriesMigrated:0,entriesDropped:0,entriesTotal:0,skippedReason:"sentinel-exists"};if(!existsSync73(contextPath))return{migrated:!1,entriesMigrated:0,entriesDropped:0,entriesTotal:0,skippedReason:"no-context-file"};let contextContent=await readFile38(contextPath,"utf-8");if(contextContent.trim().length===0)return{migrated:!1,entriesMigrated:0,entriesDropped:0,entriesTotal:0,skippedReason:"empty-context"};let rawEntries=_internals113.parseContextMd(contextContent);if(rawEntries.length===0)return await _internals113.writeSentinel(sentinelPath,0,0),{migrated:!0,entriesMigrated:0,entriesDropped:0,entriesTotal:0};let existing=await readKnowledge(knowledgePath),migrated=0,dropped=0,projectName=_internals113.inferProjectName(directory);for(let raw of rawEntries){if(config3.validation_enabled!==!1){let category=raw.categoryHint??_internals113.inferCategoryFromText(raw.text);if(!validateLesson(raw.text,existing.map((e)=>e.lesson),{category,scope:"global",confidence:0.3}).valid){dropped++;continue}}if(findNearDuplicate(raw.text,existing,config3.dedup_threshold??0.6)){dropped++;continue}let inferredTags=inferTags(raw.text),entry={id:randomUUID20(),tier:"swarm",lesson:_internals113.truncateLesson(raw.text),category:raw.categoryHint??_internals113.inferCategoryFromText(raw.text),tags:[...inferredTags,`migration:${raw.sourceSection}`],scope:"global",confidence:0.3,status:"candidate",confirmed_by:[],retrieval_outcomes:{applied_count:0,succeeded_after_count:0,failed_after_count:0},schema_version:config3.schema_version??KNOWLEDGE_SCHEMA_VERSION,created_at:new Date().toISOString(),updated_at:new Date().toISOString(),project_name:projectName,auto_generated:!0};existing.push(entry),migrated++}if(migrated>0)await rewriteKnowledge(knowledgePath,existing);return await _internals113.writeSentinel(sentinelPath,migrated,dropped),log(`[knowledge-migrator] Migrated ${migrated} entries, dropped ${dropped}`),{migrated:!0,entriesMigrated:migrated,entriesDropped:dropped,entriesTotal:rawEntries.length}}async function migrateHiveKnowledgeLegacy(config3){let legacyHivePath=_internals113.resolveLegacyHiveKnowledgePath(),canonicalHivePath=resolveHiveKnowledgePath2(),sentinelPath=path143.join(path143.dirname(canonicalHivePath),".hive-knowledge-migrated");if(existsSync73(sentinelPath))return{migrated:!1,entriesMigrated:0,entriesDropped:0,entriesTotal:0,skippedReason:"sentinel-exists"};if(!existsSync73(legacyHivePath))return{migrated:!1,entriesMigrated:0,entriesDropped:0,entriesTotal:0,skippedReason:"no-context-file"};let legacyEntries=await readKnowledge(legacyHivePath);if(legacyEntries.length===0)return await _internals113.writeSentinel(sentinelPath,0,0),{migrated:!0,entriesMigrated:0,entriesDropped:0,entriesTotal:0};let existingHiveEntries=await readKnowledge(canonicalHivePath),migrated=0,dropped=0,entryErrors=[];for(let legacyEntry of legacyEntries)try{let lesson=legacyEntry.lesson;if(!lesson||typeof lesson!=="string"||lesson.length<15){dropped++;continue}if(findNearDuplicate(lesson,existingHiveEntries,config3.dedup_threshold??0.6)){dropped++;continue}let category=legacyEntry.category||"process",validationResult=validateLesson(lesson,existingHiveEntries.map((e)=>e.lesson),{category,scope:"global",confidence:0.3});if(!validationResult.valid){let errorMsg=`Validation failed for legacy entry: ${validationResult.reason}`;entryErrors.push(errorMsg),warn(`[knowledge-migrator] ${errorMsg}`),dropped++;continue}let confidence=legacyEntry.confidence??0.8,scopeTag=legacyEntry.scope_tag||"global",legacyId=legacyEntry.id,existingIds=new Set(existingHiveEntries.map((e)=>e.id)),resolvedId=legacyId&&existingIds.has(legacyId)?randomUUID20():legacyId||randomUUID20();if(legacyId&&existingIds.has(legacyId))warn(`[knowledge-migrator] Legacy entry ID collision for "${legacyId}", generating new UUID`);let newHiveEntry={id:resolvedId,tier:"hive",lesson:_internals113.truncateLesson(lesson),category,tags:["migration:legacy-hive"],scope:scopeTag,confidence:Math.min(Math.max(confidence,0),1),status:"established",confirmed_by:[],retrieval_outcomes:{applied_count:0,succeeded_after_count:0,failed_after_count:0},schema_version:KNOWLEDGE_SCHEMA_VERSION,created_at:legacyEntry.created_at||new Date().toISOString(),updated_at:legacyEntry.updated_at||new Date().toISOString(),source_project:"legacy-promotion",encounter_score:1};try{await _internals113.appendKnowledge(canonicalHivePath,newHiveEntry),existingHiveEntries.push(newHiveEntry),migrated++}catch(appendError){let errorMsg=`Failed to append entry: ${appendError instanceof Error?appendError.message:String(appendError)}`;entryErrors.push(errorMsg),warn(`[knowledge-migrator] ${errorMsg}`),dropped++}}catch(entryError){let errorMsg=`Unexpected error processing legacy entry: ${entryError instanceof Error?entryError.message:String(entryError)}`;entryErrors.push(errorMsg),warn(`[knowledge-migrator] ${errorMsg}`),dropped++}return await _internals113.writeSentinel(sentinelPath,migrated,dropped),log(`[knowledge-migrator] Migrated ${migrated} legacy hive entries, dropped ${dropped}`),{migrated:!0,entriesMigrated:migrated,entriesDropped:dropped,entriesTotal:legacyEntries.length,...entryErrors.length>0&&{entryErrors}}}function parseContextMd(content){let sections=_internals113.splitIntoSections(content),entries=[],seen=new Set,sectionPatterns=[{pattern:/^#{1,3}\s+lessons?\s+learned/i,sourceSection:"lessons-learned"},{pattern:/^#{1,3}\s+patterns?/i,sourceSection:"patterns"},{pattern:/^#{1,3}\s+sme\s+cache/i,sourceSection:"sme-cache"},{pattern:/^#{1,3}\s+decisions?/i,sourceSection:"decisions"}];for(let section of sections){let match=sectionPatterns.find((sp)=>sp.pattern.test(section.heading));if(!match)continue;let bullets=_internals113.extractBullets(section.body);for(let bullet of bullets){if(bullet.length<15)continue;let normalized=normalize5(bullet);if(seen.has(normalized))continue;seen.add(normalized),entries.push({text:_internals113.truncateLesson(bullet),sourceSection:match.sourceSection,categoryHint:_internals113.inferCategoryFromText(bullet)})}}return entries}function splitIntoSections(content){let sections=[],headingRegex=/^(#{1,3})\s+(.+)/gm,matches=[],match=headingRegex.exec(content);while(match!==null)matches.push({index:match.index,heading:match[0]}),match=headingRegex.exec(content);for(let i=0;i<matches.length;i++){let current=matches[i],next=matches[i+1],bodyStart=current.index+current.heading.length,bodyEnd=next?next.index:content.length,body=content.slice(bodyStart,bodyEnd).trim();sections.push({heading:current.heading,body})}return sections}function extractBullets(body){let bullets=[],bulletRegex=/^\s*[-*]\s+(.+)/;for(let line of body.split(`
2042
+ `)){let match=line.match(bulletRegex);if(match)bullets.push(match[1].trim())}return bullets}function inferCategoryFromText(text){let lower=text.toLowerCase();if(/\b(?:test|spec|vitest|jest)\b/.test(lower))return"testing";if(/\b(?:security|auth|token|password|encrypt)\b/.test(lower))return"security";if(/\b(?:performance|latency|cache|throughput)\b/.test(lower))return"performance";if(/\b(?:architecture|design|pattern|structure)\b/.test(lower))return"architecture";if(/\b(?:debug|error|fix|bug|issue)\b/.test(lower))return"debugging";if(/\b(?:tool|config|setup|install|build)\b/.test(lower))return"tooling";if(/\b(?:integrate|api|hook|connect)\b/.test(lower))return"integration";if(/\b(?:process|workflow|step|approach)\b/.test(lower))return"process";return"other"}function truncateLesson2(text){if(text.length<=280)return text;return`${text.slice(0,277)}...`}function inferProjectName(directory){let packageJsonPath=path143.join(directory,"package.json");if(existsSync73(packageJsonPath))try{let pkg=JSON.parse(readFileSync54(packageJsonPath,"utf-8"));if(pkg.name&&typeof pkg.name==="string")return pkg.name}catch{}return path143.basename(directory)}async function writeSentinel(sentinelPath,migrated,dropped){let sentinel={migrated_at:new Date().toISOString(),source_version:"6.16",target_version:"6.17",entries_migrated:migrated,entries_dropped:dropped,schema_version:1,migration_tool:"knowledge-migrator.ts"};await _internals113.mkdir(path143.dirname(sentinelPath),{recursive:!0}),await _internals113.writeFile(sentinelPath,JSON.stringify(sentinel,null,2),"utf-8")}function resolveLegacyHiveKnowledgePath(){let platform=process.platform,home=process.env.HOME||os23.homedir(),dataDir;if(platform==="win32")dataDir=path143.join(process.env.LOCALAPPDATA||path143.join(home,"AppData","Local"),"opencode-swarm","Data");else if(platform==="darwin")dataDir=path143.join(home,"Library","Application Support","opencode-swarm");else dataDir=path143.join(process.env.XDG_DATA_HOME||path143.join(home,".local","share"),"opencode-swarm");return path143.join(dataDir,"hive-knowledge.jsonl")}var _internals113;var init_knowledge_migrator=__esm(()=>{init_logger();init_knowledge_store();init_knowledge_types();init_knowledge_validator();_internals113={appendKnowledge,migrateContextToKnowledge,migrateKnowledgeToExternal,migrateHiveKnowledgeLegacy,parseContextMd,splitIntoSections,extractBullets,inferCategoryFromText,truncateLesson:truncateLesson2,inferProjectName,writeSentinel,resolveLegacyHiveKnowledgePath,existsSync:existsSync73,readFileSync:readFileSync54,readFile:readFile38,mkdir:mkdir34,writeFile:writeFile22}});import{join as join110}from"node:path";function resolveEntryByPrefix(entries,inputId){let exact=entries.find((e)=>e.id===inputId);if(exact)return{entry:exact};let matches=entries.filter((e)=>e.id.startsWith(inputId));if(matches.length===0)return{error:`No entry found matching '${inputId}'.`};if(matches.length===1)return{entry:matches[0]};let candidates=matches.map((e)=>e.id).join(`
2043
2043
  `);return{error:`Ambiguous prefix '${inputId}' matches ${matches.length} entries:
2044
2044
  ${candidates}`}}async function authorizeUserCuration(directory,entry,action,reason){let{config:loadedConfig}=loadPluginConfigWithMeta(directory),config3=KnowledgeConfigSchema.parse(loadedConfig.knowledge??{}),input={directory,action,entryId:entry.id,reason,evidenceScope:"local-session",actorRole:"user"},context={config:config3,entry},decision=await authorizeCuration(input,context);if(!decision.authorized)return{ok:!1,detail:decision.detail};return{ok:!0,curationContext:{input,context}}}async function handleKnowledgeQuarantineCommand(directory,args2){let inputId=args2[0];if(!inputId)return"Usage: /swarm knowledge quarantine <id> [reason]";if(!/^[a-zA-Z0-9_-]{1,64}$/.test(inputId))return"Invalid entry ID. IDs must be 1-64 characters: letters, digits, hyphens, underscores only.";let reason=args2.slice(1).join(" ")||"Quarantined via /swarm knowledge quarantine command";try{let entries=await readKnowledge(resolveSwarmKnowledgePath(directory)),resolved=resolveEntryByPrefix(entries,inputId);if("error"in resolved)return`❌ ${resolved.error}`;let fullId=resolved.entry.id,auth=await authorizeUserCuration(directory,resolved.entry,"quarantine",reason);if(!auth.ok)return`\uD83D\uDEAB Quarantine of ${fullId} blocked by cohort-safety policy: ${auth.detail}`;return await quarantineEntry(directory,fullId,reason,"user",auth.curationContext),`✅ Entry ${fullId} quarantined successfully.`}catch(error93){return log("[knowledge-command] quarantineEntry error:",error93 instanceof Error?error93.message:String(error93)),"❌ Failed to quarantine entry. Check the entry ID and try again."}}async function handleKnowledgeRestoreCommand(directory,args2){let inputId=args2[0];if(!inputId)return"Usage: /swarm knowledge restore <id>";if(!/^[a-zA-Z0-9_-]{1,64}$/.test(inputId))return"Invalid entry ID. IDs must be 1-64 characters: letters, digits, hyphens, underscores only.";try{let swarmEntries=await readKnowledge(resolveSwarmKnowledgePath(directory)),swarmResolved=resolveEntryByPrefix(swarmEntries,inputId);if("entry"in swarmResolved&&swarmResolved.entry.status==="archived"){let fullId2=swarmResolved.entry.id,auth2=await authorizeUserCuration(directory,swarmResolved.entry,"unarchive",void 0);if(!auth2.ok)return`\uD83D\uDEAB Unarchive of ${fullId2} blocked by cohort-safety policy: ${auth2.detail}`;let result=await unarchiveEntry(directory,fullId2,auth2.curationContext);if(result.restored)return`✅ Archived entry ${fullId2} restored to '${result.restored_to}'.`;return`❌ Entry ${fullId2} could not be unarchived${result.reason?` (${result.reason})`:""}.`}let quarantinePath=join110(resolveKnowledgeStoreDir(directory),"knowledge-quarantined.jsonl"),entries=await readKnowledge(quarantinePath),resolved=resolveEntryByPrefix(entries,inputId);if("error"in resolved){if("entry"in swarmResolved)return`❌ Entry ${swarmResolved.entry.id} is neither archived nor quarantined (status: '${swarmResolved.entry.status}'). Only archived or quarantined entries can be restored.`;return`❌ ${resolved.error}`}let fullId=resolved.entry.id,auth=await authorizeUserCuration(directory,resolved.entry,"restore",void 0);if(!auth.ok)return`\uD83D\uDEAB Restore of ${fullId} blocked by cohort-safety policy: ${auth.detail}`;return await restoreEntry(directory,fullId,auth.curationContext),`✅ Entry ${fullId} restored successfully.`}catch(error93){return log("[knowledge-command] restoreEntry error:",error93 instanceof Error?error93.message:String(error93)),"❌ Failed to restore entry. Check the entry ID and try again."}}async function handleKnowledgeMigrateCommand(directory,args2){let targetDir=args2[0]||directory,config3=KnowledgeConfigSchema.parse({});try{let contextResult=await migrateContextToKnowledge(targetDir,config3),hiveResult=await migrateHiveKnowledgeLegacy(config3),messages=[];if(contextResult.skippedReason)switch(contextResult.skippedReason){case"sentinel-exists":messages.push("⏭ Context migration already completed. Delete .swarm/.knowledge-migrated to re-run.");break;case"no-context-file":messages.push("ℹ️ No .swarm/context.md found — nothing to migrate.");break;case"empty-context":messages.push("ℹ️ .swarm/context.md is empty — nothing to migrate.");break}else messages.push(`✅ Context migration: ${contextResult.entriesMigrated} entries added, ${contextResult.entriesDropped} dropped`);if(hiveResult.skippedReason)switch(hiveResult.skippedReason){case"sentinel-exists":messages.push("⏭ Hive legacy migration already completed. Delete the sentinel in the hive data dir to re-run.");break;case"no-context-file":messages.push("ℹ️ No legacy hive-knowledge.jsonl found — nothing to migrate.");break}else if(hiveResult.migrated)messages.push(`✅ Hive legacy migration: ${hiveResult.entriesMigrated} entries added, ${hiveResult.entriesDropped} dropped`);return messages.join(`
2045
2045
  `)}catch(error93){return log("[knowledge-command] migration error:",error93 instanceof Error?error93.message:String(error93)),"❌ Migration failed. Check that knowledge source files are readable."}}async function handleKnowledgeListCommand(directory,_args){try{let knowledgePath=resolveSwarmKnowledgePath(directory),entries=await readKnowledge(knowledgePath);if(entries.length===0)return"ℹ️ No knowledge entries found in .swarm/knowledge.jsonl";let lines=[`## Knowledge Entries (${entries.length} total)`,"","| ID (prefix) | Category | Confidence | Lesson (truncated) |","|--------------|----------|------------|---------------------|"];for(let entry of entries){let truncatedLesson=entry.lesson.length>60?`${entry.lesson.slice(0,57)}...`:entry.lesson,confidencePct=Math.round(entry.confidence*100);lines.push(`| ${entry.id.slice(0,12)}… | ${entry.category} | ${confidencePct}% | ${truncatedLesson} |`)}return lines.push(""),lines.push("Use `/swarm knowledge quarantine <id-prefix>` to hide an entry. Prefix matching is supported — the 12-character prefix shown is unique in most stores."),lines.join(`
@@ -2049,8 +2049,8 @@ ${USAGE7}`}let flags=[];if(parsed.plan)flags.push("plan=true");if(parsed.trace)f
2049
2049
  ${JSON.stringify(formatLearningJSON(metrics),null,2)}
2050
2050
  [/LEARNING_JSON]`;return formatLearningMarkdown(metrics)}catch(err){if(err instanceof LearningMetricsTimeoutError){if(args2.includes("--json"))return`[LEARNING_JSON]
2051
2051
  ${JSON.stringify({ok:!1,error:{code:"LEARNING_METRICS_TIMEOUT",timeout_ms:err.timeoutMs,message:timeoutMessage(err.timeoutMs)}},null,2)}
2052
- [/LEARNING_JSON]`;return timeoutMessage(err.timeoutMs)}return`Error computing learning metrics: ${err instanceof Error?err.message:String(err)}. Run /swarm diagnose to check .swarm/ health.`}}var DEFAULT_LEARNING_TIMEOUT_MS=30000,MAX_LEARNING_TIMEOUT_MS=300000,LearningMetricsTimeoutError,_internals114;var init_learning=__esm(()=>{init_learning_metrics();LearningMetricsTimeoutError=class LearningMetricsTimeoutError extends Error{timeoutMs;constructor(timeoutMs){super(`Learning metrics timed out after ${timeoutMs}ms`);this.timeoutMs=timeoutMs;this.name="LearningMetricsTimeoutError"}};_internals114={computeLearningMetrics}});function reqStr(o,field){let v=o[field];return typeof v==="string"&&v.length>0?v:null}function rewriteHistoryKey(line){if(!line||typeof line!=="object")return null;let o=line,entryId=reqStr(o,"entry_id"),timestamp=reqStr(o,"timestamp"),afterRevision=o.after_revision;if(entryId===null||timestamp===null)return null;if(typeof afterRevision!=="number"||!Number.isFinite(afterRevision))return null;return`${entryId}|${afterRevision}|${timestamp}`}function curationProposalKey(line){if(!line||typeof line!=="object")return null;let o=line,entryId=reqStr(o,"entryId"),action=reqStr(o,"action"),proposedAt=reqStr(o,"proposedAt");if(entryId===null||action===null||proposedAt===null)return null;return`${entryId}|${action}|${proposedAt}`}var KNOWLEDGE_FAMILY,FAMILY_FILENAMES;var init_family_manifest=__esm(()=>{KNOWLEDGE_FAMILY=[{filename:"knowledge.jsonl",role:"store",mergeStrategy:"dedup-id-merge",reversible:!0},{filename:"knowledge-events.jsonl",role:"events",mergeStrategy:"append-union",reversible:!0},{filename:"knowledge-rejected.jsonl",role:"rejected",mergeStrategy:"append-union",reversible:!0},{filename:"knowledge-retractions.jsonl",role:"retractions",mergeStrategy:"append-union",reversible:!0},{filename:"knowledge-counter-baseline.json",role:"counters",mergeStrategy:"sum-counters",reversible:!0},{filename:"knowledge-quarantined.jsonl",role:"quarantine",mergeStrategy:"append-union",reversible:!0},{filename:"knowledge-unactionable.jsonl",role:"unactionable",mergeStrategy:"append-union",reversible:!0},{filename:"knowledge-application.jsonl",role:"application-legacy",mergeStrategy:"append-union",reversible:!0},{filename:"knowledge-rewrites.jsonl",role:"rewrite-history",mergeStrategy:"append-concat",reversible:!0,keyOf:rewriteHistoryKey},{filename:"curation-proposals.jsonl",role:"curation-proposals",mergeStrategy:"append-concat",reversible:!0,keyOf:curationProposalKey}],FAMILY_FILENAMES=KNOWLEDGE_FAMILY.map((m)=>m.filename)});var MIGRATION_LOCK_STALE_MS=30000,MIGRATION_LOCK_RETRIES;var init_family_migration_shared=__esm(()=>{MIGRATION_LOCK_RETRIES={retries:{retries:10,minTimeout:100,maxTimeout:500}}});import{existsSync as existsSync73,readFileSync as readFileSync55}from"node:fs";import{mkdir as mkdir35}from"node:fs/promises";import*as path144 from"node:path";function readJsonl2(filePath){if(!existsSync73(filePath))return[];try{let content=readFileSync55(filePath,"utf-8"),out=[];for(let line of content.split(`
2053
- `)){let trimmed=line.trim();if(!trimmed)continue;try{out.push(JSON.parse(trimmed))}catch{}}return out}catch{return[]}}function readJson(filePath){if(!existsSync73(filePath))return null;try{return JSON.parse(readFileSync55(filePath,"utf-8"))}catch{return null}}function lineId(obj){if(!obj||typeof obj!=="object")return null;let o=obj;if(typeof o.id==="string"&&o.id.length>0)return o.id;return null}function keySelectorFor(member){return member.keyOf??lineId}function mergeStoreEntries(destination,source){let result=[...destination],seenIds=new Set(result.map((e)=>e.id)),added=0,skipped=0;for(let src of source){if(seenIds.has(src.id)){skipped++;continue}let dup=findNearDuplicate(src.lesson,result,DEDUP_THRESHOLD);if(dup){mergeEntryFields(dup,src),skipped++;continue}result.push(src),seenIds.add(src.id),added++}return{merged:result,added,skipped}}function appendUnionById(destination,source,keyOf3=lineId){let result=[...destination],seen=new Set(result.map(keyOf3).filter((x)=>x!==null)),added=0,skipped=0;for(let src of source){let id=keyOf3(src);if(!id||seen.has(id)){skipped++;continue}result.push(src),seen.add(id),added++}return{merged:result,added,skipped}}function sumCounters(destination,source){let result={...destination},added=0,skipped=0;for(let[id,srcRollup]of Object.entries(source)){let existing=result[id];if(existing){let merged={...existing,violation_timestamps:[...existing.violation_timestamps]};_internals36.mergeRollupInto(merged,srcRollup),result[id]=merged,skipped++}else result[id]=srcRollup,added++}return{merged:result,added,skipped}}function serialize2(member,data){if(member.mergeStrategy==="sum-counters")return`${JSON.stringify(data)}
2052
+ [/LEARNING_JSON]`;return timeoutMessage(err.timeoutMs)}return`Error computing learning metrics: ${err instanceof Error?err.message:String(err)}. Run /swarm diagnose to check .swarm/ health.`}}var DEFAULT_LEARNING_TIMEOUT_MS=30000,MAX_LEARNING_TIMEOUT_MS=300000,LearningMetricsTimeoutError,_internals114;var init_learning=__esm(()=>{init_learning_metrics();LearningMetricsTimeoutError=class LearningMetricsTimeoutError extends Error{timeoutMs;constructor(timeoutMs){super(`Learning metrics timed out after ${timeoutMs}ms`);this.timeoutMs=timeoutMs;this.name="LearningMetricsTimeoutError"}};_internals114={computeLearningMetrics}});function reqStr(o,field){let v=o[field];return typeof v==="string"&&v.length>0?v:null}function rewriteHistoryKey(line){if(!line||typeof line!=="object")return null;let o=line,entryId=reqStr(o,"entry_id"),timestamp=reqStr(o,"timestamp"),afterRevision=o.after_revision;if(entryId===null||timestamp===null)return null;if(typeof afterRevision!=="number"||!Number.isFinite(afterRevision))return null;return`${entryId}|${afterRevision}|${timestamp}`}function curationProposalKey(line){if(!line||typeof line!=="object")return null;let o=line,entryId=reqStr(o,"entryId"),action=reqStr(o,"action"),proposedAt=reqStr(o,"proposedAt");if(entryId===null||action===null||proposedAt===null)return null;return`${entryId}|${action}|${proposedAt}`}var KNOWLEDGE_FAMILY,FAMILY_FILENAMES;var init_family_manifest=__esm(()=>{KNOWLEDGE_FAMILY=[{filename:"knowledge.jsonl",role:"store",mergeStrategy:"dedup-id-merge",reversible:!0},{filename:"knowledge-events.jsonl",role:"events",mergeStrategy:"append-union",reversible:!0},{filename:"knowledge-rejected.jsonl",role:"rejected",mergeStrategy:"append-union",reversible:!0},{filename:"knowledge-retractions.jsonl",role:"retractions",mergeStrategy:"append-union",reversible:!0},{filename:"knowledge-counter-baseline.json",role:"counters",mergeStrategy:"sum-counters",reversible:!0},{filename:"knowledge-quarantined.jsonl",role:"quarantine",mergeStrategy:"append-union",reversible:!0},{filename:"knowledge-unactionable.jsonl",role:"unactionable",mergeStrategy:"append-union",reversible:!0},{filename:"knowledge-application.jsonl",role:"application-legacy",mergeStrategy:"append-union",reversible:!0},{filename:"knowledge-rewrites.jsonl",role:"rewrite-history",mergeStrategy:"append-concat",reversible:!0,keyOf:rewriteHistoryKey},{filename:"curation-proposals.jsonl",role:"curation-proposals",mergeStrategy:"append-concat",reversible:!0,keyOf:curationProposalKey}],FAMILY_FILENAMES=KNOWLEDGE_FAMILY.map((m)=>m.filename)});var MIGRATION_LOCK_STALE_MS=30000,MIGRATION_LOCK_RETRIES;var init_family_migration_shared=__esm(()=>{MIGRATION_LOCK_RETRIES={retries:{retries:10,minTimeout:100,maxTimeout:500}}});import{existsSync as existsSync74,readFileSync as readFileSync55}from"node:fs";import{mkdir as mkdir35}from"node:fs/promises";import*as path144 from"node:path";function readJsonl2(filePath){if(!existsSync74(filePath))return[];try{let content=readFileSync55(filePath,"utf-8"),out=[];for(let line of content.split(`
2053
+ `)){let trimmed=line.trim();if(!trimmed)continue;try{out.push(JSON.parse(trimmed))}catch{}}return out}catch{return[]}}function readJson(filePath){if(!existsSync74(filePath))return null;try{return JSON.parse(readFileSync55(filePath,"utf-8"))}catch{return null}}function lineId(obj){if(!obj||typeof obj!=="object")return null;let o=obj;if(typeof o.id==="string"&&o.id.length>0)return o.id;return null}function keySelectorFor(member){return member.keyOf??lineId}function mergeStoreEntries(destination,source){let result=[...destination],seenIds=new Set(result.map((e)=>e.id)),added=0,skipped=0;for(let src of source){if(seenIds.has(src.id)){skipped++;continue}let dup=findNearDuplicate(src.lesson,result,DEDUP_THRESHOLD);if(dup){mergeEntryFields(dup,src),skipped++;continue}result.push(src),seenIds.add(src.id),added++}return{merged:result,added,skipped}}function appendUnionById(destination,source,keyOf3=lineId){let result=[...destination],seen=new Set(result.map(keyOf3).filter((x)=>x!==null)),added=0,skipped=0;for(let src of source){let id=keyOf3(src);if(!id||seen.has(id)){skipped++;continue}result.push(src),seen.add(id),added++}return{merged:result,added,skipped}}function sumCounters(destination,source){let result={...destination},added=0,skipped=0;for(let[id,srcRollup]of Object.entries(source)){let existing=result[id];if(existing){let merged={...existing,violation_timestamps:[...existing.violation_timestamps]};_internals36.mergeRollupInto(merged,srcRollup),result[id]=merged,skipped++}else result[id]=srcRollup,added++}return{merged:result,added,skipped}}function serialize2(member,data){if(member.mergeStrategy==="sum-counters")return`${JSON.stringify(data)}
2054
2054
  `;let arr=data;if(arr.length===0)return"";return`${arr.map((e)=>JSON.stringify(e)).join(`
2055
2055
  `)}
2056
2056
  `}function validateSerialized(member,serialized2){if(member.mergeStrategy==="sum-counters")try{let obj=JSON.parse(serialized2);if(!obj||typeof obj!=="object"||Array.isArray(obj))return!1;return!0}catch{return!1}let keyOf3=keySelectorFor(member);for(let line of serialized2.split(`
@@ -2086,10 +2086,10 @@ Flags:
2086
2086
  `,"utf-8")}catch{}}function parseTaskToolInput(input){let record3=input,rawTool=typeof record3.tool==="string"?record3.tool:void 0,toolName=rawTool?normalizeToolName(rawTool)??rawTool:void 0;if(toolName!=="Task"&&toolName!=="task")return null;if(!record3.args||typeof record3.args!=="object")return null;let args2=record3.args,prompt=args2.prompt;if(typeof prompt!=="string"||prompt.trim().length===0)return null;let target=typeof args2.subagent_type==="string"?args2.subagent_type:typeof args2.agent==="string"?args2.agent:typeof record3.agent==="string"?record3.agent:"architect";return{sessionID:typeof record3.sessionID==="string"?record3.sessionID:void 0,agentRole:stripKnownSwarmPrefix(target),prompt}}function isCuratorAgent(agentRole){return agentRole==="curator"||agentRole==="curator_init"||agentRole==="curator_phase"||agentRole==="curator_postmortem"}function messagesContainRecall(messages){return messages.some((message)=>message?.parts?.some((part)=>typeof part?.text==="string"&&(part.text.includes(MEMORY_SENTINEL)||part.text.includes("Retrieved Swarm Memory"))))}function getSessionID(input,messages){let inputSession=input?.sessionID;if(typeof inputSession==="string")return inputSession;for(let message of messages){let sessionID=message?.info?.sessionID;if(typeof sessionID==="string")return sessionID}return}function resolveMessageAgent(messages,options,sessionID){let configured=options.getActiveAgentName?.(sessionID);if(configured)return stripKnownSwarmPrefix(configured);for(let message of messages){let agent=message?.info?.agent;if(typeof agent==="string")return stripKnownSwarmPrefix(agent)}return"architect"}function latestTextForRole(messages,role){for(let i=messages.length-1;i>=0;i--){let message=messages[i];if(message.info?.role!==role||!Array.isArray(message.parts))continue;let text=message.parts.map((part)=>part?.text).filter((partText)=>typeof partText==="string").join(`
2087
2087
  `).trim();if(text)return text}return null}function extractTaskToolPrompt(messages){for(let i=messages.length-1;i>=0;i--){let msg=messages[i];if((msg.role??msg.info?.role)!=="assistant")continue;let content=Array.isArray(msg.content)?msg.content:Array.isArray(msg.parts)?msg.parts:[];for(let j=content.length-1;j>=0;j--){let block=content[j];if(block&&typeof block==="object"){let b=block;if(b.type==="tool_use"&&b.name==="Task"){let prompt=b.input?.prompt;if(typeof prompt==="string"&&prompt.length>0)return prompt}}}}return null}function recallMessageInsertIndex(messages){for(let i=messages.length-1;i>=0;i--)if(messages[i]?.info?.role==="user")return i;return messages.length}function extractTouchedFiles(text){let matches=text.match(/\b(?:src|tests|test|docs|scripts|packages)\/[A-Za-z0-9._/@+-]+/g);return Array.from(new Set(matches??[])).slice(0,20)}function compactText(text){let compacted=text.replace(/\s+/g," ").trim();if(compacted.length<=2000)return compacted;return Array.from(compacted).slice(0,2000).join("")}var MEMORY_SENTINEL,UNITID_PROBE_TASK_ID_PATTERN;var init_injector=__esm(()=>{init_agent_output_schema();init_schema();init_normalize_tool_name();init_utils2();init_config2();init_gateway();init_recall_planner();init_run_log();MEMORY_SENTINEL=MEMORY_RECALL_SENTINEL;UNITID_PROBE_TASK_ID_PATTERN=/\bTASK:\s*(\d+(?:\.\d+)+)\b/});var init_memory=__esm(()=>{init_config2();init_errors6();init_evaluation();init_gateway();init_injector();init_jsonl_migration();init_local_jsonl_provider();init_maintenance();init_memory_link();init_prompt_block();init_recall_planner();init_redaction();init_role_profiles();init_run_log();init_schema2();init_sqlite_provider();init_storage_root()});import{appendFile as appendFile20,mkdir as mkdir39,readFile as readFile40}from"node:fs/promises";import*as path149 from"node:path";function resolveLogPath2(target){if(typeof target==="string")return validateSwarmPath(target,LOG_RELATIVE_PATH);if(target.kind==="cohort")return path149.join(target.cohortRoot,LOG_BASENAME);return validateSwarmPath(target.directory,LOG_RELATIVE_PATH)}async function readConsolidationLog(target){let filePath=resolveLogPath2(target),raw;try{raw=await readFile40(filePath,"utf-8")}catch{return[]}let records=[];for(let line of raw.split(`
2088
2088
  `)){let trimmed=line.trim();if(!trimmed)continue;try{records.push(JSON.parse(trimmed))}catch{}}return records}async function appendConsolidationLog(target,record3){let filePath=resolveLogPath2(target);await mkdir39(path149.dirname(filePath),{recursive:!0}),await appendFile20(filePath,`${JSON.stringify(record3)}
2089
- `,"utf-8")}var LOG_RELATIVE_PATH,LOG_BASENAME="consolidation-log.jsonl";var init_consolidation_log=__esm(()=>{init_utils2();LOG_RELATIVE_PATH=path149.join("memory","consolidation-log.jsonl")});import{existsSync as existsSync74}from"node:fs";import*as path150 from"node:path";import{fileURLToPath as fileURLToPath6}from"node:url";async function handleMemoryCommand(_directory,_args){return["## Swarm Memory","","- `/swarm memory status` - show provider, SQLite path, JSONL files, and last migration report","- `/swarm memory pending` - show pending proposals and recent rejection reasons","- `/swarm memory recall-log` - summarize recall usage by agent role and memory ID","- `/swarm memory value-log` - show per-memory learned-utility (q-value) history, recent rewards, and suppression/promotion candidacy","- `/swarm memory stale` - list expired scratch, superseded, deleted, and low-utility memories","- `/swarm memory compact` - dry-run compaction; pass `--confirm` to remove deleted, superseded, and expired scratch records","- `/swarm memory export` - export current memory and proposals to `.swarm/memory/export/*.jsonl`","- `/swarm memory import` - import `.swarm/memory/{memories,proposals}.jsonl` into SQLite","- `/swarm memory migrate` - run the one-time legacy JSONL to SQLite migration","- `/swarm memory evaluate --json` - run the golden recall evaluation fixtures and emit a JSON report","- `/swarm memory consolidation-log [--limit <n>]` - summarize recent episodic→semantic consolidation passes (max 50 per query)","- `/swarm memory link [name]` - share memory across linked worktrees (requires `memory.link.enabled: true`)","- `/swarm memory link status` - show the memory link state (distinct from knowledge link)","- `/swarm memory unlink` - stop sharing memory; copies the cohort family back to local"].join(`
2089
+ `,"utf-8")}var LOG_RELATIVE_PATH,LOG_BASENAME="consolidation-log.jsonl";var init_consolidation_log=__esm(()=>{init_utils2();LOG_RELATIVE_PATH=path149.join("memory","consolidation-log.jsonl")});import{existsSync as existsSync75}from"node:fs";import*as path150 from"node:path";import{fileURLToPath as fileURLToPath6}from"node:url";async function handleMemoryCommand(_directory,_args){return["## Swarm Memory","","- `/swarm memory status` - show provider, SQLite path, JSONL files, and last migration report","- `/swarm memory pending` - show pending proposals and recent rejection reasons","- `/swarm memory recall-log` - summarize recall usage by agent role and memory ID","- `/swarm memory value-log` - show per-memory learned-utility (q-value) history, recent rewards, and suppression/promotion candidacy","- `/swarm memory stale` - list expired scratch, superseded, deleted, and low-utility memories","- `/swarm memory compact` - dry-run compaction; pass `--confirm` to remove deleted, superseded, and expired scratch records","- `/swarm memory export` - export current memory and proposals to `.swarm/memory/export/*.jsonl`","- `/swarm memory import` - import `.swarm/memory/{memories,proposals}.jsonl` into SQLite","- `/swarm memory migrate` - run the one-time legacy JSONL to SQLite migration","- `/swarm memory evaluate --json` - run the golden recall evaluation fixtures and emit a JSON report","- `/swarm memory consolidation-log [--limit <n>]` - summarize recent episodic→semantic consolidation passes (max 50 per query)","- `/swarm memory link [name]` - share memory across linked worktrees (requires `memory.link.enabled: true`)","- `/swarm memory link status` - show the memory link state (distinct from knowledge link)","- `/swarm memory unlink` - stop sharing memory; copies the cohort family back to local"].join(`
2090
2090
  `)}async function handleMemoryConsolidationLogCommand(directory,args2){let parsed=parseMaintenanceArgs(args2,{usage:"Usage: /swarm memory consolidation-log [--limit <n>] (max 50 records per query)",allowConfirm:!1});if("error"in parsed)return parsed.error;let limit=Math.min(parsed.limit,50),loadedMemory=loadPluginConfig(directory).memory,records=await readConsolidationLog(resolveVettedMemoryRoot(directory,resolveMemoryConfig(loadedMemory??DEFAULT_MEMORY_CONFIG))),recent=records.slice(-limit).reverse(),lines=["## Swarm Memory Consolidation Log","",`- Total recorded passes: \`${records.length}\``,`- Showing: \`${recent.length}\``];if(recent.length===0)return lines.push("","No consolidation passes have been recorded yet."),lines.join(`
2091
2091
  `);for(let record3 of recent)lines.push("",`### Phase ${record3.phaseNumber} — ${record3.completedAt}`,`- Run: \`${record3.runId??"unknown"}\``,`- Clusters: \`${record3.clusterCount}\` (deferred \`${record3.clustersDeferred}\`)`,`- Decisions applied: \`${record3.decisionsEmitted}\` (added \`${record3.added}\`, superseded \`${record3.superseded}\`)`,`- Contradictions: \`${record3.contradictionsDetected}\` | Deduped: \`${record3.deduped}\` | Proposed: \`${record3.proposed}\``,`- Memories decayed: \`${record3.memoriesDecayed}\` | Errored: \`${record3.errored}\``,`- Processed proposals: \`${record3.processedProposalIds.length}\``);return lines.join(`
2092
- `)}async function handleMemoryStatusCommand(directory,_args){let config3=resolveCommandMemoryConfig(directory),storageDir=resolveMemoryStorageDir(directory,config3),sqlitePath=resolveSqliteDatabasePath(directory,config3),jsonlFiles=await getLegacyJsonlFileStatus(directory,config3),report=await readMigrationReport(directory,config3),lines=["## Swarm Memory Status","",`- Enabled: \`${config3.enabled}\``,`- Provider: \`${config3.provider}\``,`- Storage: \`${storageDir}\``,`- SQLite path: \`${sqlitePath}\``,`- SQLite database exists: \`${existsSync74(sqlitePath)}\``,"- Automatic destructive cleanup: `disabled`","","### Legacy JSONL"];for(let file3 of jsonlFiles)lines.push(`- ${file3.file}: \`${file3.exists?"present":"missing"}\` (${file3.sizeBytes} bytes)`);if(lines.push("","### Migration"),!report)lines.push("- Last report: `none`");else if(lines.push(`- Completed at: \`${report.completedAt}\``,`- Imported memories: \`${report.importedMemories}\``,`- Imported proposals: \`${report.importedProposals}\``,`- Invalid rows: \`${report.invalidRows.length}\``,`- Backups: \`${report.backups.length}\``),report.invalidRows.length>0){lines.push("","Invalid rows:");for(let row of report.invalidRows.slice(0,20))lines.push(`- ${row.file}:${row.line} - ${row.error}`);if(report.invalidRows.length>20)lines.push(`- ... ${report.invalidRows.length-20} more`)}return lines.join(`
2092
+ `)}async function handleMemoryStatusCommand(directory,_args){let config3=resolveCommandMemoryConfig(directory),storageDir=resolveMemoryStorageDir(directory,config3),sqlitePath=resolveSqliteDatabasePath(directory,config3),jsonlFiles=await getLegacyJsonlFileStatus(directory,config3),report=await readMigrationReport(directory,config3),lines=["## Swarm Memory Status","",`- Enabled: \`${config3.enabled}\``,`- Provider: \`${config3.provider}\``,`- Storage: \`${storageDir}\``,`- SQLite path: \`${sqlitePath}\``,`- SQLite database exists: \`${existsSync75(sqlitePath)}\``,"- Automatic destructive cleanup: `disabled`","","### Legacy JSONL"];for(let file3 of jsonlFiles)lines.push(`- ${file3.file}: \`${file3.exists?"present":"missing"}\` (${file3.sizeBytes} bytes)`);if(lines.push("","### Migration"),!report)lines.push("- Last report: `none`");else if(lines.push(`- Completed at: \`${report.completedAt}\``,`- Imported memories: \`${report.importedMemories}\``,`- Imported proposals: \`${report.importedProposals}\``,`- Invalid rows: \`${report.invalidRows.length}\``,`- Backups: \`${report.backups.length}\``),report.invalidRows.length>0){lines.push("","Invalid rows:");for(let row of report.invalidRows.slice(0,20))lines.push(`- ${row.file}:${row.line} - ${row.error}`);if(report.invalidRows.length>20)lines.push(`- ... ${report.invalidRows.length-20} more`)}return lines.join(`
2093
2093
  `)}async function handleMemoryPendingCommand(directory,args2){let parsed=parseMaintenanceArgs(args2,{usage:"Usage: /swarm memory pending [--limit <n>]",allowConfirm:!1});if("error"in parsed)return parsed.error;let config3=resolveCommandMemoryConfig(directory),provider=createMaintenanceProvider(directory,config3);try{await provider.initialize?.();let report=await buildMemoryMaintenanceReport(provider,{...maintenanceReportOptions(config3,parsed.limit)}),lines=["## Swarm Memory Pending","",`- Pending proposals shown: \`${report.pendingProposals.length}\``,`- Rejected proposal reasons shown: \`${report.rejectedProposalReasons.length}\``,`- Promotion candidates shown: \`${report.promotionCandidates.length}\``];return appendProposalLines(lines,"Pending proposals",report.pendingProposals),appendProposalLines(lines,"Rejected proposal reasons",report.rejectedProposalReasons),appendMemoryLines(lines,"Promotion candidates (high learned utility, frequently recalled)",report.promotionCandidates),lines.join(`
2094
2094
  `)}finally{await provider.close?.()}}async function handleMemoryRecallLogCommand(directory,args2){let parsed=parseMaintenanceArgs(args2,{usage:"Usage: /swarm memory recall-log [--limit <n>]",allowConfirm:!1});if("error"in parsed)return parsed.error;let config3=resolveCommandMemoryConfig(directory),provider=createMaintenanceProvider(directory,config3);try{await provider.initialize?.();let report=await buildMemoryMaintenanceReport(provider,{...maintenanceReportOptions(config3,parsed.limit)}),lines=["## Swarm Memory Recall Log","",`- Recall events scanned: \`${report.recallEventCount}\``,`- Most-recalled memories shown: \`${report.mostRecalledMemories.length}\``,`- Never-recalled memories shown: \`${report.neverRecalledMemories.length}\``];return appendRecallRoleLines(lines,report.recallByAgentRole),appendRecallMemoryLines(lines,report.mostRecalledMemories),appendMemoryLines(lines,"Never-recalled memories",report.neverRecalledMemories),lines.join(`
2095
2095
  `)}finally{await provider.close?.()}}async function handleMemoryValueLogCommand(directory,args2){let parsed=parseMaintenanceArgs(args2,{usage:"Usage: /swarm memory value-log [--limit <n>]",allowConfirm:!1});if("error"in parsed)return parsed.error;let config3=resolveCommandMemoryConfig(directory),provider=createMaintenanceProvider(directory,config3),q=config3.qLearning;try{await provider.initialize?.();let lines=["## Swarm Memory Value Log",""];if(!provider.listRewardEvents)return lines.push("- Reward-event history is not available for this memory provider."),lines.join(`
@@ -2102,11 +2102,11 @@ Flags:
2102
2102
  `)}function resolveCommandMemoryConfig(directory){let loaded=loadPluginConfig(directory).memory;return resolveMemoryConfig(loaded??DEFAULT_MEMORY_CONFIG)}function parseEvaluateArgs(directory,args2){let json3=!1,fixtureDirectory=path150.join(PACKAGE_ROOT,"tests","fixtures","memory-recall");for(let i=0;i<args2.length;i++){let arg=args2[i];if(arg==="--json"){json3=!0;continue}if(arg==="--fixtures"){let next=args2[i+1];if(!next)return{error:"Usage: /swarm memory evaluate [--json] [--fixtures <directory>]"};let resolvedFixtures=path150.resolve(directory,next),canonical=path150.normalize(resolvedFixtures)+path150.sep,allowedRootA=path150.normalize(directory)+path150.sep,allowedRootB=path150.normalize(path150.join(PACKAGE_ROOT,"tests","fixtures","memory-recall"))+path150.sep;if(!canonical.startsWith(allowedRootA)&&!canonical.startsWith(allowedRootB))return{error:"--fixtures <directory> must resolve under the project directory or the bundled tests/fixtures/memory-recall directory"};fixtureDirectory=resolvedFixtures,i++;continue}return{error:"Usage: /swarm memory evaluate [--json] [--fixtures <directory>]"}}return{json:json3,fixtureDirectory}}function parseMaintenanceArgs(args2,options){let limit=20,confirm=!1,allowLimit=options.allowLimit??!0;for(let i=0;i<args2.length;i++){let arg=args2[i];if(arg==="--confirm"&&options.allowConfirm){confirm=!0;continue}if(arg==="--limit"&&allowLimit){let next=args2[i+1];if(!next||!/^\d+$/.test(next))return{error:options.usage};limit=Math.min(100,Math.max(1,Number(next))),i++;continue}return{error:options.usage}}return{limit,confirm}}function resolvePackageRootFromModule(modulePath){let moduleDir=path150.dirname(modulePath),leaf=path150.basename(moduleDir);if(leaf==="commands"||leaf==="cli")return path150.resolve(moduleDir,"..","..");if(leaf==="dist")return path150.resolve(moduleDir,"..");return path150.resolve(moduleDir,"..")}function formatMigrationResult(label,report){if(!report)return[`## Swarm Memory ${label}`,"","No migration report was written."].join(`
2103
2103
  `);let lines=[`## Swarm Memory ${label}`,"",`- Completed at: \`${report.completedAt}\``,`- Imported memories: \`${report.importedMemories}\``,`- Imported proposals: \`${report.importedProposals}\``,`- Invalid rows: \`${report.invalidRows.length}\``,`- Backups: \`${report.backups.length}\``];if(report.backups.length>0){lines.push("","Backups:");for(let backup of report.backups)lines.push(`- \`${backup.backup}\` (${backup.created?"created":"already existed"})`)}return appendInvalidRows(lines,report.invalidRows),lines.join(`
2104
2104
  `)}function appendInvalidRows(lines,invalidRows){if(invalidRows.length===0)return;lines.push("","Invalid rows:");for(let row of invalidRows.slice(0,20))lines.push(`- ${row.file}:${row.line} - ${row.error}`);if(invalidRows.length>20)lines.push(`- ... ${invalidRows.length-20} more`)}function appendProposalLines(lines,title,proposals){if(lines.push("",`### ${title}`),proposals.length===0){lines.push("- none");return}for(let proposal of proposals){let reason=proposal.status==="rejected"?` - ${proposal.rejectionReason??"no reason recorded"}`:"";lines.push(`- \`${proposal.id}\` ${proposal.operation} ${proposal.targetMemoryId??proposal.proposedRecord?.id??"new"} (${proposal.status})${reason}`)}}function appendMemoryLines(lines,title,memories){if(lines.push("",`### ${title}`),memories.length===0){lines.push("- none");return}for(let memory of memories)lines.push(`- \`${memory.id}\` ${memory.kind} confidence=${memory.confidence.toFixed(2)} updated=${memory.updatedAt} - ${truncate(memory.text,100)}`)}function appendRecallRoleLines(lines,roles){if(lines.push("","### Recall by agent role"),roles.length===0){lines.push("- none");return}for(let role of roles){let memoryCount=Object.keys(role.memoryIds).length;lines.push(`- \`${role.agentRole}\`: ${role.count} recall event(s), ${memoryCount} memory ID(s)`)}}function appendRecallMemoryLines(lines,memories){if(lines.push("","### Most-recalled memories"),memories.length===0){lines.push("- none");return}for(let memory of memories)lines.push(`- \`${memory.memoryId}\`: ${memory.count} hit(s), last=${memory.lastRecalledAt}, avgScore=${memory.averageScore.toFixed(3)}`)}function appendSupersededChains(lines,report){if(lines.push("","### Superseded chains"),report.supersededChains.length===0){lines.push("- none");return}for(let chain of report.supersededChains){let reason=chain.reason?` - ${chain.reason}`:"";lines.push(`- ${chain.chain.map((id)=>`\`${id}\``).join(" -> ")}${reason}`)}}function formatCompactResult(result,confirmed){let lines=["## Swarm Memory Compact","",`- Mode: \`${confirmed?"confirmed":"dry-run"}\``,`- Deleted tombstones: \`${result.removedDeleted}\``,`- Superseded records: \`${result.removedSuperseded}\``,`- Expired scratch records: \`${result.removedExpiredScratch}\``,`- Remaining memories: \`${result.remaining}\``];if(!confirmed)lines.push("","No records were removed. Re-run `/swarm memory compact --confirm` to apply this compaction.");return lines.join(`
2105
- `)}function truncate(value,maxLength){if(value.length<=maxLength)return value;return`${value.slice(0,maxLength-3)}...`}var PACKAGE_ROOT;var init_memory2=__esm(()=>{init_loader();init_memory();init_consolidation_log();PACKAGE_ROOT=path150.resolve(resolvePackageRootFromModule(fileURLToPath6(import.meta.url)))});var MEMORY_FAMILY,MIGRATED_MEMORY_FILENAMES;var init_memory_family_manifest=__esm(()=>{MEMORY_FAMILY=[{filename:"memory.db",scope:"canonical",mergeStrategy:"sqlite-file-copy",note:"SQLite memory database (records, proposals, events, recall usage, rewards, embedding config). FTS/vec indexes travel inside as derived state."},{filename:"memories.jsonl",scope:"canonical",mergeStrategy:"append-union",note:"JSONL provider memory records (legacy/debug mode only)."},{filename:"proposals.jsonl",scope:"canonical",mergeStrategy:"append-union",note:"JSONL provider pending proposals."},{filename:"audit.jsonl",scope:"canonical",mergeStrategy:"append-union",note:"JSONL provider audit events."},{filename:"reward-events.jsonl",scope:"canonical",mergeStrategy:"append-union",note:"JSONL provider reward events."},{filename:"consolidation-log.jsonl",scope:"canonical",mergeStrategy:"append-union",note:"Consolidation pass idempotency log (phaseNumber-keyed)."},{filename:"backups/",scope:"derived",mergeStrategy:"skip",note:"Pre-migration source backups (rebuildable; not migrated)."},{filename:"export/",scope:"derived",mergeStrategy:"skip",note:"JSONL export artifacts (rebuildable; not migrated)."}],MIGRATED_MEMORY_FILENAMES=MEMORY_FAMILY.filter((m)=>m.mergeStrategy!=="skip").map((m)=>m.filename)});import{copyFileSync as copyFileSync5,existsSync as existsSync75,readFileSync as readFileSync56,unlinkSync as unlinkSync22}from"node:fs";import{mkdir as mkdir40,rename as rename16}from"node:fs/promises";import*as path151 from"node:path";function readJsonl3(filePath){if(!existsSync75(filePath))return[];try{let content=readFileSync56(filePath,"utf-8"),out=[];for(let line of content.split(`
2105
+ `)}function truncate(value,maxLength){if(value.length<=maxLength)return value;return`${value.slice(0,maxLength-3)}...`}var PACKAGE_ROOT;var init_memory2=__esm(()=>{init_loader();init_memory();init_consolidation_log();PACKAGE_ROOT=path150.resolve(resolvePackageRootFromModule(fileURLToPath6(import.meta.url)))});var MEMORY_FAMILY,MIGRATED_MEMORY_FILENAMES;var init_memory_family_manifest=__esm(()=>{MEMORY_FAMILY=[{filename:"memory.db",scope:"canonical",mergeStrategy:"sqlite-file-copy",note:"SQLite memory database (records, proposals, events, recall usage, rewards, embedding config). FTS/vec indexes travel inside as derived state."},{filename:"memories.jsonl",scope:"canonical",mergeStrategy:"append-union",note:"JSONL provider memory records (legacy/debug mode only)."},{filename:"proposals.jsonl",scope:"canonical",mergeStrategy:"append-union",note:"JSONL provider pending proposals."},{filename:"audit.jsonl",scope:"canonical",mergeStrategy:"append-union",note:"JSONL provider audit events."},{filename:"reward-events.jsonl",scope:"canonical",mergeStrategy:"append-union",note:"JSONL provider reward events."},{filename:"consolidation-log.jsonl",scope:"canonical",mergeStrategy:"append-union",note:"Consolidation pass idempotency log (phaseNumber-keyed)."},{filename:"backups/",scope:"derived",mergeStrategy:"skip",note:"Pre-migration source backups (rebuildable; not migrated)."},{filename:"export/",scope:"derived",mergeStrategy:"skip",note:"JSONL export artifacts (rebuildable; not migrated)."}],MIGRATED_MEMORY_FILENAMES=MEMORY_FAMILY.filter((m)=>m.mergeStrategy!=="skip").map((m)=>m.filename)});import{copyFileSync as copyFileSync5,existsSync as existsSync76,readFileSync as readFileSync56,unlinkSync as unlinkSync23}from"node:fs";import{mkdir as mkdir40,rename as rename16}from"node:fs/promises";import*as path151 from"node:path";function readJsonl3(filePath){if(!existsSync76(filePath))return[];try{let content=readFileSync56(filePath,"utf-8"),out=[];for(let line of content.split(`
2106
2106
  `)){let trimmed=line.trim();if(!trimmed)continue;try{out.push(JSON.parse(trimmed))}catch{}}return out}catch{return[]}}function appendUnionById2(destination,source){let result=[...destination],seen=new Set(result.map((r)=>{let o=r;return typeof o.id==="string"?o.id:JSON.stringify(r)})),added=0,skipped=0;for(let src of source){let o=src,id=typeof o.id==="string"?o.id:JSON.stringify(src);if(seen.has(id)){skipped++;continue}result.push(src),seen.add(id),added++}return{merged:result,added,skipped}}function serializeJsonl(values){if(values.length===0)return"";return`${values.map((e)=>JSON.stringify(e)).join(`
2107
2107
  `)}
2108
2108
  `}function validateSerializedJsonl(serialized2){for(let line of serialized2.split(`
2109
- `)){let trimmed=line.trim();if(!trimmed)continue;try{let parsed=JSON.parse(trimmed);if(!parsed||typeof parsed!=="object")return!1}catch{return!1}}return!0}function stageSqliteDb(sourceStoragePath,destDir){let sourceDbPath=path151.join(sourceStoragePath,"memory.db");if(!existsSync75(sourceDbPath))return null;let stagedPath=path151.join(destDir,".memory.db.stage");copyFileSync5(sourceDbPath,stagedPath);for(let suffix of["-wal","-shm"]){let sidecar=`${sourceDbPath}${suffix}`;if(existsSync75(sidecar))try{copyFileSync5(sidecar,`${stagedPath}${suffix}`)}catch{}}return{stagedPath}}async function mergeStagedSqlite(destStoragePath,stagedPath){let destDbPath=path151.join(destStoragePath,"memory.db");if(!existsSync75(destDbPath)){await rename16(stagedPath,destDbPath);for(let suffix of["-wal","-shm"]){let stagedSidecar=`${stagedPath}${suffix}`;if(existsSync75(stagedSidecar))try{await rename16(stagedSidecar,`${destDbPath}${suffix}`)}catch{}}return{merged:await countRowsSafe(destDbPath),skipped:0}}try{let{loadDatabaseCtor:loadDatabaseCtor2}=await Promise.resolve().then(() => (init_sqlite_loader(),exports_sqlite_loader)),db=new(loadDatabaseCtor2())(destDbPath);try{let safePath=stagedPath.replace(/'/g,"''");db.run(`ATTACH DATABASE '${safePath}' AS staged;`);let tables=["memory_items","memory_proposals","memory_events","memory_recall_usage","memory_reward_events"],merged=0,skippedDueToError=0,failedTables=[];for(let table of tables)try{let stashed=db.query(`SELECT COUNT(*) AS n FROM staged.sqlite_master WHERE type='table' AND name='${table}'`).get();if(!stashed||stashed.n===0)continue;let result=db.run(`INSERT OR IGNORE INTO ${table} SELECT * FROM staged.${table};`);merged+=result.changes??0}catch(err){skippedDueToError++,failedTables.push(`${table} (${err instanceof Error?err.message:String(err)})`)}if(db.run("DETACH DATABASE staged;"),failedTables.length>0)warn(`[memory-family-migration] ${failedTables.length} table(s) skipped during SQLite ATTACH merge: ${failedTables.join(", ")}`);return{merged,skipped:skippedDueToError}}finally{db.close();try{unlinkSync22(stagedPath);for(let suffix of["-wal","-shm"])try{unlinkSync22(`${stagedPath}${suffix}`)}catch{}}catch{}}}catch(err){throw Error(`memory-family-migration: failed to merge SQLite into non-empty destination ${destDbPath}: ${err instanceof Error?err.message:String(err)}`)}}async function countRowsSafe(dbPath){try{let{loadDatabaseCtor:loadDatabaseCtor2}=await Promise.resolve().then(() => (init_sqlite_loader(),exports_sqlite_loader)),db=new(loadDatabaseCtor2())(dbPath);try{return db.query("SELECT COUNT(*) AS n FROM memory_items").get()?.n??0}finally{db.close()}}catch{return 0}}async function migrateMemoryFamily(destRoot,sourceRoot){let destStoragePath=rootStoragePath(destRoot),sourceStoragePath=rootStoragePath(sourceRoot);await mkdir40(destStoragePath,{recursive:!0});let destRelease=null;try{destRelease=await import_proper_lockfile12.default.lock(destStoragePath,{...MIGRATION_LOCK_RETRIES,stale:MIGRATION_LOCK_STALE_MS})}catch{}let perMember=[];try{for(let member of MEMORY_FAMILY){if(member.mergeStrategy==="skip")continue;let srcPath=path151.join(sourceStoragePath,member.filename),destPath=path151.join(destStoragePath,member.filename);if(member.mergeStrategy==="sqlite-file-copy"){if(!existsSync75(srcPath)){perMember.push({filename:member.filename,merged:0,skipped:0});continue}let staged=stageSqliteDb(sourceStoragePath,destStoragePath);if(!staged){perMember.push({filename:member.filename,merged:0,skipped:0});continue}let{merged,skipped}=await mergeStagedSqlite(destStoragePath,staged.stagedPath);perMember.push({filename:member.filename,merged,skipped});continue}if(member.mergeStrategy==="append-union"){if(!existsSync75(srcPath)){perMember.push({filename:member.filename,merged:0,skipped:0});continue}let srcData=readJsonl3(srcPath),destData=readJsonl3(destPath),{merged,added,skipped}=appendUnionById2(destData,srcData),serialized2=serializeJsonl(merged);if(!validateSerializedJsonl(serialized2))throw Error(`memory-family-migration: validation failed for ${member.filename}; aborting before commit`);await atomicWriteFile(destPath,serialized2),perMember.push({filename:member.filename,merged:added,skipped})}}if(isCohortRoot(sourceRoot)){let backupDir=path151.join(destStoragePath,"backups");await mkdir40(backupDir,{recursive:!0});let stamp=new Date().toISOString().replace(/[:.]/g,"-"),sourceDbPath=path151.join(sourceStoragePath,"memory.db");if(existsSync75(sourceDbPath)){try{copyFileSync5(sourceDbPath,path151.join(backupDir,`memory.db.pre-merge-${stamp}`))}catch{}try{let{readdirSync:readdirSync18,unlinkSync:rmFileSync}=await import("node:fs"),backups=readdirSync18(backupDir).filter((f)=>f.startsWith("memory.db.pre-merge-")).sort();while(backups.length>MAX_BACKUPS){let oldest=backups.shift();if(oldest)rmFileSync(path151.join(backupDir,oldest))}}catch{}}}}finally{if(destRelease)try{await destRelease()}catch{}}return{perMember}}var import_proper_lockfile12,MAX_BACKUPS=5;var init_memory_family_migration=__esm(()=>{init_task_file();init_family_migration_shared();init_logger();init_memory_family_manifest();init_storage_root();import_proper_lockfile12=__toESM(require_proper_lockfile(),1)});import{mkdir as mkdir41,writeFile as writeFile24}from"node:fs/promises";import*as path152 from"node:path";function formatStatus2(directory){let pointer=readMemoryLinkPointer(directory);if(!pointer)return["ℹ️ Memory is NOT linked. Memory stays local to `.swarm/memory/`.","Run `/swarm memory link` to share memory across worktrees of this repo.","(Knowledge link and memory link are independent — `/swarm link` does not link memory.)"].join(`
2109
+ `)){let trimmed=line.trim();if(!trimmed)continue;try{let parsed=JSON.parse(trimmed);if(!parsed||typeof parsed!=="object")return!1}catch{return!1}}return!0}function stageSqliteDb(sourceStoragePath,destDir){let sourceDbPath=path151.join(sourceStoragePath,"memory.db");if(!existsSync76(sourceDbPath))return null;let stagedPath=path151.join(destDir,".memory.db.stage");copyFileSync5(sourceDbPath,stagedPath);for(let suffix of["-wal","-shm"]){let sidecar=`${sourceDbPath}${suffix}`;if(existsSync76(sidecar))try{copyFileSync5(sidecar,`${stagedPath}${suffix}`)}catch{}}return{stagedPath}}async function mergeStagedSqlite(destStoragePath,stagedPath){let destDbPath=path151.join(destStoragePath,"memory.db");if(!existsSync76(destDbPath)){await rename16(stagedPath,destDbPath);for(let suffix of["-wal","-shm"]){let stagedSidecar=`${stagedPath}${suffix}`;if(existsSync76(stagedSidecar))try{await rename16(stagedSidecar,`${destDbPath}${suffix}`)}catch{}}return{merged:await countRowsSafe(destDbPath),skipped:0}}try{let{loadDatabaseCtor:loadDatabaseCtor2}=await Promise.resolve().then(() => (init_sqlite_loader(),exports_sqlite_loader)),db=new(loadDatabaseCtor2())(destDbPath);try{let safePath=stagedPath.replace(/'/g,"''");db.run(`ATTACH DATABASE '${safePath}' AS staged;`);let tables=["memory_items","memory_proposals","memory_events","memory_recall_usage","memory_reward_events"],merged=0,skippedDueToError=0,failedTables=[];for(let table of tables)try{let stashed=db.query(`SELECT COUNT(*) AS n FROM staged.sqlite_master WHERE type='table' AND name='${table}'`).get();if(!stashed||stashed.n===0)continue;let result=db.run(`INSERT OR IGNORE INTO ${table} SELECT * FROM staged.${table};`);merged+=result.changes??0}catch(err){skippedDueToError++,failedTables.push(`${table} (${err instanceof Error?err.message:String(err)})`)}if(db.run("DETACH DATABASE staged;"),failedTables.length>0)warn(`[memory-family-migration] ${failedTables.length} table(s) skipped during SQLite ATTACH merge: ${failedTables.join(", ")}`);return{merged,skipped:skippedDueToError}}finally{db.close();try{unlinkSync23(stagedPath);for(let suffix of["-wal","-shm"])try{unlinkSync23(`${stagedPath}${suffix}`)}catch{}}catch{}}}catch(err){throw Error(`memory-family-migration: failed to merge SQLite into non-empty destination ${destDbPath}: ${err instanceof Error?err.message:String(err)}`)}}async function countRowsSafe(dbPath){try{let{loadDatabaseCtor:loadDatabaseCtor2}=await Promise.resolve().then(() => (init_sqlite_loader(),exports_sqlite_loader)),db=new(loadDatabaseCtor2())(dbPath);try{return db.query("SELECT COUNT(*) AS n FROM memory_items").get()?.n??0}finally{db.close()}}catch{return 0}}async function migrateMemoryFamily(destRoot,sourceRoot){let destStoragePath=rootStoragePath(destRoot),sourceStoragePath=rootStoragePath(sourceRoot);await mkdir40(destStoragePath,{recursive:!0});let destRelease=null;try{destRelease=await import_proper_lockfile12.default.lock(destStoragePath,{...MIGRATION_LOCK_RETRIES,stale:MIGRATION_LOCK_STALE_MS})}catch{}let perMember=[];try{for(let member of MEMORY_FAMILY){if(member.mergeStrategy==="skip")continue;let srcPath=path151.join(sourceStoragePath,member.filename),destPath=path151.join(destStoragePath,member.filename);if(member.mergeStrategy==="sqlite-file-copy"){if(!existsSync76(srcPath)){perMember.push({filename:member.filename,merged:0,skipped:0});continue}let staged=stageSqliteDb(sourceStoragePath,destStoragePath);if(!staged){perMember.push({filename:member.filename,merged:0,skipped:0});continue}let{merged,skipped}=await mergeStagedSqlite(destStoragePath,staged.stagedPath);perMember.push({filename:member.filename,merged,skipped});continue}if(member.mergeStrategy==="append-union"){if(!existsSync76(srcPath)){perMember.push({filename:member.filename,merged:0,skipped:0});continue}let srcData=readJsonl3(srcPath),destData=readJsonl3(destPath),{merged,added,skipped}=appendUnionById2(destData,srcData),serialized2=serializeJsonl(merged);if(!validateSerializedJsonl(serialized2))throw Error(`memory-family-migration: validation failed for ${member.filename}; aborting before commit`);await atomicWriteFile(destPath,serialized2),perMember.push({filename:member.filename,merged:added,skipped})}}if(isCohortRoot(sourceRoot)){let backupDir=path151.join(destStoragePath,"backups");await mkdir40(backupDir,{recursive:!0});let stamp=new Date().toISOString().replace(/[:.]/g,"-"),sourceDbPath=path151.join(sourceStoragePath,"memory.db");if(existsSync76(sourceDbPath)){try{copyFileSync5(sourceDbPath,path151.join(backupDir,`memory.db.pre-merge-${stamp}`))}catch{}try{let{readdirSync:readdirSync18,unlinkSync:rmFileSync}=await import("node:fs"),backups=readdirSync18(backupDir).filter((f)=>f.startsWith("memory.db.pre-merge-")).sort();while(backups.length>MAX_BACKUPS){let oldest=backups.shift();if(oldest)rmFileSync(path151.join(backupDir,oldest))}}catch{}}}}finally{if(destRelease)try{await destRelease()}catch{}}return{perMember}}var import_proper_lockfile12,MAX_BACKUPS=5;var init_memory_family_migration=__esm(()=>{init_task_file();init_family_migration_shared();init_logger();init_memory_family_manifest();init_storage_root();import_proper_lockfile12=__toESM(require_proper_lockfile(),1)});import{mkdir as mkdir41,writeFile as writeFile24}from"node:fs/promises";import*as path152 from"node:path";function formatStatus2(directory){let pointer=readMemoryLinkPointer(directory);if(!pointer)return["ℹ️ Memory is NOT linked. Memory stays local to `.swarm/memory/`.","Run `/swarm memory link` to share memory across worktrees of this repo.","(Knowledge link and memory link are independent — `/swarm link` does not link memory.)"].join(`
2110
2110
  `);let cohortDir=resolveLinkDir(pointer.linkId),lines=["\uD83D\uDD17 Memory is shared across linked worktrees.",` link id: ${pointer.linkId}`];if(pointer.cohortId)lines.push(` cohort: ${pointer.cohortId}`);if(pointer.identitySource)lines.push(` identity: ${pointer.identitySource}`);if(pointer.degraded)lines.push(" ⚠ degraded: cohort id is machine-local (not portable across machines).");if(lines.push(` shared at: ${path152.join(cohortDir,"memory")}`),lines.push(` since: ${pointer.createdAt}`),pointer.generation!==void 0)lines.push(` generation: ${pointer.generation}`);return lines.push("Run `/swarm memory unlink` to stop sharing (keeps a local copy)."),lines.join(`
2111
2111
  `)}async function handleMemoryLinkCommand(directory,args2){if(args2[0]==="status")return formatStatus2(directory);let nameArg=args2.find((a)=>!a.startsWith("--")),linkId,displayName,cohort;if(nameArg){let sanitized=sanitizeLinkId(nameArg);if(!sanitized)return`❌ Invalid link name "${nameArg}". Use letters, digits, '.', '-', or '_'.`;linkId=sanitized,displayName=nameArg;try{cohort=await resolveCohortId(directory)}catch{}}else try{cohort=await resolveCohortId(directory),linkId=cohort.cohortId}catch(error93){return`❌ Failed to resolve cohort identity: ${error93 instanceof Error?error93.message:String(error93)}`}if(cohort?.degraded)criticalWarn(`[opencode-swarm] Cohort identity for memory link is degraded (source: ${cohort.source}). The shared memory store will be cohesive for sibling worktrees on THIS machine, but it is not a portable cohort identity (no usable git remote).`);let existing=readMemoryLinkPointer(directory);if(existing&&existing.linkId===linkId)return`ℹ️ Memory is already linked to "${linkId}".
2112
2112
  ${formatStatus2(directory)}`;let{config:loadedConfig}=loadPluginConfigWithMeta(directory),memoryConfig=MemoryConfigSchema.parse(loadedConfig.memory??{});if(!memoryConfig.link?.enabled)return["❌ Memory sharing is not enabled. Set `memory.link.enabled: true` in your","opencode.json config before running `/swarm memory link`."].join(`
@@ -2176,7 +2176,7 @@ Actionability (direct text only; required unless knowledge.promotion_require_act
2176
2176
  `,"utf-8"),invalidateCachedArtifact(filePath)}catch{}}function deriveAction(tool3){let toolLower=normalizeToolNameLowerCase(tool3??"");if(toolLower==="task")return"delegate";if(["write","edit","apply_patch","swarm_apply_patch"].includes(toolLower))return"edit";if(["read","glob","grep","search"].includes(toolLower))return"read";if(["bash","shell"].includes(toolLower))return"execute";if(toolLower==="test_runner")return"test";return"tool_use"}function fnv1aHex(text){let hash4=2166136261;for(let i=0;i<text.length;i++)hash4^=text.charCodeAt(i),hash4=Math.imul(hash4,16777619)>>>0;return hash4.toString(16).padStart(8,"0")}function redactCommandSecrets(text){let redacted=redactSecrets(text).replace(URL_CREDENTIALS_PATTERN,"$1[REDACTED:url_credentials]@"),beginMarker=redacted.search(/-----BEGIN [A-Z ]*PRIVATE KEY-----/);return beginMarker===-1?redacted:`${redacted.slice(0,beginMarker)}[REDACTED:private_key_block]`}function normalizeCommandTarget(command){let normalized=command.trim().replace(/\s+/g," "),bounded=normalized.length>MAX_COMMAND_TARGET_LENGTH?`${normalized.slice(0,MAX_COMMAND_TARGET_LENGTH-3)}...`:normalized,redacted=redactCommandSecrets(bounded);if(redacted===bounded)return redacted;let prefix=`#${fnv1aHex(bounded)} `,room=MAX_COMMAND_TARGET_LENGTH-prefix.length,body=redacted.length>room?`${redacted.slice(0,room-3)}...`:redacted;return`${prefix}${body}`}function extractTarget(tool3,args2){if(!args2)return"";if(tool3.toLowerCase()==="task"){let subagentType=args2.subagent_type;if(typeof subagentType==="string"&&subagentType.length>0)return subagentType}let targetFields=["filePath","path","file","target"];for(let field of targetFields){let value=args2[field];if(typeof value==="string"&&value.length>0)return value}let toolLower=tool3.toLowerCase();if(toolLower==="bash"||toolLower==="shell"||toolLower==="execute"||toolLower==="command"){let command=args2.command;if(typeof command==="string"&&command.trim().length>0)return normalizeCommandTarget(command);let description=args2.description;if(typeof description==="string"&&description.length>0){let safeDescription=redactCommandSecrets(description.slice(0,REDACTION_SCAN_WINDOW));return safeDescription.length>30?`${safeDescription.slice(0,27)}...`:safeDescription}let argsStr=args2.args;if(typeof argsStr==="string"&&argsStr.trim().length>0)return normalizeCommandTarget(argsStr)}return""}function extractIntent(tool3,args2){if(!args2)return"";if(tool3.toLowerCase()==="task"){let{prompt,description}=args2,safeText=redactCommandSecrets((typeof prompt==="string"?prompt:typeof description==="string"?description:"").slice(0,REDACTION_SCAN_WINDOW));if(safeText.length>100)return`${safeText.slice(0,97)}...`;return safeText}let intentFields=["description","task"];for(let field of intentFields){let value=args2[field];if(typeof value==="string"&&value.length>0){let safe=redactCommandSecrets(value.slice(0,REDACTION_SCAN_WINDOW));return safe.length>200?`${safe.slice(0,197)}...`:safe}}return""}function mapResult(verdict){if(verdict==="success")return"success";if(verdict==="failure")return"failure";return"pending"}function createTrajectoryLoggerHook(config3,_directory){let enabled=config3.enabled??!0,maxLines=config3.max_lines??500;return{toolAfter:async(input,output)=>{if(!enabled)return;let sessionId=input.sessionID;if(consumeDeniedCallMarker(sessionId,input.callID)){callStartTimes.delete(`${sessionId}:${input.callID}`);return}let session=swarmState.agentSessions.get(sessionId);if(!session?.delegationActive)return;let taskId=session.currentTaskId;if(!taskId)return;let startKey=`${sessionId}:${input.callID}`,startTime=callStartTimes.get(startKey)??Date.now();callStartTimes.delete(startKey);let elapsed_ms=Date.now()-startTime,agentName=swarmState.activeAgent.get(sessionId)??session?.agentName??"unknown",args_summary=summarizeArgs(input.args,200),verdict=deriveVerdict(output),step=nextTrajectoryStep(sessionId),action=deriveAction(input.tool),target=extractTarget(input.tool,input.args),intent=extractIntent(input.tool,input.args),result=mapResult(verdict),entry={step,agent:agentName,action,target,intent,timestamp:new Date().toISOString(),result,tool:input.tool,args_summary,verdict,elapsed_ms},sanitized=sanitizeTaskId2(taskId),relativePath2=path168.join("evidence",sanitized,"trajectory.jsonl"),trajectoryPath=validateSwarmPath(_directory,relativePath2);try{await fs90.mkdir(path168.dirname(trajectoryPath),{recursive:!0});let line=`${JSON.stringify(entry)}
2177
2177
  `;await fs90.appendFile(trajectoryPath,line,"utf-8"),await truncateTrajectoryFile(trajectoryPath,maxLines)}catch{}try{await appendTrajectoryEntry(sessionId,entry,_directory,maxLines)}catch{}}}}function markDeniedCall(sessionId,callID){if(!callID)return;let now2=Date.now();for(let[key2,expiresAt]of deniedCallMarkers)if(expiresAt<=now2)deniedCallMarkers.delete(key2);let key=`${sessionId}:${callID}`;deniedCallMarkers.delete(key),deniedCallMarkers.set(key,now2+DENIED_CALL_TTL_MS);while(deniedCallMarkers.size>MAX_DENIED_CALL_MARKERS){let oldest=deniedCallMarkers.keys().next().value;if(oldest===void 0||oldest===key)break;deniedCallMarkers.delete(oldest)}}function consumeDeniedCallMarker(sessionId,callID){if(!callID)return!1;let key=`${sessionId}:${callID}`,expiresAt=deniedCallMarkers.get(key);if(expiresAt===void 0)return!1;return deniedCallMarkers.delete(key),expiresAt>Date.now()}async function recordDeniedToolCall(sessionID,input,errorMessage2,directory,options){try{let session=swarmState.agentSessions.get(sessionID);if(!session?.delegationActive)return;let maxLines=options?.maxLines??500,startKey=`${sessionID}:${input.callID}`,startTime=callStartTimes.get(startKey);if(startTime!==void 0)callStartTimes.delete(startKey);let elapsed_ms=startTime===void 0?0:Date.now()-startTime,agentName=swarmState.activeAgent.get(sessionID)??session.agentName??"unknown",code=deriveGateDenialCode(errorMessage2),entry={step:nextTrajectoryStep(sessionID),agent:agentName,action:deriveAction(input.tool),target:extractTarget(input.tool,input.args),intent:`denied: ${code}`,timestamp:new Date().toISOString(),result:"failure",tool:input.tool,args_summary:summarizeArgs(input.args,200),verdict:"failure",elapsed_ms,callID:input.callID};markDeniedCall(sessionID,input.callID);try{await appendTrajectoryEntry(sessionID,entry,directory,maxLines)}catch{}let taskId=session.currentTaskId;if(!taskId)return;try{let relativePath2=path168.join("evidence",sanitizeTaskId2(taskId),"trajectory.jsonl"),trajectoryPath=validateSwarmPath(directory,relativePath2);await fs90.mkdir(path168.dirname(trajectoryPath),{recursive:!0}),await fs90.appendFile(trajectoryPath,`${JSON.stringify(entry)}
2178
2178
  `,"utf-8"),await truncateTrajectoryFile(trajectoryPath,maxLines)}catch{}}catch{}}function clearTrajectoryStep(sessionId){clearTrajectoryStepCounters(sessionId)}function summarizeArgs(args2,maxLength){if(!args2||Object.keys(args2).length===0)return"";let summaries=[];for(let[key,value]of Object.entries(args2)){if(SENSITIVE_FIELDS.has(key)||isSensitiveKey(key)){summaries.push(`${key}:[REDACTED]`);continue}if(value===null||value===void 0)summaries.push(`${key}:null`);else if(typeof value==="string"){let window2=value.slice(0,REDACTION_SCAN_WINDOW),redacted=redactCommandSecrets(window2),truncated=redacted.length>50?`${redacted.slice(0,50)}...`:redacted;summaries.push(`${key}:"${truncated}"`)}else if(typeof value==="number"||typeof value==="boolean")summaries.push(`${key}:${String(value)}`);else if(Array.isArray(value)){let itemSummary=value.length>3?`${value.slice(0,3).map(String).join(",")},...(+${value.length-3})`:value.map(String).join(",");summaries.push(`${key}:[${itemSummary}]`)}else if(typeof value==="object"){let keys=Object.keys(value);summaries.push(`${key}:{${keys.join(",")}}`)}else summaries.push(`${key}:${typeof value}`)}let summary=summaries.join(" ");return summary.length>maxLength?`${summary.slice(0,maxLength-3)}...`:summary}function deriveVerdict(output){if(output.metadata&&typeof output.metadata==="object"&&!Array.isArray(output.metadata)){let meta3=output.metadata;if(typeof meta3.verdict==="string"&&meta3.verdict.length>0)return meta3.verdict;if(meta3.success===!1||meta3.passed===!1)return"failure";if(meta3.success===!0||meta3.passed===!0)return"success"}let outputStr=String(output.output??"");if(outputStr.startsWith("Error:")||outputStr.startsWith("error:")||outputStr.startsWith("Error: "))return"failure";return"success"}var callStartTimes,SENSITIVE_FIELDS,SENSITIVE_SUBSTRINGS,URL_CREDENTIALS_PATTERN,REDACTION_SCAN_WINDOW=4096,MAX_COMMAND_TARGET_LENGTH=200,MAX_DENIED_CALL_MARKERS=500,DENIED_CALL_TTL_MS=300000,deniedCallMarkers;var init_trajectory_logger=__esm(()=>{init_manager2();init_redaction();init_trajectory_store();init_state2();init_swarm_artifact_cache();init_gate_denial_tracker();init_normalize_tool_name();init_trajectory_step_state();init_utils2();callStartTimes=new Map,SENSITIVE_FIELDS=new Set(["password","token","secret","api_key","apikey","authorization","access_token","refresh_token","private_key","secret_key","credential","auth","bearer","x-api-key","session_id","cookie"]),SENSITIVE_SUBSTRINGS=["key","secret","token","password","auth","credential","private","certificate","bearer","session","cookie"];URL_CREDENTIALS_PATTERN=/\b([a-zA-Z][a-zA-Z0-9+.-]*:\/\/)[^\s/@:]+:[^\s/@]+@/g;deniedCallMarkers=new Map});import*as fs91 from"node:fs";import*as path169 from"node:path";function errorMessage2(err){if(err instanceof Error)return err.message;return String(err)}async function handleResetSessionCommand(directory,_args){let results=[];try{let backup=_internals132.backupSwarmStateBeforeReset(directory,"reset-session",["session"]);if(backup.backupDir&&backup.copied.length>0){let rel=path169.relative(directory,backup.backupDir);results.push(`\uD83D\uDCE6 Backed up session state to ${rel}/ (restore by copying files back into .swarm/session/)`)}for(let w of backup.warnings)results.push(`⚠️ Backup warning: ${w}`)}catch(err){results.push(`⚠️ Auto-backup failed (continuing with reset): ${err instanceof Error?err.message:String(err)}`)}let statePath;try{if(statePath=validateSwarmPath(directory,"session/state.json"),fs91.existsSync(statePath))fs91.unlinkSync(statePath),results.push("✅ Deleted .swarm/session/state.json");else results.push("⏭️ state.json not found (already clean)")}catch{results.push("❌ Failed to delete state.json")}let sessionDir=statePath?path169.dirname(statePath):void 0,sessionFiles=[];if(sessionDir&&fs91.existsSync(sessionDir))try{sessionFiles=fs91.readdirSync(sessionDir)}catch(err){results.push(`❌ Failed to read session directory: ${errorMessage2(err)}`)}for(let file3 of sessionFiles){if(file3==="state.json")continue;let filePath=path169.join(sessionDir,file3);try{if(!fs91.existsSync(filePath))continue;if(!fs91.lstatSync(filePath).isFile())continue;fs91.unlinkSync(filePath),results.push(`✓ Deleted ${file3}`)}catch(err){results.push(`❌ Failed to delete ${file3}: ${errorMessage2(err)}`)}}let sessionCount=swarmState.agentSessions.size;for(let[sessionId,session]of swarmState.agentSessions)resetPrmSessionState(session,sessionId),clearTrajectoryStep(sessionId);swarmState.agentSessions.clear(),results.push(`✅ Cleared ${sessionCount} in-memory agent session(s)`);let chainCount=swarmState.delegationChains.size;swarmState.delegationChains.clear(),results.push(`✅ Cleared ${chainCount} delegation chain(s)`);let worktreesDir=path169.resolve(path169.dirname(directory),SWARM_WORKTREE_DIR_NAME);try{if(fs91.existsSync(worktreesDir))fs91.rmSync(worktreesDir,{recursive:!0,force:!0}),results.push("✅ Removed .swarm-worktrees/ directory")}catch(err){results.push(`⚠️ Failed to remove .swarm-worktrees/: ${errorMessage2(err)}`)}try{let branchResult=await _internals132.cleanupOrphanedBranches(directory,[]);if(branchResult.removed.length>0)results.push(`✅ Removed ${branchResult.removed.length} orphan swarm-lane branch(es)`);if(branchResult.errors.length>0)results.push(`⚠️ Failed to remove ${branchResult.errors.length} branch(es): ${branchResult.errors.map((e)=>e.error).join("; ")}`);if(branchResult.skippedRecoveryBranches&&branchResult.skippedRecoveryBranches.length>0)results.push(`ℹ️ Preserved ${branchResult.skippedRecoveryBranches.length} branch(es) with unresolved merge-back recovery records (run /swarm status to inspect)`);if(branchResult.recoveryReadError)results.push("⚠️ Skipped all lane-branch deletions: .swarm/recovery/ was unreadable (fail-safe). Resolve or clear corrupt recovery records and re-run.")}catch(err){results.push(`⚠️ Failed to cleanup orphan branches: ${errorMessage2(err)}`)}return["## Session State Reset","",...results,"","Session state cleared. Plan, evidence, and knowledge preserved.","","**All circuit breakers and revision limits have been cleared.** You can continue in this session — fresh state will be initialized automatically on the next tool call."].join(`
2179
- `)}var _internals132;var init_reset_session=__esm(()=>{init_constants();init_trajectory_logger();init_utils2();init_prm();init_state2();init_merge();init_reset_backup();_internals132={cleanupOrphanedBranches,backupSwarmStateBeforeReset}});import{mkdirSync as mkdirSync43,readdirSync as readdirSync25,renameSync as renameSync26,rmSync as rmSync14,statSync as statSync38}from"node:fs";import*as path170 from"node:path";function sanitizeSummaryId(id){if(!id||id.length===0)throw Error("Invalid summary ID: empty string");if(/\0/.test(id))throw Error("Invalid summary ID: contains null bytes");for(let i=0;i<id.length;i++)if(id.charCodeAt(i)<32)throw Error("Invalid summary ID: contains control characters");if(id.includes("..")||id.includes("../")||id.includes("..\\"))throw Error("Invalid summary ID: path traversal detected");if(!SUMMARY_ID_REGEX.test(id))throw Error(`Invalid summary ID: must match pattern ^S\\d+$, got "${id}"`);return id}async function storeSummary(directory,id,fullOutput,summaryText,maxStoredBytes){let sanitizedId=sanitizeSummaryId(id),preCheckEntry={id:sanitizedId,summaryText,fullOutput,timestamp:Date.now(),originalBytes:Buffer.byteLength(fullOutput,"utf8")},serializedSize=Buffer.byteLength(JSON.stringify(preCheckEntry),"utf8");if(serializedSize>maxStoredBytes)throw Error(`Summary entry size (${serializedSize} bytes) exceeds maximum (${maxStoredBytes} bytes)`);let relativePath2=path170.join("summaries",`${sanitizedId}.json`),summaryPath=validateSwarmPath(directory,relativePath2),summaryDir=path170.dirname(summaryPath),entry={id:sanitizedId,summaryText,fullOutput,timestamp:Date.now(),originalBytes:Buffer.byteLength(fullOutput,"utf8")},entryJson=JSON.stringify(entry);mkdirSync43(summaryDir,{recursive:!0});let tempPath=path170.join(summaryDir,`${sanitizedId}.json.tmp.${Date.now()}.${process.pid}`);try{await bunWrite(tempPath,entryJson),renameSync26(tempPath,summaryPath),invalidateCachedArtifact(summaryPath)}catch(error93){try{rmSync14(tempPath,{force:!0})}catch{}throw error93}}async function loadFullOutput(directory,id){let sanitizedId=sanitizeSummaryId(id),relativePath2=path170.join("summaries",`${sanitizedId}.json`);validateSwarmPath(directory,relativePath2);let content=await readSwarmFileAsync(directory,relativePath2);if(content===null)return null;try{let parsed=JSON.parse(content);if(typeof parsed.fullOutput==="string")return parsed.fullOutput;return warn(`Summary entry ${sanitizedId} missing valid fullOutput field`),null}catch(error93){return warn(`Summary entry validation failed for ${sanitizedId}: ${error93 instanceof Error?error93.message:String(error93)}`),null}}var SUMMARY_ID_REGEX;var init_manager4=__esm(()=>{init_utils2();init_utils();init_bun_compat();init_swarm_artifact_cache();SUMMARY_ID_REGEX=/^S\d+$/});async function handleRetrieveCommand(directory,args2){let summaryId=args2[0];if(!summaryId)return["## Swarm Retrieve","","Usage: `/swarm retrieve <id>`","","Example: `/swarm retrieve S1`","","Retrieves the full output that was replaced by a summary."].join(`
2179
+ `)}var _internals132;var init_reset_session=__esm(()=>{init_constants();init_trajectory_logger();init_utils2();init_prm();init_state2();init_merge();init_reset_backup();_internals132={cleanupOrphanedBranches,backupSwarmStateBeforeReset}});import{mkdirSync as mkdirSync43,readdirSync as readdirSync25,renameSync as renameSync25,rmSync as rmSync14,statSync as statSync38}from"node:fs";import*as path170 from"node:path";function sanitizeSummaryId(id){if(!id||id.length===0)throw Error("Invalid summary ID: empty string");if(/\0/.test(id))throw Error("Invalid summary ID: contains null bytes");for(let i=0;i<id.length;i++)if(id.charCodeAt(i)<32)throw Error("Invalid summary ID: contains control characters");if(id.includes("..")||id.includes("../")||id.includes("..\\"))throw Error("Invalid summary ID: path traversal detected");if(!SUMMARY_ID_REGEX.test(id))throw Error(`Invalid summary ID: must match pattern ^S\\d+$, got "${id}"`);return id}async function storeSummary(directory,id,fullOutput,summaryText,maxStoredBytes){let sanitizedId=sanitizeSummaryId(id),preCheckEntry={id:sanitizedId,summaryText,fullOutput,timestamp:Date.now(),originalBytes:Buffer.byteLength(fullOutput,"utf8")},serializedSize=Buffer.byteLength(JSON.stringify(preCheckEntry),"utf8");if(serializedSize>maxStoredBytes)throw Error(`Summary entry size (${serializedSize} bytes) exceeds maximum (${maxStoredBytes} bytes)`);let relativePath2=path170.join("summaries",`${sanitizedId}.json`),summaryPath=validateSwarmPath(directory,relativePath2),summaryDir=path170.dirname(summaryPath),entry={id:sanitizedId,summaryText,fullOutput,timestamp:Date.now(),originalBytes:Buffer.byteLength(fullOutput,"utf8")},entryJson=JSON.stringify(entry);mkdirSync43(summaryDir,{recursive:!0});let tempPath=path170.join(summaryDir,`${sanitizedId}.json.tmp.${Date.now()}.${process.pid}`);try{await bunWrite(tempPath,entryJson),renameSync25(tempPath,summaryPath),invalidateCachedArtifact(summaryPath)}catch(error93){try{rmSync14(tempPath,{force:!0})}catch{}throw error93}}async function loadFullOutput(directory,id){let sanitizedId=sanitizeSummaryId(id),relativePath2=path170.join("summaries",`${sanitizedId}.json`);validateSwarmPath(directory,relativePath2);let content=await readSwarmFileAsync(directory,relativePath2);if(content===null)return null;try{let parsed=JSON.parse(content);if(typeof parsed.fullOutput==="string")return parsed.fullOutput;return warn(`Summary entry ${sanitizedId} missing valid fullOutput field`),null}catch(error93){return warn(`Summary entry validation failed for ${sanitizedId}: ${error93 instanceof Error?error93.message:String(error93)}`),null}}var SUMMARY_ID_REGEX;var init_manager4=__esm(()=>{init_utils2();init_utils();init_bun_compat();init_swarm_artifact_cache();SUMMARY_ID_REGEX=/^S\d+$/});async function handleRetrieveCommand(directory,args2){let summaryId=args2[0];if(!summaryId)return["## Swarm Retrieve","","Usage: `/swarm retrieve <id>`","","Example: `/swarm retrieve S1`","","Retrieves the full output that was replaced by a summary."].join(`
2180
2180
  `);try{let fullOutput=await loadFullOutput(directory,summaryId);if(fullOutput===null)return`## Summary Not Found
2181
2181
 
2182
2182
  No stored output found for ID \`${summaryId}\`.
@@ -2291,22 +2291,22 @@ OpenSpec-compatible SDD support:
2291
2291
  Spec-Kit SDD support:
2292
2292
  - detects .specify/ marker + specs/NNN-feature-name/spec.md layout
2293
2293
  - projects a single Spec-Kit feature into .swarm/spec.md via /swarm sdd project
2294
- - use --source speckit or --source openspec to disambiguate when both are present`;var init_sdd=__esm(()=>{init_effective_spec();init_path_security();_internals139={writeProjectedSpecSync},SWARM_SPEC_REL2=path177.join(".swarm","spec.md")});import{renameSync as renameSync29,unlinkSync as unlinkSync29}from"node:fs";async function handleSimulateCommand(directory,args2){let thresholdIndex=args2.indexOf("--threshold"),minCommitsIndex=args2.indexOf("--min-commits"),options={};if(thresholdIndex>=0&&args2[thresholdIndex+1]){let val=parseFloat(args2[thresholdIndex+1]);if(!Number.isNaN(val)&&val>=0&&val<=1)options.npmiThreshold=val}if(minCommitsIndex>=0&&args2[minCommitsIndex+1]){let val=parseInt(args2[minCommitsIndex+1],10);if(!Number.isNaN(val)&&val>0)options.minCommits=val}let darkMatterPairs;try{darkMatterPairs=await _internals91.detectDarkMatter(directory,options)}catch(err){return`## Simulate Report
2294
+ - use --source speckit or --source openspec to disambiguate when both are present`;var init_sdd=__esm(()=>{init_effective_spec();init_path_security();_internals139={writeProjectedSpecSync},SWARM_SPEC_REL2=path177.join(".swarm","spec.md")});import{renameSync as renameSync28,unlinkSync as unlinkSync30}from"node:fs";async function handleSimulateCommand(directory,args2){let thresholdIndex=args2.indexOf("--threshold"),minCommitsIndex=args2.indexOf("--min-commits"),options={};if(thresholdIndex>=0&&args2[thresholdIndex+1]){let val=parseFloat(args2[thresholdIndex+1]);if(!Number.isNaN(val)&&val>=0&&val<=1)options.npmiThreshold=val}if(minCommitsIndex>=0&&args2[minCommitsIndex+1]){let val=parseInt(args2[minCommitsIndex+1],10);if(!Number.isNaN(val)&&val>0)options.minCommits=val}let darkMatterPairs;try{darkMatterPairs=await _internals91.detectDarkMatter(directory,options)}catch(err){return`## Simulate Report
2295
2295
 
2296
2296
  ### Error
2297
2297
 
2298
2298
  Error analyzing git history: ${err instanceof Error?err.message:String(err)}
2299
2299
 
2300
2300
  Ensure this is a git repository with commit history.`}let report=["# Simulate Report","",`Generated: ${new Date().toISOString()}`,"","## Dark Matter Analysis",`${darkMatterPairs.length} hidden coupling pairs detected:`,"","| File A | File B | NPMI | Co-Changes | Lift |","|--------|--------|------|------------|------|",...darkMatterPairs.map((p)=>`| ${p.fileA} | ${p.fileB} | ${p.npmi.toFixed(3)} | ${p.coChangeCount} | ${p.lift.toFixed(2)} |`),"","## Recommendation",`${darkMatterPairs.length} hidden coupling pairs may cause unexpected side effects when modified.`].filter(Boolean).join(`
2301
- `);try{let fs99=await import("node:fs/promises"),path178=await import("node:path"),reportPath=path178.join(directory,".swarm","simulate-report.md");await fs99.mkdir(path178.dirname(reportPath),{recursive:!0});let reportTempPath=path178.join(path178.dirname(reportPath),`${path178.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random()*1e9)}`);try{await fs99.writeFile(reportTempPath,report,"utf-8"),renameSync29(reportTempPath,reportPath)}catch(err){try{unlinkSync29(reportTempPath)}catch{}throw err}}catch(err){let writeErr=err instanceof Error?err.message:String(err);warn(`simulate: failed to write report to ${directory}/.swarm/simulate-report.md`,writeErr)}return`${darkMatterPairs.length} hidden coupling pairs detected`}var init_simulate=__esm(()=>{init_co_change_analyzer();init_utils()});import{createHash as createHash44,randomUUID as randomUUID22}from"node:crypto";import{closeSync as closeSync19,existsSync as existsSync89,fsyncSync as fsyncSync6,mkdirSync as mkdirSync46,openSync as openSync19,readFileSync as readFileSync67,renameSync as renameSync30,statSync as statSync39,unlinkSync as unlinkSync30,writeFileSync as writeFileSync28,writeFileSync as writeFileSyncAsync}from"node:fs";import*as path178 from"node:path";function canonicalJson3(value){if(value===null||typeof value!=="object")return JSON.stringify(value);if(Array.isArray(value))return`[${value.map(canonicalJson3).join(",")}]`;return`{${Object.entries(value).filter(([,v])=>v!==void 0).sort(([a],[b])=>a<b?-1:a>b?1:0).map(([k,v])=>`${JSON.stringify(k)}:${canonicalJson3(v)}`).join(",")}}`}function computeStateHash(value){return createHash44("sha256").update(canonicalJson3(value),"utf8").digest("hex")}function computeContentHash2(content){return createHash44("sha256").update(content,"utf8").digest("hex")}function computeEventHash(event){return computeStateHash({seq:event.seq,candidateId:event.candidateId,skillSlug:event.skillSlug,eventType:event.eventType,fromState:event.fromState,toState:event.toState,actor:event.actor,origin:event.origin,reason:event.reason,contentHashBefore:event.contentHashBefore,contentHashAfter:event.contentHashAfter,hashBefore:event.hashBefore,evidenceRefs:event.evidenceRefs,...event.payload?{payload:event.payload}:{},timestamp:event.timestamp})}function isValidSkillSlug(slug){return SLUG_PATTERN3.test(slug)}function isValidCandidateId(id){return/^[A-Za-z0-9_-]{8,128}$/.test(id)}function mintCandidateId(){return randomUUID22()}function candidateDir(directory,skillSlug,candidateId2){return path178.join(directory,".swarm","evolution","skills",skillSlug,candidateId2)}function ledgerPath(directory,skillSlug,candidateId2){return path178.join(candidateDir(directory,skillSlug,candidateId2),"lifecycle.jsonl")}function stateProjectionPath(directory,skillSlug,candidateId2){return path178.join(candidateDir(directory,skillSlug,candidateId2),"state.json")}function ensureCandidateDir(directory,skillSlug,candidateId2){let dir=candidateDir(directory,skillSlug,candidateId2);if(!existsSync89(dir))mkdirSync46(dir,{recursive:!0});return dir}function writeFileFsyncedThenRename2(tempPath,targetPath,data){let fd=openSync19(tempPath,"w");try{writeFileSync28(fd,data,"utf8"),fsyncSync6(fd)}finally{closeSync19(fd)}try{renameSync30(tempPath,targetPath)}catch(err){try{unlinkSync30(tempPath)}catch{}throw err}}async function appendEvent2(directory,eventInput){if(assertProjectRoot(directory),!isValidSkillSlug(eventInput.skillSlug))throw Error(`invalid skill slug: ${eventInput.skillSlug}`);if(!isValidCandidateId(eventInput.candidateId))throw Error(`invalid candidate id: ${eventInput.candidateId}`);let filePath=ledgerPath(directory,eventInput.skillSlug,eventInput.candidateId);return _internals140.withEvidenceLock(directory,path178.join(".swarm","evolution","skills",eventInput.skillSlug,eventInput.candidateId,"lifecycle.jsonl"),"skill-opt-ledger","append-skill-opt-event",async()=>{ensureCandidateDir(directory,eventInput.skillSlug,eventInput.candidateId);let existing=existsSync89(filePath)?readFileSync67(filePath,"utf8"):"",events=parseEventsFromText(existing),nextSeq=events.length===0?1:events[events.length-1].seq+1,lastEvent=events.length===0?null:events[events.length-1],hashBefore=lastEvent?lastEvent.hashAfter:computeStateHash(null),event={seq:nextSeq,timestamp:eventInput.timestamp??new Date().toISOString(),candidateId:eventInput.candidateId,skillSlug:eventInput.skillSlug,eventType:eventInput.eventType,fromState:eventInput.fromState,toState:eventInput.toState,actor:eventInput.actor,origin:eventInput.origin,contentHashBefore:eventInput.contentHashBefore,contentHashAfter:eventInput.contentHashAfter,hashBefore,hashAfter:"",reason:eventInput.reason,evidenceRefs:eventInput.evidenceRefs,...eventInput.payload?{payload:eventInput.payload}:{}};event.hashAfter=computeEventHash(event);let tempPath=`${filePath}.tmp.${Date.now()}.${Math.floor(Math.random()*1e9)}`,line=`${JSON.stringify(event)}
2301
+ `);try{let fs99=await import("node:fs/promises"),path178=await import("node:path"),reportPath=path178.join(directory,".swarm","simulate-report.md");await fs99.mkdir(path178.dirname(reportPath),{recursive:!0});let reportTempPath=path178.join(path178.dirname(reportPath),`${path178.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random()*1e9)}`);try{await fs99.writeFile(reportTempPath,report,"utf-8"),renameSync28(reportTempPath,reportPath)}catch(err){try{unlinkSync30(reportTempPath)}catch{}throw err}}catch(err){let writeErr=err instanceof Error?err.message:String(err);warn(`simulate: failed to write report to ${directory}/.swarm/simulate-report.md`,writeErr)}return`${darkMatterPairs.length} hidden coupling pairs detected`}var init_simulate=__esm(()=>{init_co_change_analyzer();init_utils()});import{createHash as createHash44,randomUUID as randomUUID22}from"node:crypto";import{closeSync as closeSync19,existsSync as existsSync90,fsyncSync as fsyncSync6,mkdirSync as mkdirSync46,openSync as openSync19,readFileSync as readFileSync67,renameSync as renameSync29,statSync as statSync39,unlinkSync as unlinkSync31,writeFileSync as writeFileSync28,writeFileSync as writeFileSyncAsync}from"node:fs";import*as path178 from"node:path";function canonicalJson3(value){if(value===null||typeof value!=="object")return JSON.stringify(value);if(Array.isArray(value))return`[${value.map(canonicalJson3).join(",")}]`;return`{${Object.entries(value).filter(([,v])=>v!==void 0).sort(([a],[b])=>a<b?-1:a>b?1:0).map(([k,v])=>`${JSON.stringify(k)}:${canonicalJson3(v)}`).join(",")}}`}function computeStateHash(value){return createHash44("sha256").update(canonicalJson3(value),"utf8").digest("hex")}function computeContentHash2(content){return createHash44("sha256").update(content,"utf8").digest("hex")}function computeEventHash(event){return computeStateHash({seq:event.seq,candidateId:event.candidateId,skillSlug:event.skillSlug,eventType:event.eventType,fromState:event.fromState,toState:event.toState,actor:event.actor,origin:event.origin,reason:event.reason,contentHashBefore:event.contentHashBefore,contentHashAfter:event.contentHashAfter,hashBefore:event.hashBefore,evidenceRefs:event.evidenceRefs,...event.payload?{payload:event.payload}:{},timestamp:event.timestamp})}function isValidSkillSlug(slug){return SLUG_PATTERN3.test(slug)}function isValidCandidateId(id){return/^[A-Za-z0-9_-]{8,128}$/.test(id)}function mintCandidateId(){return randomUUID22()}function candidateDir(directory,skillSlug,candidateId2){return path178.join(directory,".swarm","evolution","skills",skillSlug,candidateId2)}function ledgerPath(directory,skillSlug,candidateId2){return path178.join(candidateDir(directory,skillSlug,candidateId2),"lifecycle.jsonl")}function stateProjectionPath(directory,skillSlug,candidateId2){return path178.join(candidateDir(directory,skillSlug,candidateId2),"state.json")}function ensureCandidateDir(directory,skillSlug,candidateId2){let dir=candidateDir(directory,skillSlug,candidateId2);if(!existsSync90(dir))mkdirSync46(dir,{recursive:!0});return dir}function writeFileFsyncedThenRename2(tempPath,targetPath,data){let fd=openSync19(tempPath,"w");try{writeFileSync28(fd,data,"utf8"),fsyncSync6(fd)}finally{closeSync19(fd)}try{renameSync29(tempPath,targetPath)}catch(err){try{unlinkSync31(tempPath)}catch{}throw err}}async function appendEvent2(directory,eventInput){if(assertProjectRoot(directory),!isValidSkillSlug(eventInput.skillSlug))throw Error(`invalid skill slug: ${eventInput.skillSlug}`);if(!isValidCandidateId(eventInput.candidateId))throw Error(`invalid candidate id: ${eventInput.candidateId}`);let filePath=ledgerPath(directory,eventInput.skillSlug,eventInput.candidateId);return _internals140.withEvidenceLock(directory,path178.join(".swarm","evolution","skills",eventInput.skillSlug,eventInput.candidateId,"lifecycle.jsonl"),"skill-opt-ledger","append-skill-opt-event",async()=>{ensureCandidateDir(directory,eventInput.skillSlug,eventInput.candidateId);let existing=existsSync90(filePath)?readFileSync67(filePath,"utf8"):"",events=parseEventsFromText(existing),nextSeq=events.length===0?1:events[events.length-1].seq+1,lastEvent=events.length===0?null:events[events.length-1],hashBefore=lastEvent?lastEvent.hashAfter:computeStateHash(null),event={seq:nextSeq,timestamp:eventInput.timestamp??new Date().toISOString(),candidateId:eventInput.candidateId,skillSlug:eventInput.skillSlug,eventType:eventInput.eventType,fromState:eventInput.fromState,toState:eventInput.toState,actor:eventInput.actor,origin:eventInput.origin,contentHashBefore:eventInput.contentHashBefore,contentHashAfter:eventInput.contentHashAfter,hashBefore,hashAfter:"",reason:eventInput.reason,evidenceRefs:eventInput.evidenceRefs,...eventInput.payload?{payload:eventInput.payload}:{}};event.hashAfter=computeEventHash(event);let tempPath=`${filePath}.tmp.${Date.now()}.${Math.floor(Math.random()*1e9)}`,line=`${JSON.stringify(event)}
2302
2302
  `,validContent=events.map((e)=>JSON.stringify(e)).join(`
2303
2303
  `)+(events.length>0?`
2304
2304
  `:"");_internals140.writeFileFsyncedThenRename(tempPath,filePath,validContent+line);let verify=parseEventsFromText(_internals140.readFileSync(filePath,"utf8")),last=verify.length>0?verify[verify.length-1]:null;if(!last||last.seq!==event.seq||last.hashAfter!==event.hashAfter)throw Error(`skill-opt ledger append verification failed for candidate ${event.candidateId} seq ${event.seq}`);return event})}function parseEventsFromText(text){if(text.length===0)return[];let lines=text.split(`
2305
- `),events=[];for(let line of lines){if(line.length===0)continue;try{events.push(JSON.parse(line))}catch{break}}return events}function replayCandidate(directory,skillSlug,candidateId2){let filePath=ledgerPath(directory,skillSlug,candidateId2);if(!existsSync89(filePath))return{events:[],state:null,truncated:!1,badSuffix:null,lastCompleteSeq:0};let text=readFileSync67(filePath,"utf8");if(text.length===0)return{events:[],state:null,truncated:!1,badSuffix:null,lastCompleteSeq:0};let lines=text.split(`
2305
+ `),events=[];for(let line of lines){if(line.length===0)continue;try{events.push(JSON.parse(line))}catch{break}}return events}function replayCandidate(directory,skillSlug,candidateId2){let filePath=ledgerPath(directory,skillSlug,candidateId2);if(!existsSync90(filePath))return{events:[],state:null,truncated:!1,badSuffix:null,lastCompleteSeq:0};let text=readFileSync67(filePath,"utf8");if(text.length===0)return{events:[],state:null,truncated:!1,badSuffix:null,lastCompleteSeq:0};let lines=text.split(`
2306
2306
  `),events=[],truncated=!1,badSuffix=null,lastCompleteSeq=0;for(let i=0;i<lines.length;i++){let line=lines[i];if(line.length===0)continue;let parsed;try{parsed=JSON.parse(line)}catch{truncated=!0,badSuffix=lines.slice(i).join(`
2307
2307
  `);break}if(computeEventHash(parsed)!==parsed.hashAfter){truncated=!0,badSuffix=lines.slice(i).join(`
2308
- `);break}events.push(parsed),lastCompleteSeq=parsed.seq}let state=events.length===0?null:events[events.length-1].toState;return{events,state,truncated,badSuffix,lastCompleteSeq}}function quarantineSuffix(directory,skillSlug,badSuffix){assertProjectRoot(directory);let dir=path178.join(directory,".swarm","evolution","skills");if(!existsSync89(dir))mkdirSync46(dir,{recursive:!0});let hash4=computeStateHash(badSuffix).slice(0,12),stamp=Date.now(),quarantinePath=path178.join(dir,`lifecycle-quarantine.${skillSlug}.${stamp}.${hash4}`);return writeFileSyncAsync(quarantinePath,badSuffix,"utf8"),quarantinePath}function writeStateProjection(directory,skillSlug,candidateId2,replay){assertProjectRoot(directory);let target=stateProjectionPath(directory,skillSlug,candidateId2);ensureCandidateDir(directory,skillSlug,candidateId2);let projection={v:1,candidateId:candidateId2,skillSlug,state:replay.state,lastCompleteSeq:replay.lastCompleteSeq,truncated:replay.truncated,eventCount:replay.events.length,updatedAt:new Date().toISOString()},tempPath=`${target}.tmp.${Date.now()}.${Math.floor(Math.random()*1e9)}`;_internals140.writeFileFsyncedThenRename(tempPath,target,`${JSON.stringify(projection,null,2)}
2309
- `)}function writeArtifact(directory,skillSlug,candidateId2,fileName,content){assertProjectRoot(directory);let dir=ensureCandidateDir(directory,skillSlug,candidateId2),target=path178.join(dir,fileName),tempPath=`${target}.tmp.${Date.now()}.${Math.floor(Math.random()*1e9)}`;return _internals140.writeFileFsyncedThenRename(tempPath,target,content),target}function readArtifact(directory,skillSlug,candidateId2,fileName){let target=path178.join(candidateDir(directory,skillSlug,candidateId2),fileName);if(!existsSync89(target))return null;return readFileSync67(target,"utf8")}var SLUG_PATTERN3,_internals140;var init_store2=__esm(()=>{init_lock();init_project_boundary();SLUG_PATTERN3=/^[a-z0-9][a-z0-9-]{0,63}$/;_internals140={withEvidenceLock,writeFileFsyncedThenRename:writeFileFsyncedThenRename2,writeFileSync:writeFileSyncAsync,readFileSync:readFileSync67,renameSync:renameSync30,unlinkSync:unlinkSync30,existsSync:existsSync89,statSync:statSync39}});function isLegalTransition(from,to){return(from===null?INITIAL_TRANSITIONS:LEGAL_TRANSITIONS[from]).includes(to)}function assertTransition(from,to){if(!isLegalTransition(from,to))throw new IllegalTransitionError(from,to)}async function recordTransition(input){let replay=replayCandidate(input.directory,input.skillSlug,input.candidateId),fromState=replay.state;if(replay.truncated&&replay.badSuffix)quarantineSuffix(input.directory,input.skillSlug,replay.badSuffix),fromState=replay.events.length===0?null:replay.events[replay.events.length-1].toState;if(assertTransition(fromState,input.toState),input.toState==="validation_running"){if(replay.events.some((e)=>e.toState==="accepted_pending_approval"||e.toState==="rejected"||e.toState==="inconclusive"))throw Error(`candidate ${input.candidateId} already completed validation — start a new candidate to re-test`)}let event=await appendEvent2(input.directory,{candidateId:input.candidateId,skillSlug:input.skillSlug,eventType:input.eventType,fromState,toState:input.toState,actor:input.actor,origin:input.origin,contentHashBefore:input.contentHashBefore??null,contentHashAfter:input.contentHashAfter??null,reason:input.reason,evidenceRefs:input.evidenceRefs??[],...input.payload?{payload:input.payload}:{}});return writeStateProjection(input.directory,input.skillSlug,input.candidateId,{...replayCandidate(input.directory,input.skillSlug,input.candidateId),events:[...replay.events,event]}),{event,fromState,replayTruncated:replay.truncated}}function currentCandidateState(directory,skillSlug,candidateId2){let replay=replayCandidate(directory,skillSlug,candidateId2);if(replay.truncated&&replay.badSuffix)quarantineSuffix(directory,skillSlug,replay.badSuffix);return{state:replay.events.length===0?null:replay.events[replay.events.length-1].toState,lastEvent:replay.events.length===0?null:replay.events[replay.events.length-1],truncated:replay.truncated}}var IllegalTransitionError,LEGAL_TRANSITIONS,INITIAL_TRANSITIONS;var init_lifecycle=__esm(()=>{init_store2();IllegalTransitionError=class IllegalTransitionError extends Error{from;to;constructor(from,to){super(`illegal skill-opt transition: ${from??"<none>"} → ${to}`);this.from=from;this.to=to;this.name="IllegalTransitionError"}};LEGAL_TRANSITIONS={discovered:["drafted"],drafted:["smoke_validated","rejected"],smoke_validated:["validation_running","rejected"],validation_running:["accepted_pending_approval","rejected","inconclusive"],accepted_pending_approval:["activated","expired","rolled_back"],rejected:[],inconclusive:["drafted","rejected"],activated:["rolled_back"],expired:[],rolled_back:[]},INITIAL_TRANSITIONS=["discovered"]});import{existsSync as existsSync90,mkdirSync as mkdirSync47,readFileSync as readFileSync68,renameSync as renameSync31,unlinkSync as unlinkSync31,writeFileSync as writeFileSync29}from"node:fs";import*as path179 from"node:path";function writeSkillFileAtomic(targetPath,content){let tempPath=`${targetPath}.tmp.${Date.now()}.${Math.floor(Math.random()*1e9)}`;try{_internals141.writeFileSync(tempPath,content,"utf8"),_internals141.renameSync(tempPath,targetPath)}finally{try{if(existsSync90(tempPath))_internals141.unlinkSync(tempPath)}catch{}}}async function activateCandidate(input){let skillPath=path179.join(input.directory,".opencode","skills","generated",input.skillSlug,"SKILL.md"),incumbent=existsSync90(skillPath)?readFileSync68(skillPath,"utf8"):"",currentHash=computeContentHash2(incumbent);if(currentHash!==input.expectedContentHash)return{activated:!1,reason:`STALE_BASE: expected ${input.expectedContentHash.slice(0,12)} but current is ${currentHash.slice(0,12)}`,rollbackSnapshotRef:""};let candidateContent=readArtifact(input.directory,input.skillSlug,input.candidateId,"candidate.md");if(candidateContent===null)return{activated:!1,reason:"candidate content not found (drafted candidate missing)",rollbackSnapshotRef:""};let state=currentCandidateState(input.directory,input.skillSlug,input.candidateId);if(state.state!=="accepted_pending_approval")return{activated:!1,reason:`INVALID_STATE: candidate is in state ${state.state??"<none>"}; activation requires accepted_pending_approval`,rollbackSnapshotRef:""};let rollbackSnapshotRef=writeArtifact(input.directory,input.skillSlug,input.candidateId,"rollback.md",incumbent),skillRoot=path179.dirname(skillPath);if(!existsSync90(skillRoot))mkdirSync47(skillRoot,{recursive:!0});return writeSkillFileAtomic(skillPath,candidateContent),await recordTransition({directory:input.directory,skillSlug:input.skillSlug,candidateId:input.candidateId,toState:"activated",eventType:"activate",actor:input.actor,origin:"command:skill-opt:approve",reason:"human-approved activation",contentHashBefore:currentHash,contentHashAfter:computeContentHash2(candidateContent),evidenceRefs:[rollbackSnapshotRef],payload:{rollbackSnapshotRef}}),{activated:!0,reason:"activated",rollbackSnapshotRef}}async function rollbackCandidate(input){let snapshot=readArtifact(input.directory,input.skillSlug,input.candidateId,"rollback.md");if(snapshot===null)return{rolledBack:!1,reason:"no rollback snapshot recorded for this candidate"};let state=currentCandidateState(input.directory,input.skillSlug,input.candidateId);if(state.state!=="activated")return{rolledBack:!1,reason:`INVALID_STATE: candidate is in state ${state.state??"<none>"}; rollback requires activated`};let skillPath=path179.join(input.directory,".opencode","skills","generated",input.skillSlug,"SKILL.md"),beforeContent=existsSync90(skillPath)?readFileSync68(skillPath,"utf8"):"";return writeSkillFileAtomic(skillPath,snapshot),await recordTransition({directory:input.directory,skillSlug:input.skillSlug,candidateId:input.candidateId,toState:"rolled_back",eventType:"rollback",actor:input.actor,origin:"command:skill-opt:rollback",reason:"human-invoked rollback",contentHashBefore:computeContentHash2(beforeContent),contentHashAfter:computeContentHash2(snapshot)}),{rolledBack:!0,reason:"rolled back from snapshot"}}var _internals141;var init_activation2=__esm(()=>{init_lifecycle();init_store2();_internals141={writeFileSync:writeFileSync29,renameSync:renameSync31,unlinkSync:unlinkSync31}});var exports_runner={};__export(exports_runner,{runEvaluation:()=>runEvaluation,createModelEvaluationExecutor:()=>createModelEvaluationExecutor,_internals:()=>_internals142});import*as fs99 from"node:fs";import*as path180 from"node:path";function aggregateCost(results){if(results.some((result)=>result.cost.source==="unavailable"))return{source:"unavailable"};return{source:results.some((result)=>result.cost.source==="estimated")?"estimated":"reported",usd:results.reduce((sum,result)=>sum+(result.cost.usd??0),0)}}function failureResult(args2){return{v:1,taskId:args2.task.id,category:args2.task.category,protected:args2.task.protected,repetition:args2.repetition,candidateId:args2.candidate.id,seed:args2.seed,outcome:args2.outcome,scoreRange:args2.task.scorer.scoreRange,cost:args2.cost??{source:"unavailable"},durationMs:args2.durationMs,retries:0,failureCode:args2.failureCode}}function parseBuiltinScore(text){let value;try{value=JSON.parse(text.trim())}catch{throw new ScorerFailure("malformed","builtin-invalid-json",!1)}let parsed=BuiltinVerdictSchema.safeParse(value);if(!parsed.success)throw new ScorerFailure("malformed","builtin-schema-invalid",!1);let verdict=parsed.data;return{v:1,score:verdict.caught?1:0,cost:{source:"unavailable"},metadata:verdict.reason?{reason:verdict.reason}:void 0}}async function scoreExecution(args2){if(args2.task.scorer.kind==="builtin")return parseBuiltinScore(args2.execution.text);let sourceEnvironment=resolveContainedExistingPath(args2.inputRoot,args2.task.environment.path),sourceExecutable=resolveContainedExistingPath(args2.inputRoot,args2.task.scorer.argv[0]),scorerRelative=path180.relative(sourceEnvironment,sourceExecutable);if(!scorerRelative||scorerRelative===".."||scorerRelative.startsWith(`..${path180.sep}`)||path180.isAbsolute(scorerRelative))throw new ScorerFailure("malformed","scorer-outside-task-package",!1);let isolatedExecutable=resolveContainedExistingPath(args2.isolatedRoot,scorerRelative);if(!fs99.statSync(isolatedExecutable).isFile())throw new ScorerFailure("malformed","scorer-not-a-file",!1);let extension=path180.extname(isolatedExecutable).toLowerCase(),isJavaScript=[".cjs",".js",".mjs"].includes(extension),executable=isJavaScript?process.execPath:isolatedExecutable,scorerArgs=isJavaScript?[isolatedExecutable,...args2.task.scorer.argv.slice(1)]:args2.task.scorer.argv.slice(1),artifactDirectory=path180.join(args2.isolatedRoot,".artifacts");fs99.mkdirSync(artifactDirectory,{recursive:!0}),fs99.writeFileSync(path180.join(artifactDirectory,"model-output.json"),JSON.stringify({v:1,text:args2.execution.text}));let result=await _internals142.runExternalTool({executable,args:scorerArgs,cwd:args2.isolatedRoot,timeoutMs:Math.min(args2.task.scorer.timeoutMs,args2.timeoutMs),maxStdoutBytes:args2.maxOutputBytes,maxStderrBytes:args2.maxOutputBytes,abortSignal:args2.abortSignal,env:{...process.env,SWARM_EVAL_TASK_ID:args2.task.id,SWARM_EVAL_CANDIDATE_ID:args2.candidate.id,SWARM_EVAL_ARTIFACT_DIR:artifactDirectory,SWARM_EVAL_SEED:args2.seed}});if(result.status==="timeout")throw new ScorerFailure("timeout","scorer-timeout",!1);if(result.status==="cancelled")throw new ScorerFailure("cancelled","scorer-cancelled",!1);if(result.status==="spawn-error")throw new ScorerFailure("infrastructure_failure","scorer-spawn-failure",!0);if(result.exitCode!==0)throw new ScorerFailure("infrastructure_failure",`scorer-exit-${result.exitCode??"none"}`,!0);if(result.stdoutTruncated||result.stderrTruncated)throw new ScorerFailure("malformed","scorer-output-truncated",!1);let value;try{value=JSON.parse(result.stdout.trim())}catch{throw new ScorerFailure("malformed","scorer-invalid-json",!1)}let parsed=ScorerOutputSchema.safeParse(value);if(!parsed.success)throw new ScorerFailure("malformed","scorer-schema-invalid",!1);return parsed.data}async function runExecutorWithinBudget(args2){let startedAt=Date.now(),controller=new AbortController,timedOut=!1,parentAbort=()=>controller.abort();if(args2.parentSignal.addEventListener("abort",parentAbort,{once:!0}),args2.parentSignal.aborted)controller.abort();let timer=setTimeout(()=>{timedOut=!0,controller.abort()},args2.maxTimeMs);try{let aborted3=new Promise((resolve73)=>{let finish=()=>resolve73({status:timedOut?"timeout":"cancelled",text:"",durationMs:Date.now()-startedAt,cost:{source:"unavailable"},error:timedOut?"executor-task-timeout":"executor-cancelled"});if(controller.signal.addEventListener("abort",finish,{once:!0}),controller.signal.aborted)finish()});return await Promise.race([args2.options.executor({task:args2.task,candidate:args2.candidate,isolatedRoot:args2.isolatedRoot,instruction:args2.instruction,payload:args2.payload,seed:args2.seed,abortSignal:controller.signal,projectRoot:args2.options.projectRoot}),aborted3])}finally{clearTimeout(timer),args2.parentSignal.removeEventListener("abort",parentAbort),controller.abort()}}async function executePairMember(args2){let startedAt=Date.now(),seed=canonicalHash(`${args2.options.seed}:${args2.task.id}:${args2.candidate.id}:${args2.repetition}`);if(args2.signal.aborted)return failureResult({...args2,seed,outcome:"cancelled",durationMs:0,failureCode:"cancelled-before-execution"});if(args2.task.environment.kind==="container")return failureResult({...args2,seed,outcome:"unsupported",durationMs:0,failureCode:"container-runner-unavailable"});try{return await _internals142.withDisposableWorktree({projectRoot:args2.options.projectRoot,baseRef:args2.baseSha,abortSignal:args2.signal,run:async(worktree)=>{let isolatedRoot=path180.join(worktree.path,".swarm-evaluation-task");fs99.mkdirSync(isolatedRoot,{recursive:!0});try{fs99.cpSync(resolveContainedExistingPath(args2.inputRoot,args2.task.environment.path),isolatedRoot,{recursive:!0,errorOnExist:!1});let instruction=fs99.readFileSync(resolveContainedExistingPath(args2.inputRoot,args2.task.instructionPath),"utf8"),payload=fs99.readFileSync(resolveContainedExistingPath(args2.inputRoot,args2.candidate.payloadPath),"utf8"),remainingBeforeExecution=args2.options.budgets.maxTaskTimeMs-(Date.now()-startedAt);if(remainingBeforeExecution<=0)return failureResult({...args2,seed,outcome:"timeout",durationMs:Date.now()-startedAt,failureCode:"task-budget-exhausted-before-executor"});let execution=await runExecutorWithinBudget({options:args2.options,task:args2.task,candidate:args2.candidate,isolatedRoot,instruction,payload,seed,parentSignal:args2.signal,maxTimeMs:remainingBeforeExecution});if(execution.status!=="completed")return failureResult({...args2,seed,outcome:execution.status==="infrastructure_failure"?"infrastructure_failure":execution.status,durationMs:execution.durationMs,cost:execution.cost,failureCode:execution.error??`executor-${execution.status}`});if(Buffer.byteLength(execution.text,"utf8")>args2.options.budgets.maxOutputBytes)return failureResult({...args2,seed,outcome:"malformed",durationMs:Date.now()-startedAt,cost:execution.cost,failureCode:"executor-output-truncated"});let scored;try{let remainingBeforeScorer=args2.options.budgets.maxTaskTimeMs-(Date.now()-startedAt);if(remainingBeforeScorer<=0)throw new ScorerFailure("timeout","task-budget-exhausted-before-scorer",!1);scored=await scoreExecution({task:args2.task,candidate:args2.candidate,inputRoot:args2.inputRoot,isolatedRoot,execution,seed,maxOutputBytes:args2.options.budgets.maxOutputBytes,timeoutMs:remainingBeforeScorer,abortSignal:args2.signal})}catch(error93){let scorerFailure=error93 instanceof ScorerFailure?error93:void 0;return failureResult({...args2,seed,outcome:args2.signal.aborted?"cancelled":scorerFailure?.outcome??"malformed",durationMs:Date.now()-startedAt,cost:execution.cost,failureCode:scorerFailure?.failureCode??(error93 instanceof Error?error93.message.slice(0,160):"scorer-error")})}let[minimum,maximum]=args2.task.scorer.scoreRange;if(scored.score<minimum||scored.score>maximum)return failureResult({...args2,seed,outcome:"malformed",durationMs:Date.now()-startedAt,cost:scored.cost,failureCode:"score-out-of-range"});return{v:1,taskId:args2.task.id,category:args2.task.category,protected:args2.task.protected,repetition:args2.repetition,candidateId:args2.candidate.id,seed,outcome:"scored",score:scored.score,scoreRange:args2.task.scorer.scoreRange,cost:scored.cost,durationMs:Date.now()-startedAt,retries:0,metadata:scored.metadata}}finally{fs99.rmSync(isolatedRoot,{recursive:!0,force:!0})}}})}catch(error93){return failureResult({...args2,seed,outcome:"infrastructure_failure",durationMs:Date.now()-startedAt,failureCode:canonicalHash(String(error93)).slice(0,32)})}}async function executePairMemberWithRetries(args2){let result;for(let attempt=0;attempt<=args2.options.budgets.maxRetries;attempt++)if(result=await executePairMember(args2),result.retries=attempt,result.outcome!=="infrastructure_failure"||args2.signal.aborted)return result;return result}async function runEvaluation(options){let inputRoot=options.inputRoot??options.projectRoot,tasks=options.tasks.map((task)=>EvaluationTaskV1Schema.parse(task));if(tasks.length===0||tasks.length>options.budgets.maxTasks)throw Error("evaluation task count exceeds its declared budget");if(tasks.some((task)=>task.split!==options.split))throw Error("evaluation task split does not match the run split");let baseline=EvaluationCandidateV1Schema.parse(options.baseline),candidate=EvaluationCandidateV1Schema.parse(options.candidate);for(let item of[baseline,candidate])if(await computeCandidateInputContentHash(inputRoot,item)!==item.contentHash)throw Error(`candidate ${item.id} content hash is invalid`);let snapshotDraft={v:1,id:`taskset-${canonicalHash(tasks.map((task)=>task.id)).slice(0,20)}`,split:options.split,tasks,createdAt:new Date().toISOString()};for(let task of tasks)await admitEvaluationTask(options.projectRoot,task,inputRoot);let taskSet={...snapshotDraft,contentHash:computeTaskSetContentHash(snapshotDraft)},storedTaskSet=await saveTaskSetSnapshot(options.projectRoot,taskSet,inputRoot),runId=`eval-${canonicalHash({baseline:baseline.contentHash,candidate:candidate.contentHash,taskSet:storedTaskSet.contentHash,split:options.split,seed:options.seed,models:options.models,budgets:options.budgets}).slice(0,32)}`,existingRun=await readEvaluationRun(options.projectRoot,runId);if(existingRun)return existingRun;if(options.split==="test")await claimHeldOutTest(options.projectRoot,{v:1,runId,taskSetHash:storedTaskSet.contentHash,baselineHash:baseline.contentHash,candidateHash:candidate.contentHash,claimedAt:new Date().toISOString()});let before=await _internals142.captureWorkingTreeFingerprint(options.projectRoot),controller=new AbortController,externallyCancelled=options.abortSignal?.aborted??!1,timedOut=!1,budgetInconclusive=!1,scheduledSpendUsd=0,externalAbort=()=>{externallyCancelled=!0,controller.abort()};if(options.abortSignal?.addEventListener("abort",externalAbort,{once:!0}),externallyCancelled)controller.abort();let totalExecutions=tasks.length*2*options.budgets.maxRepetitions,executionWaves=Math.ceil(totalExecutions/options.budgets.maxConcurrency),totalTimeoutMs=Math.min(2147483647,options.budgets.maxTaskTimeMs*executionWaves*(options.budgets.maxRetries+1)+1000),timeout=setTimeout(()=>{timedOut=!0,controller.abort()},totalTimeoutMs);try{let limit=pLimit(options.budgets.maxConcurrency),jobs=[];for(let task of tasks)for(let item of[baseline,candidate])for(let repetition=0;repetition<options.budgets.maxRepetitions;repetition++)jobs.push(limit(()=>executePairMemberWithRetries({options,inputRoot,task,candidate:item,repetition,signal:controller.signal,baseSha:before.head}).then((result)=>{if(options.budgets.maxSpendUsd!==void 0){if(result.cost.source==="unavailable")budgetInconclusive=!0,controller.abort();else if(scheduledSpendUsd+=result.cost.usd??0,scheduledSpendUsd>options.budgets.maxSpendUsd)budgetInconclusive=!0,controller.abort()}return result})));let results=await Promise.all(jobs);for(let task of tasks)if(await computeTaskInputContentHash(inputRoot,task)!==task.contentHash)throw Error(`task ${task.id} changed during evaluation`);for(let item of[baseline,candidate])if(await computeCandidateInputContentHash(inputRoot,item)!==item.contentHash)throw Error(`candidate ${item.id} changed during evaluation`);let cost=aggregateCost(results),spendUnknown=options.budgets.maxSpendUsd!==void 0&&cost.source==="unavailable",overSpend=options.budgets.maxSpendUsd!==void 0&&cost.source!=="unavailable"&&(cost.usd??0)>options.budgets.maxSpendUsd,incomplete=results.some((result)=>result.outcome!=="scored"),runDraft={v:1,runId,createdAt:new Date().toISOString(),status:externallyCancelled||timedOut?"cancelled":incomplete||spendUnknown||overSpend||budgetInconclusive?"inconclusive":"complete",baseline,candidate,taskSet:{id:storedTaskSet.id,contentHash:storedTaskSet.contentHash,taskIds:tasks.map((task)=>task.id)},split:options.split,seed:options.seed,models:options.models,environment:{platform:process.platform,arch:process.arch,runtime:`node-${process.versions.node};bun-${process.versions.bun??"compat"}`,baseSha:before.head,activeTreeHash:canonicalHash(before),taskSetHash:storedTaskSet.contentHash},budgets:options.budgets,results,cost},run=EvaluationRunV1Schema.parse({...runDraft,integrityHash:computeRunIntegrityHash(runDraft)});return await saveEvaluationRun(options.projectRoot,run),run}finally{clearTimeout(timeout),options.abortSignal?.removeEventListener("abort",externalAbort);let after=await _internals142.captureWorkingTreeFingerprint(options.projectRoot);if(before.head!==after.head||before.porcelainHash!==after.porcelainHash)throw Error("evaluation changed the active working tree")}}function createModelEvaluationExecutor(dispatcher,parentSessionId){return async(args2)=>{let result=await dispatcher({sessionDirectory:args2.projectRoot,agentName:args2.candidate.agent??"reviewer",modelId:args2.candidate.model,system:args2.payload,prompt:["EVALUATION TASK:",args2.instruction,"",`Work ONLY in this directory: ${args2.isolatedRoot}`,"Return the task-required scorer payload exactly."].join(`
2308
+ `);break}events.push(parsed),lastCompleteSeq=parsed.seq}let state=events.length===0?null:events[events.length-1].toState;return{events,state,truncated,badSuffix,lastCompleteSeq}}function quarantineSuffix(directory,skillSlug,badSuffix){assertProjectRoot(directory);let dir=path178.join(directory,".swarm","evolution","skills");if(!existsSync90(dir))mkdirSync46(dir,{recursive:!0});let hash4=computeStateHash(badSuffix).slice(0,12),stamp=Date.now(),quarantinePath=path178.join(dir,`lifecycle-quarantine.${skillSlug}.${stamp}.${hash4}`);return writeFileSyncAsync(quarantinePath,badSuffix,"utf8"),quarantinePath}function writeStateProjection(directory,skillSlug,candidateId2,replay){assertProjectRoot(directory);let target=stateProjectionPath(directory,skillSlug,candidateId2);ensureCandidateDir(directory,skillSlug,candidateId2);let projection={v:1,candidateId:candidateId2,skillSlug,state:replay.state,lastCompleteSeq:replay.lastCompleteSeq,truncated:replay.truncated,eventCount:replay.events.length,updatedAt:new Date().toISOString()},tempPath=`${target}.tmp.${Date.now()}.${Math.floor(Math.random()*1e9)}`;_internals140.writeFileFsyncedThenRename(tempPath,target,`${JSON.stringify(projection,null,2)}
2309
+ `)}function writeArtifact(directory,skillSlug,candidateId2,fileName,content){assertProjectRoot(directory);let dir=ensureCandidateDir(directory,skillSlug,candidateId2),target=path178.join(dir,fileName),tempPath=`${target}.tmp.${Date.now()}.${Math.floor(Math.random()*1e9)}`;return _internals140.writeFileFsyncedThenRename(tempPath,target,content),target}function readArtifact(directory,skillSlug,candidateId2,fileName){let target=path178.join(candidateDir(directory,skillSlug,candidateId2),fileName);if(!existsSync90(target))return null;return readFileSync67(target,"utf8")}var SLUG_PATTERN3,_internals140;var init_store2=__esm(()=>{init_lock();init_project_boundary();SLUG_PATTERN3=/^[a-z0-9][a-z0-9-]{0,63}$/;_internals140={withEvidenceLock,writeFileFsyncedThenRename:writeFileFsyncedThenRename2,writeFileSync:writeFileSyncAsync,readFileSync:readFileSync67,renameSync:renameSync29,unlinkSync:unlinkSync31,existsSync:existsSync90,statSync:statSync39}});function isLegalTransition(from,to){return(from===null?INITIAL_TRANSITIONS:LEGAL_TRANSITIONS[from]).includes(to)}function assertTransition(from,to){if(!isLegalTransition(from,to))throw new IllegalTransitionError(from,to)}async function recordTransition(input){let replay=replayCandidate(input.directory,input.skillSlug,input.candidateId),fromState=replay.state;if(replay.truncated&&replay.badSuffix)quarantineSuffix(input.directory,input.skillSlug,replay.badSuffix),fromState=replay.events.length===0?null:replay.events[replay.events.length-1].toState;if(assertTransition(fromState,input.toState),input.toState==="validation_running"){if(replay.events.some((e)=>e.toState==="accepted_pending_approval"||e.toState==="rejected"||e.toState==="inconclusive"))throw Error(`candidate ${input.candidateId} already completed validation — start a new candidate to re-test`)}let event=await appendEvent2(input.directory,{candidateId:input.candidateId,skillSlug:input.skillSlug,eventType:input.eventType,fromState,toState:input.toState,actor:input.actor,origin:input.origin,contentHashBefore:input.contentHashBefore??null,contentHashAfter:input.contentHashAfter??null,reason:input.reason,evidenceRefs:input.evidenceRefs??[],...input.payload?{payload:input.payload}:{}});return writeStateProjection(input.directory,input.skillSlug,input.candidateId,{...replayCandidate(input.directory,input.skillSlug,input.candidateId),events:[...replay.events,event]}),{event,fromState,replayTruncated:replay.truncated}}function currentCandidateState(directory,skillSlug,candidateId2){let replay=replayCandidate(directory,skillSlug,candidateId2);if(replay.truncated&&replay.badSuffix)quarantineSuffix(directory,skillSlug,replay.badSuffix);return{state:replay.events.length===0?null:replay.events[replay.events.length-1].toState,lastEvent:replay.events.length===0?null:replay.events[replay.events.length-1],truncated:replay.truncated}}var IllegalTransitionError,LEGAL_TRANSITIONS,INITIAL_TRANSITIONS;var init_lifecycle=__esm(()=>{init_store2();IllegalTransitionError=class IllegalTransitionError extends Error{from;to;constructor(from,to){super(`illegal skill-opt transition: ${from??"<none>"} → ${to}`);this.from=from;this.to=to;this.name="IllegalTransitionError"}};LEGAL_TRANSITIONS={discovered:["drafted"],drafted:["smoke_validated","rejected"],smoke_validated:["validation_running","rejected"],validation_running:["accepted_pending_approval","rejected","inconclusive"],accepted_pending_approval:["activated","expired","rolled_back"],rejected:[],inconclusive:["drafted","rejected"],activated:["rolled_back"],expired:[],rolled_back:[]},INITIAL_TRANSITIONS=["discovered"]});import{existsSync as existsSync91,mkdirSync as mkdirSync47,readFileSync as readFileSync68,renameSync as renameSync30,unlinkSync as unlinkSync32,writeFileSync as writeFileSync29}from"node:fs";import*as path179 from"node:path";function writeSkillFileAtomic(targetPath,content){let tempPath=`${targetPath}.tmp.${Date.now()}.${Math.floor(Math.random()*1e9)}`;try{_internals141.writeFileSync(tempPath,content,"utf8"),_internals141.renameSync(tempPath,targetPath)}finally{try{if(existsSync91(tempPath))_internals141.unlinkSync(tempPath)}catch{}}}async function activateCandidate(input){let skillPath=path179.join(input.directory,".opencode","skills","generated",input.skillSlug,"SKILL.md"),incumbent=existsSync91(skillPath)?readFileSync68(skillPath,"utf8"):"",currentHash=computeContentHash2(incumbent);if(currentHash!==input.expectedContentHash)return{activated:!1,reason:`STALE_BASE: expected ${input.expectedContentHash.slice(0,12)} but current is ${currentHash.slice(0,12)}`,rollbackSnapshotRef:""};let candidateContent=readArtifact(input.directory,input.skillSlug,input.candidateId,"candidate.md");if(candidateContent===null)return{activated:!1,reason:"candidate content not found (drafted candidate missing)",rollbackSnapshotRef:""};let state=currentCandidateState(input.directory,input.skillSlug,input.candidateId);if(state.state!=="accepted_pending_approval")return{activated:!1,reason:`INVALID_STATE: candidate is in state ${state.state??"<none>"}; activation requires accepted_pending_approval`,rollbackSnapshotRef:""};let rollbackSnapshotRef=writeArtifact(input.directory,input.skillSlug,input.candidateId,"rollback.md",incumbent),skillRoot=path179.dirname(skillPath);if(!existsSync91(skillRoot))mkdirSync47(skillRoot,{recursive:!0});return writeSkillFileAtomic(skillPath,candidateContent),await recordTransition({directory:input.directory,skillSlug:input.skillSlug,candidateId:input.candidateId,toState:"activated",eventType:"activate",actor:input.actor,origin:"command:skill-opt:approve",reason:"human-approved activation",contentHashBefore:currentHash,contentHashAfter:computeContentHash2(candidateContent),evidenceRefs:[rollbackSnapshotRef],payload:{rollbackSnapshotRef}}),{activated:!0,reason:"activated",rollbackSnapshotRef}}async function rollbackCandidate(input){let snapshot=readArtifact(input.directory,input.skillSlug,input.candidateId,"rollback.md");if(snapshot===null)return{rolledBack:!1,reason:"no rollback snapshot recorded for this candidate"};let state=currentCandidateState(input.directory,input.skillSlug,input.candidateId);if(state.state!=="activated")return{rolledBack:!1,reason:`INVALID_STATE: candidate is in state ${state.state??"<none>"}; rollback requires activated`};let skillPath=path179.join(input.directory,".opencode","skills","generated",input.skillSlug,"SKILL.md"),beforeContent=existsSync91(skillPath)?readFileSync68(skillPath,"utf8"):"";return writeSkillFileAtomic(skillPath,snapshot),await recordTransition({directory:input.directory,skillSlug:input.skillSlug,candidateId:input.candidateId,toState:"rolled_back",eventType:"rollback",actor:input.actor,origin:"command:skill-opt:rollback",reason:"human-invoked rollback",contentHashBefore:computeContentHash2(beforeContent),contentHashAfter:computeContentHash2(snapshot)}),{rolledBack:!0,reason:"rolled back from snapshot"}}var _internals141;var init_activation2=__esm(()=>{init_lifecycle();init_store2();_internals141={writeFileSync:writeFileSync29,renameSync:renameSync30,unlinkSync:unlinkSync32}});var exports_runner={};__export(exports_runner,{runEvaluation:()=>runEvaluation,createModelEvaluationExecutor:()=>createModelEvaluationExecutor,_internals:()=>_internals142});import*as fs99 from"node:fs";import*as path180 from"node:path";function aggregateCost(results){if(results.some((result)=>result.cost.source==="unavailable"))return{source:"unavailable"};return{source:results.some((result)=>result.cost.source==="estimated")?"estimated":"reported",usd:results.reduce((sum,result)=>sum+(result.cost.usd??0),0)}}function failureResult(args2){return{v:1,taskId:args2.task.id,category:args2.task.category,protected:args2.task.protected,repetition:args2.repetition,candidateId:args2.candidate.id,seed:args2.seed,outcome:args2.outcome,scoreRange:args2.task.scorer.scoreRange,cost:args2.cost??{source:"unavailable"},durationMs:args2.durationMs,retries:0,failureCode:args2.failureCode}}function parseBuiltinScore(text){let value;try{value=JSON.parse(text.trim())}catch{throw new ScorerFailure("malformed","builtin-invalid-json",!1)}let parsed=BuiltinVerdictSchema.safeParse(value);if(!parsed.success)throw new ScorerFailure("malformed","builtin-schema-invalid",!1);let verdict=parsed.data;return{v:1,score:verdict.caught?1:0,cost:{source:"unavailable"},metadata:verdict.reason?{reason:verdict.reason}:void 0}}async function scoreExecution(args2){if(args2.task.scorer.kind==="builtin")return parseBuiltinScore(args2.execution.text);let sourceEnvironment=resolveContainedExistingPath(args2.inputRoot,args2.task.environment.path),sourceExecutable=resolveContainedExistingPath(args2.inputRoot,args2.task.scorer.argv[0]),scorerRelative=path180.relative(sourceEnvironment,sourceExecutable);if(!scorerRelative||scorerRelative===".."||scorerRelative.startsWith(`..${path180.sep}`)||path180.isAbsolute(scorerRelative))throw new ScorerFailure("malformed","scorer-outside-task-package",!1);let isolatedExecutable=resolveContainedExistingPath(args2.isolatedRoot,scorerRelative);if(!fs99.statSync(isolatedExecutable).isFile())throw new ScorerFailure("malformed","scorer-not-a-file",!1);let extension=path180.extname(isolatedExecutable).toLowerCase(),isJavaScript=[".cjs",".js",".mjs"].includes(extension),executable=isJavaScript?process.execPath:isolatedExecutable,scorerArgs=isJavaScript?[isolatedExecutable,...args2.task.scorer.argv.slice(1)]:args2.task.scorer.argv.slice(1),artifactDirectory=path180.join(args2.isolatedRoot,".artifacts");fs99.mkdirSync(artifactDirectory,{recursive:!0}),fs99.writeFileSync(path180.join(artifactDirectory,"model-output.json"),JSON.stringify({v:1,text:args2.execution.text}));let result=await _internals142.runExternalTool({executable,args:scorerArgs,cwd:args2.isolatedRoot,timeoutMs:Math.min(args2.task.scorer.timeoutMs,args2.timeoutMs),maxStdoutBytes:args2.maxOutputBytes,maxStderrBytes:args2.maxOutputBytes,abortSignal:args2.abortSignal,env:{...process.env,SWARM_EVAL_TASK_ID:args2.task.id,SWARM_EVAL_CANDIDATE_ID:args2.candidate.id,SWARM_EVAL_ARTIFACT_DIR:artifactDirectory,SWARM_EVAL_SEED:args2.seed}});if(result.status==="timeout")throw new ScorerFailure("timeout","scorer-timeout",!1);if(result.status==="cancelled")throw new ScorerFailure("cancelled","scorer-cancelled",!1);if(result.status==="spawn-error")throw new ScorerFailure("infrastructure_failure","scorer-spawn-failure",!0);if(result.exitCode!==0)throw new ScorerFailure("infrastructure_failure",`scorer-exit-${result.exitCode??"none"}`,!0);if(result.stdoutTruncated||result.stderrTruncated)throw new ScorerFailure("malformed","scorer-output-truncated",!1);let value;try{value=JSON.parse(result.stdout.trim())}catch{throw new ScorerFailure("malformed","scorer-invalid-json",!1)}let parsed=ScorerOutputSchema.safeParse(value);if(!parsed.success)throw new ScorerFailure("malformed","scorer-schema-invalid",!1);return parsed.data}async function runExecutorWithinBudget(args2){let startedAt=Date.now(),controller=new AbortController,timedOut=!1,parentAbort=()=>controller.abort();if(args2.parentSignal.addEventListener("abort",parentAbort,{once:!0}),args2.parentSignal.aborted)controller.abort();let timer=setTimeout(()=>{timedOut=!0,controller.abort()},args2.maxTimeMs);try{let aborted3=new Promise((resolve73)=>{let finish=()=>resolve73({status:timedOut?"timeout":"cancelled",text:"",durationMs:Date.now()-startedAt,cost:{source:"unavailable"},error:timedOut?"executor-task-timeout":"executor-cancelled"});if(controller.signal.addEventListener("abort",finish,{once:!0}),controller.signal.aborted)finish()});return await Promise.race([args2.options.executor({task:args2.task,candidate:args2.candidate,isolatedRoot:args2.isolatedRoot,instruction:args2.instruction,payload:args2.payload,seed:args2.seed,abortSignal:controller.signal,projectRoot:args2.options.projectRoot}),aborted3])}finally{clearTimeout(timer),args2.parentSignal.removeEventListener("abort",parentAbort),controller.abort()}}async function executePairMember(args2){let startedAt=Date.now(),seed=canonicalHash(`${args2.options.seed}:${args2.task.id}:${args2.candidate.id}:${args2.repetition}`);if(args2.signal.aborted)return failureResult({...args2,seed,outcome:"cancelled",durationMs:0,failureCode:"cancelled-before-execution"});if(args2.task.environment.kind==="container")return failureResult({...args2,seed,outcome:"unsupported",durationMs:0,failureCode:"container-runner-unavailable"});try{return await _internals142.withDisposableWorktree({projectRoot:args2.options.projectRoot,baseRef:args2.baseSha,abortSignal:args2.signal,run:async(worktree)=>{let isolatedRoot=path180.join(worktree.path,".swarm-evaluation-task");fs99.mkdirSync(isolatedRoot,{recursive:!0});try{fs99.cpSync(resolveContainedExistingPath(args2.inputRoot,args2.task.environment.path),isolatedRoot,{recursive:!0,errorOnExist:!1});let instruction=fs99.readFileSync(resolveContainedExistingPath(args2.inputRoot,args2.task.instructionPath),"utf8"),payload=fs99.readFileSync(resolveContainedExistingPath(args2.inputRoot,args2.candidate.payloadPath),"utf8"),remainingBeforeExecution=args2.options.budgets.maxTaskTimeMs-(Date.now()-startedAt);if(remainingBeforeExecution<=0)return failureResult({...args2,seed,outcome:"timeout",durationMs:Date.now()-startedAt,failureCode:"task-budget-exhausted-before-executor"});let execution=await runExecutorWithinBudget({options:args2.options,task:args2.task,candidate:args2.candidate,isolatedRoot,instruction,payload,seed,parentSignal:args2.signal,maxTimeMs:remainingBeforeExecution});if(execution.status!=="completed")return failureResult({...args2,seed,outcome:execution.status==="infrastructure_failure"?"infrastructure_failure":execution.status,durationMs:execution.durationMs,cost:execution.cost,failureCode:execution.error??`executor-${execution.status}`});if(Buffer.byteLength(execution.text,"utf8")>args2.options.budgets.maxOutputBytes)return failureResult({...args2,seed,outcome:"malformed",durationMs:Date.now()-startedAt,cost:execution.cost,failureCode:"executor-output-truncated"});let scored;try{let remainingBeforeScorer=args2.options.budgets.maxTaskTimeMs-(Date.now()-startedAt);if(remainingBeforeScorer<=0)throw new ScorerFailure("timeout","task-budget-exhausted-before-scorer",!1);scored=await scoreExecution({task:args2.task,candidate:args2.candidate,inputRoot:args2.inputRoot,isolatedRoot,execution,seed,maxOutputBytes:args2.options.budgets.maxOutputBytes,timeoutMs:remainingBeforeScorer,abortSignal:args2.signal})}catch(error93){let scorerFailure=error93 instanceof ScorerFailure?error93:void 0;return failureResult({...args2,seed,outcome:args2.signal.aborted?"cancelled":scorerFailure?.outcome??"malformed",durationMs:Date.now()-startedAt,cost:execution.cost,failureCode:scorerFailure?.failureCode??(error93 instanceof Error?error93.message.slice(0,160):"scorer-error")})}let[minimum,maximum]=args2.task.scorer.scoreRange;if(scored.score<minimum||scored.score>maximum)return failureResult({...args2,seed,outcome:"malformed",durationMs:Date.now()-startedAt,cost:scored.cost,failureCode:"score-out-of-range"});return{v:1,taskId:args2.task.id,category:args2.task.category,protected:args2.task.protected,repetition:args2.repetition,candidateId:args2.candidate.id,seed,outcome:"scored",score:scored.score,scoreRange:args2.task.scorer.scoreRange,cost:scored.cost,durationMs:Date.now()-startedAt,retries:0,metadata:scored.metadata}}finally{fs99.rmSync(isolatedRoot,{recursive:!0,force:!0})}}})}catch(error93){return failureResult({...args2,seed,outcome:"infrastructure_failure",durationMs:Date.now()-startedAt,failureCode:canonicalHash(String(error93)).slice(0,32)})}}async function executePairMemberWithRetries(args2){let result;for(let attempt=0;attempt<=args2.options.budgets.maxRetries;attempt++)if(result=await executePairMember(args2),result.retries=attempt,result.outcome!=="infrastructure_failure"||args2.signal.aborted)return result;return result}async function runEvaluation(options){let inputRoot=options.inputRoot??options.projectRoot,tasks=options.tasks.map((task)=>EvaluationTaskV1Schema.parse(task));if(tasks.length===0||tasks.length>options.budgets.maxTasks)throw Error("evaluation task count exceeds its declared budget");if(tasks.some((task)=>task.split!==options.split))throw Error("evaluation task split does not match the run split");let baseline=EvaluationCandidateV1Schema.parse(options.baseline),candidate=EvaluationCandidateV1Schema.parse(options.candidate);for(let item of[baseline,candidate])if(await computeCandidateInputContentHash(inputRoot,item)!==item.contentHash)throw Error(`candidate ${item.id} content hash is invalid`);let snapshotDraft={v:1,id:`taskset-${canonicalHash(tasks.map((task)=>task.id)).slice(0,20)}`,split:options.split,tasks,createdAt:new Date().toISOString()};for(let task of tasks)await admitEvaluationTask(options.projectRoot,task,inputRoot);let taskSet={...snapshotDraft,contentHash:computeTaskSetContentHash(snapshotDraft)},storedTaskSet=await saveTaskSetSnapshot(options.projectRoot,taskSet,inputRoot),runId=`eval-${canonicalHash({baseline:baseline.contentHash,candidate:candidate.contentHash,taskSet:storedTaskSet.contentHash,split:options.split,seed:options.seed,models:options.models,budgets:options.budgets}).slice(0,32)}`,existingRun=await readEvaluationRun(options.projectRoot,runId);if(existingRun)return existingRun;if(options.split==="test")await claimHeldOutTest(options.projectRoot,{v:1,runId,taskSetHash:storedTaskSet.contentHash,baselineHash:baseline.contentHash,candidateHash:candidate.contentHash,claimedAt:new Date().toISOString()});let before=await _internals142.captureWorkingTreeFingerprint(options.projectRoot),controller=new AbortController,externallyCancelled=options.abortSignal?.aborted??!1,timedOut=!1,budgetInconclusive=!1,scheduledSpendUsd=0,externalAbort=()=>{externallyCancelled=!0,controller.abort()};if(options.abortSignal?.addEventListener("abort",externalAbort,{once:!0}),externallyCancelled)controller.abort();let totalExecutions=tasks.length*2*options.budgets.maxRepetitions,executionWaves=Math.ceil(totalExecutions/options.budgets.maxConcurrency),totalTimeoutMs=Math.min(2147483647,options.budgets.maxTaskTimeMs*executionWaves*(options.budgets.maxRetries+1)+1000),timeout=setTimeout(()=>{timedOut=!0,controller.abort()},totalTimeoutMs);try{let limit=pLimit(options.budgets.maxConcurrency),jobs=[];for(let task of tasks)for(let item of[baseline,candidate])for(let repetition=0;repetition<options.budgets.maxRepetitions;repetition++)jobs.push(limit(()=>executePairMemberWithRetries({options,inputRoot,task,candidate:item,repetition,signal:controller.signal,baseSha:before.head}).then((result)=>{if(options.budgets.maxSpendUsd!==void 0){if(result.cost.source==="unavailable")budgetInconclusive=!0,controller.abort();else if(scheduledSpendUsd+=result.cost.usd??0,scheduledSpendUsd>options.budgets.maxSpendUsd)budgetInconclusive=!0,controller.abort()}return result})));let results=await Promise.all(jobs);for(let task of tasks)if(await computeTaskInputContentHash(inputRoot,task)!==task.contentHash)throw Error(`task ${task.id} changed during evaluation`);for(let item of[baseline,candidate])if(await computeCandidateInputContentHash(inputRoot,item)!==item.contentHash)throw Error(`candidate ${item.id} changed during evaluation`);let cost=aggregateCost(results),spendUnknown=options.budgets.maxSpendUsd!==void 0&&cost.source==="unavailable",overSpend=options.budgets.maxSpendUsd!==void 0&&cost.source!=="unavailable"&&(cost.usd??0)>options.budgets.maxSpendUsd,incomplete=results.some((result)=>result.outcome!=="scored"),runDraft={v:1,runId,createdAt:new Date().toISOString(),status:externallyCancelled||timedOut?"cancelled":incomplete||spendUnknown||overSpend||budgetInconclusive?"inconclusive":"complete",baseline,candidate,taskSet:{id:storedTaskSet.id,contentHash:storedTaskSet.contentHash,taskIds:tasks.map((task)=>task.id)},split:options.split,seed:options.seed,models:options.models,environment:{platform:process.platform,arch:process.arch,runtime:`node-${process.versions.node};bun-${process.versions.bun??"compat"}`,baseSha:before.head,activeTreeHash:canonicalHash(before),taskSetHash:storedTaskSet.contentHash},budgets:options.budgets,results,cost},run=EvaluationRunV1Schema.parse({...runDraft,integrityHash:computeRunIntegrityHash(runDraft)});return await saveEvaluationRun(options.projectRoot,run),run}finally{clearTimeout(timeout),options.abortSignal?.removeEventListener("abort",externalAbort);let after=await _internals142.captureWorkingTreeFingerprint(options.projectRoot);if(before.head!==after.head||before.porcelainHash!==after.porcelainHash)throw Error("evaluation changed the active working tree")}}function createModelEvaluationExecutor(dispatcher,parentSessionId){return async(args2)=>{let result=await dispatcher({sessionDirectory:args2.projectRoot,agentName:args2.candidate.agent??"reviewer",modelId:args2.candidate.model,system:args2.payload,prompt:["EVALUATION TASK:",args2.instruction,"",`Work ONLY in this directory: ${args2.isolatedRoot}`,"Return the task-required scorer payload exactly."].join(`
2310
2310
  `),timeoutMs:args2.task.scorer.timeoutMs,parentSessionId,abortSignal:args2.abortSignal});return{status:result.status==="error"?"infrastructure_failure":result.status,text:result.text,durationMs:result.durationMs,cost:{source:"unavailable"},error:result.error}}}var ScorerOutputSchema,BuiltinVerdictSchema,ScorerFailure,_internals142;var init_runner=__esm(()=>{init_p_limit();init_zod();init_external_tool_runner();init_contracts();init_disposable_worktree();init_hashing();init_store();ScorerOutputSchema=exports_external.object({v:exports_external.literal(1),score:exports_external.number().finite(),cost:CostRecordSchema,metadata:exports_external.record(exports_external.string(),exports_external.unknown()).optional()}).strict(),BuiltinVerdictSchema=exports_external.object({v:exports_external.literal(1),caught:exports_external.boolean(),reason:exports_external.string().optional()}).strict();ScorerFailure=class ScorerFailure extends Error{outcome;failureCode;retryable;constructor(outcome,failureCode,retryable){super(failureCode);this.outcome=outcome;this.failureCode=failureCode;this.retryable=retryable;this.name="ScorerFailure"}};_internals142={captureWorkingTreeFingerprint,runExternalTool,withDisposableWorktree}});import*as fs100 from"node:fs/promises";import*as path181 from"node:path";function parseBaselineManifest(value){if(value===null||typeof value!=="object"||Array.isArray(value)||Object.keys(value).sort().join("\x00")!==["v","sourceSha","payloadPath","sha256"].sort().join("\x00"))throw Error("PR-review recovery baseline manifest is invalid");let manifest=value;if(manifest.v!==1||typeof manifest.sourceSha!=="string"||typeof manifest.payloadPath!=="string"||typeof manifest.sha256!=="string")throw Error("PR-review recovery baseline manifest is invalid");return manifest}async function candidate(packageRoot,input){return{...input,contentHash:await computeCandidateInputContentHash(packageRoot,input)}}async function task(packageRoot){let input={v:1,id:"pr-review-controller-recovery",source:"curated",split:"train",category:"pr-review-recovery",protected:!0,instructionPath:INSTRUCTION_PATH,environment:{kind:"fixture",path:ENVIRONMENT_PATH},scorer:{kind:"project",argv:[SCORER_PATH],timeoutMs:30000,scoreRange:[0,1]},provenance:{origin:"https://github.com/ZaxbyHub/opencode-swarm/issues/2075",license:"MIT"}};return{...input,contentHash:await computeTaskInputContentHash(packageRoot,input)}}async function verifyBaseline(packageRoot,requestedSourceSha){if(requestedSourceSha!==PR_REVIEW_RECOVERY_BASE_SHA)throw Error(`PR-review recovery baseline source SHA must be ${PR_REVIEW_RECOVERY_BASE_SHA}`);let manifest=parseBaselineManifest(JSON.parse(await fs100.readFile(path181.join(packageRoot,BASELINE_MANIFEST_PATH),"utf8")));if(manifest.sourceSha!==PR_REVIEW_RECOVERY_BASE_SHA||manifest.payloadPath!==BASELINE_PAYLOAD_PATH)throw Error("PR-review recovery baseline source SHA is invalid");let payload=await fs100.readFile(path181.join(packageRoot,manifest.payloadPath));if(sha2562(payload)!==manifest.sha256)throw Error("PR-review recovery baseline payload hash is invalid")}async function evaluatePrReviewRecoveryV1(options){let packageRoot=path181.resolve(options.packageRoot??options.projectRoot);await verifyBaseline(packageRoot,options.baselineSourceSha??PR_REVIEW_RECOVERY_BASE_SHA);let model=options.model??"configured",baseline=await candidate(packageRoot,{v:1,id:"pr-review-recovery-baseline",kind:"baseline",payloadPath:BASELINE_PAYLOAD_PATH,model,agent:"reviewer"}),current=await candidate(packageRoot,{v:1,id:"pr-review-recovery-candidate",kind:"skill",payloadPath:CANDIDATE_PAYLOAD_PATH,model,agent:"reviewer"}),budgets={maxTasks:1,maxRepetitions:1,maxConcurrency:1,maxTaskTimeMs:60000,maxRetries:0,maxOutputBytes:32768,...options.budgets};return runEvaluation({projectRoot:options.projectRoot,inputRoot:packageRoot,tasks:[await task(packageRoot)],baseline,candidate:current,split:"train",seed:options.seed??"pr-review-recovery-v1",models:[model],budgets,executor:createModelEvaluationExecutor(options.dispatcher,options.parentSessionId),abortSignal:options.abortSignal})}var PR_REVIEW_RECOVERY_BASE_SHA="3811fe5981072c7fa541523e9f08430f18594590",FIXTURE_ROOT="evaluation-fixtures/pr-review-recovery",BASELINE_MANIFEST_PATH,BASELINE_PAYLOAD_PATH,CANDIDATE_PAYLOAD_PATH=".opencode/skills/swarm-pr-review/SKILL.md",INSTRUCTION_PATH,ENVIRONMENT_PATH,SCORER_PATH;var init_pr_review_recovery=__esm(()=>{init_hashing();init_runner();BASELINE_MANIFEST_PATH=`${FIXTURE_ROOT}/baseline-manifest.json`,BASELINE_PAYLOAD_PATH=`${FIXTURE_ROOT}/baseline/SKILL.md`,INSTRUCTION_PATH=`${FIXTURE_ROOT}/instruction.md`,ENVIRONMENT_PATH=`${FIXTURE_ROOT}/environment`,SCORER_PATH=`${ENVIRONMENT_PATH}/score-recovery.cjs`});function normalize16(result){if(result.outcome!=="scored"||result.score===void 0)return;let[minimum,maximum]=result.scoreRange;if(maximum<=minimum||result.score<minimum||result.score>maximum)return;return(result.score-minimum)/(maximum-minimum)}function resultKey(result){return`${result.taskId}\x00${result.repetition}`}function collectPairs(candidateResults,referenceResults){let references=new Map(referenceResults.map((result)=>[resultKey(result),result])),pairs=[];for(let candidateResult of candidateResults){let referenceResult=references.get(resultKey(candidateResult));if(!referenceResult)continue;let candidate2=normalize16(candidateResult),reference=normalize16(referenceResult);if(candidate2===void 0||reference===void 0)continue;pairs.push({key:resultKey(candidateResult),category:candidateResult.category,protected:candidateResult.protected||referenceResult.protected,reference,candidate:candidate2,referenceResult,candidateResult})}return pairs.sort((left,right)=>left.key.localeCompare(right.key))}function mean(values){return values.length===0?0:values.reduce((total,value)=>total+value,0)/values.length}function seededRandom(seedHash){let state=Number.parseInt(seedHash.slice(0,8),16)>>>0;return()=>{state+=1831565813;let value=state;return value=Math.imul(value^value>>>15,value|1),value^=value+Math.imul(value^value>>>7,value|61),((value^value>>>14)>>>0)/4294967296}}function percentile(sorted,probability){if(sorted.length===0)return 0;let position=(sorted.length-1)*probability,lower=Math.floor(position),upper=Math.ceil(position);if(lower===upper)return sorted[lower]??0;let fraction=position-lower;return(sorted[lower]??0)*(1-fraction)+(sorted[upper]??0)*fraction}function pairedBootstrapConfidenceInterval(deltas,seedHash,resamples=1e4){if(deltas.length===0)return[0,0];let random=seededRandom(seedHash),estimates=Array(resamples);for(let sample=0;sample<resamples;sample++){let total=0;for(let index=0;index<deltas.length;index++)total+=deltas[Math.floor(random()*deltas.length)]??0;estimates[sample]=total/deltas.length}return estimates.sort((left,right)=>left-right),[percentile(estimates,0.025),percentile(estimates,0.975)]}function availableCosts(pairs){return pairs.every((pair)=>pair.candidateResult.cost.source!=="unavailable"&&pair.referenceResult.cost.source!=="unavailable")}function makeComparison(pairs,scheduledPairs,referenceRunId,referenceCandidateId,seedHash){let deltas=pairs.map((pair)=>pair.candidate-pair.reference);return{baselineRunId:referenceRunId,baselineCandidateId:referenceCandidateId,baselineMean:mean(pairs.map((pair)=>pair.reference)),candidateMean:mean(pairs.map((pair)=>pair.candidate)),pairedDelta:mean(deltas),confidenceInterval:pairedBootstrapConfidenceInterval(deltas,seedHash),validPairs:pairs.length,missingPairs:Math.max(0,scheduledPairs-pairs.length),coverage:scheduledPairs===0?0:Math.min(1,pairs.length/scheduledPairs)}}function decidePromotion(input){let run=input.run,policy=PromotionPolicyV1Schema.parse({v:1,...input.policy??{}}),policyHash=canonicalHash(policy),seedHash=sha2562(`${run.seed}${run.taskSet.contentHash}${run.baseline.contentHash}${run.candidate.contentHash}${policyHash}`),scheduledPairs=run.taskSet.taskIds.length*run.budgets.maxRepetitions,candidateResults=run.results.filter((result)=>result.candidateId===run.candidate.id),baselineResults=run.results.filter((result)=>result.candidateId===run.baseline.id),baselinePairs=collectPairs(candidateResults,baselineResults),historicalCompatible=input.historicalBest!==void 0&&input.historicalBest.taskSet.contentHash===run.taskSet.contentHash&&input.historicalBest.split===run.split,historicalResults=historicalCompatible?input.historicalBest?.results.filter((result)=>result.candidateId===input.historicalBest?.candidate.id):[],historicalPairs=collectPairs(candidateResults,historicalResults??[]),historicalSeed=sha2562(`${seedHash}:historical-best`),baseline=makeComparison(baselinePairs,scheduledPairs,run.runId,run.baseline.id,seedHash),historicalBest=makeComparison(historicalPairs,scheduledPairs,input.historicalBest?.runId??"unavailable",input.historicalBest?.candidate.id??"unavailable",historicalSeed),categories=[...new Set(baselinePairs.map((pair)=>pair.category))].sort().map((category)=>{let pairs=baselinePairs.filter((pair)=>pair.category===category),categoryProtected=pairs.some((pair)=>pair.protected),tolerance=policy.protectedCategoryTolerances[category]??0,baselineMean=mean(pairs.map((pair)=>pair.reference)),candidateMean=mean(pairs.map((pair)=>pair.candidate)),pairedDelta=candidateMean-baselineMean;return{category,protected:categoryProtected,tolerance,baselineMean,candidateMean,pairedDelta,regression:categoryProtected&&pairedDelta<-tolerance}}),reasons=[],status="inconclusive";if(!historicalCompatible)reasons.push("historical_best_incompatible_or_missing");if(baseline.validPairs<policy.minValidPairs)reasons.push("baseline_insufficient_valid_pairs");if(historicalBest.validPairs<policy.minValidPairs)reasons.push("historical_best_insufficient_valid_pairs");if(baseline.coverage<policy.minCoverage)reasons.push("baseline_insufficient_coverage");if(historicalBest.coverage<policy.minCoverage)reasons.push("historical_best_insufficient_coverage");if(policy.requireAvailableCosts&&(!availableCosts(baselinePairs)||!availableCosts(historicalPairs)||run.cost.source==="unavailable"||input.historicalBest?.cost.source==="unavailable"))reasons.push("promotion_cost_unavailable");let evidenceSufficient=reasons.length===0,protectedRegressions=categories.filter((category)=>category.regression);for(let category of protectedRegressions)reasons.push(`protected_category_regression:${category.category}`);let baselineDecisiveRegression=baseline.confidenceInterval[1]<-policy.deadband,historicalDecisiveRegression=historicalBest.confidenceInterval[1]<-policy.deadband;if(evidenceSufficient&&(baselineDecisiveRegression||historicalDecisiveRegression)){if(status="reject",baselineDecisiveRegression)reasons.push("decisive_regression:baseline");if(historicalDecisiveRegression)reasons.push("decisive_regression:historical_best")}else if(evidenceSufficient&&protectedRegressions.length>0)status="reject";else if(evidenceSufficient&&baseline.confidenceInterval[0]>policy.deadband&&historicalBest.confidenceInterval[0]>policy.deadband)status="accept",reasons.push("improvement_exceeds_deadband_for_baseline_and_historical_best");else if(evidenceSufficient)reasons.push("confidence_interval_overlaps_deadband");let historicalRun=input.historicalBest,decisionCore={runId:run.runId,status,reasons,baseline,historicalBest,deadband:policy.deadband,bootstrap:{resamples:1e4,confidence:0.95,seedHash},categories,lineage:{baselineRunId:run.runId,historicalBestRunId:historicalRun?.runId??"unavailable",taskSetHash:run.taskSet.contentHash,baselineHash:run.baseline.contentHash,candidateHash:run.candidate.contentHash,historicalBestHash:historicalRun?.candidate.contentHash??"0".repeat(64)},policyHash,unavailableQualityMetrics:["complexity_delta","public_api_delta"]};return PromotionDecisionV1Schema.parse({v:1,decisionId:`promotion-${canonicalHash(decisionCore)}`,decidedAt:input.decidedAt??new Date().toISOString(),...decisionCore})}var init_statistics=__esm(()=>{init_contracts();init_hashing()});async function evaluateCandidateV1(options){let run=await runEvaluation(options),decision=decidePromotion({run,historicalBest:options.historicalBest,policy:options.policy,decidedAt:options.decidedAt}),storedDecision=await savePromotionDecision(options.projectRoot,decision);return{run,decision:storedDecision}}var evaluationV1;var init_public_api=__esm(()=>{init_gate_ground_truth();init_hashing();init_pr_review_recovery();init_runner();init_statistics();init_store();evaluationV1=Object.freeze(Object.assign((options)=>evaluateCandidateV1(options),{evaluateCandidate:evaluateCandidateV1,evaluatePrReviewRecovery:evaluatePrReviewRecoveryV1,runEvaluation,decidePromotion:(input)=>decidePromotion(input),hashTaskInput:computeTaskInputContentHash,hashCandidateInput:computeCandidateInputContentHash,recordTestImpactGroundTruth:recordTestImpactGateGroundTruth}))});function buildGeneratorInputs(args2){for(let ev of args2.eligibleEvidence){if(args2.claimedTestTaskIds.has(ev.id))throw Error(`LEAKAGE_DETECTED: evidence id ${ev.id} is a held-out task`);let phraseFields=[...ev.triggers,...ev.requiredActions,...ev.forbiddenActions];for(let id of args2.claimedTestTaskIds){let escaped=id.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),re=new RegExp(`(^|[^A-Za-z0-9_-])${escaped}([^A-Za-z0-9_-]|$)`);for(let phrase of phraseFields)if(re.test(phrase))throw Error(`LEAKAGE_DETECTED: evidence ${ev.id} phrase references held-out task ${id}`)}}return{baselineContent:args2.baselineContent,eligibleEvidence:args2.eligibleEvidence,counterexamples:args2.counterexamples,budget:{maxChangedLines:args2.budget.max_changed_lines,maxChangedBytes:args2.budget.max_changed_bytes,maxChangedSections:args2.budget.max_changed_sections}}}function defaultDeterministicDraft(inputs){let baseline=inputs.baselineContent,evidenceLines=inputs.eligibleEvidence.slice(0,6).map((e)=>`- ${e.id} (confidence ${e.confidence.toFixed(2)}): triggers=${e.triggers.slice(0,3).join("; ")}`).join(`
2311
2311
  `),counterexampleNote=inputs.counterexamples.length>0?`
2312
2312
 
@@ -2320,16 +2320,16 @@ ${evidenceLines}${counterexampleNote}
2320
2320
 
2321
2321
  ${section}`,changedLines=countChangedLines(baseline,content),changedBytes=Buffer.byteLength(content,"utf8")-Buffer.byteLength(baseline,"utf8");return{content,diffSummary:{changedLines,changedBytes:Math.abs(changedBytes),changedSections:content.split(/^## /m).length-baseline.split(/^## /m).length},rationale:"deterministic seed from eligible evidence + rejection-ledger counterexamples",risks:["deterministic draft may underfit if evidence is sparse","supplemental LLM draft gated off (proposal-only)"],rollbackSnapshot:baseline,metric:{eligibilityScore:inputs.eligibleEvidence.reduce((s,e)=>s+e.confidence,0)}}}function enforceTrustRegion(candidate2,budget){let v=candidate2.diffSummary,breaches=[];if(v.changedLines>budget.maxChangedLines)breaches.push(`changedLines ${v.changedLines} > ${budget.maxChangedLines}`);if(v.changedBytes>budget.maxChangedBytes)breaches.push(`changedBytes ${v.changedBytes} > ${budget.maxChangedBytes}`);if(v.changedSections>budget.maxChangedSections)breaches.push(`changedSections ${v.changedSections} > ${budget.maxChangedSections}`);if(breaches.length>0)throw Error(`TrustRegionViolation: ${breaches.join("; ")}`)}function countChangedLines(a,b){let aLines=a.split(`
2322
2322
  `),bLines=b.split(`
2323
- `),max=Math.max(aLines.length,bLines.length),changed2=0;for(let i=0;i<max;i++)if(aLines[i]!==bLines[i])changed2++;return changed2}function draftCandidate(inputs){let candidate2=_internals143.draftDeterministic(inputs);return enforceTrustRegion(candidate2,inputs.budget),candidate2}var _internals143;var init_candidates=__esm(()=>{_internals143={draftDeterministic:defaultDeterministicDraft}});async function deterministicSeed(input){let entries=await selectCandidateEntries(input.directory,{minConfidence:input.minConfidence??DEFAULT_SKILL_MIN_CONFIDENCE,minConfirmations:input.minConfirmations??DEFAULT_SKILL_MIN_CONFIRMATIONS}),evidence2=[],filteredOut=0;for(let entry of entries){let triggers=(entry.triggers??[]).slice(0,8).map(String),requiredActions=(entry.required_actions??[]).slice(0,8).map(String),forbiddenActions=(entry.forbidden_actions??[]).slice(0,8).map(String);if(triggers.length===0&&requiredActions.length===0){filteredOut++;continue}evidence2.push({id:String(entry.id),triggers,requiredActions,forbiddenActions,confidence:typeof entry.confidence==="number"?entry.confidence:0})}let capped=evidence2.slice(0,24);return{evidence:capped,filteredOut:filteredOut+Math.max(0,evidence2.length-capped.length)}}var init_deterministic_seed=__esm(()=>{init_skill_generator()});import*as child_process9 from"node:child_process";function spawnAsync(command,cwd,timeoutMs){return new Promise((resolve74)=>{try{let[rawCmd,...args2]=command,cmd=process.platform==="win32"&&WIN32_CMD_BINARIES.has(rawCmd)&&!rawCmd.includes(".")?`${rawCmd}.cmd`:rawCmd,proc=_internals144.spawn(cmd,args2,{cwd,stdio:["ignore","pipe","pipe"]}),stdout="",stderr="",done=!1,MAX_OUTPUT=524288;proc.stdout.on("data",(d)=>{if(stdout.length<MAX_OUTPUT){if(stdout+=d,stdout.length>=MAX_OUTPUT){stdout=stdout.slice(0,MAX_OUTPUT);try{proc.stdout.destroy()}catch{}}}}),proc.stderr.on("data",(d)=>{if(stderr.length<MAX_OUTPUT){if(stderr+=d,stderr.length>=MAX_OUTPUT){stderr=stderr.slice(0,MAX_OUTPUT);try{proc.stderr.destroy()}catch{}}}});let timer=setTimeout(()=>{if(done)return;done=!0;try{proc.stdout.destroy()}catch{}try{proc.stderr.destroy()}catch{}try{proc.kill()}catch{}resolve74(null)},timeoutMs);proc.on("close",(code)=>{if(done)return;done=!0,clearTimeout(timer),resolve74({exitCode:code??1,stdout,stderr})}),proc.on("error",()=>{if(done)return;done=!0,clearTimeout(timer),resolve74(null)})}catch{resolve74(null)}})}var WIN32_CMD_BINARIES,_internals144;var init_spawn_helper=__esm(()=>{WIN32_CMD_BINARIES=new Set(["npm","npx","pnpm","yarn"]),_internals144={spawn:child_process9.spawn}});import{existsSync as existsSync91,lstatSync as lstatSync22,readFileSync as readFileSync70,realpathSync as realpathSync30}from"node:fs";import*as path182 from"node:path";async function validateSkillSmoke(input){let notes=[],repoRel=path182.join(".opencode","skills","generated",input.skillSlug,"SKILL.md");if(!_internals145.validateSkillPath(repoRel))return{ok:!1,verdict:"VIOLATED",notes:[`skill path not in an allowlisted root: ${repoRel}`]};let skillRoot=path182.join(input.directory,".opencode","skills","generated",input.skillSlug);if(existsSync91(skillRoot)){if(_internals145.isSymbolicLink(skillRoot))return{ok:!1,verdict:"VIOLATED",notes:["skill root is a symlink (reparse denied)"]};let realRoot=_internals145.realpath(skillRoot),realProjectDir=_internals145.realpath(input.directory);if(_internals145.escapedRoot(realProjectDir,realRoot))return{ok:!1,verdict:"VIOLATED",notes:["skill root escaped project root after realpath (reparse denied)"]}}let fmError=checkFrontmatter(input.candidateContent);if(fmError)return{ok:!1,verdict:"VIOLATED",notes:[`frontmatter: ${fmError}`]};if(await _internals145.isRejectedSkillContent(input.directory,input.skillSlug,input.candidateContent))return{ok:!1,verdict:"VIOLATED",notes:["candidate matches a previously-rejected edit (rejection ledger)"]};let evalResult=await _internals145.evaluateSkillChange({directory:input.directory,slug:input.skillSlug,candidateContent:input.candidateContent,incumbentContent:input.incumbentContent||void 0,operation:"skill-opt-smoke"});if(evalResult.status==="invalid_eval_set")notes.push(`invalid eval set: ${evalResult.reason}`);else if(evalResult.status==="rejected")return{ok:!1,verdict:"VIOLATED",notes:[`phrase-eval gate rejected: ${evalResult.reason}`]};else if(evalResult.status==="passed")notes.push(`phrase-eval passed (score ${evalResult.candidateScore.toFixed(2)})`);if(input.checkCommand&&input.checkCommand.length>0){let cmdResult=await _internals145.spawnAsync(input.checkCommand,input.directory,input.checkTimeoutMs??60000);if(!cmdResult||cmdResult.exitCode!==0)return{ok:!1,verdict:"VIOLATED",notes:[`check command exited ${cmdResult?cmdResult.exitCode:"null"}: ${(cmdResult?.stderr??"").slice(0,200)}`]};notes.push("check command passed")}return{ok:!0,verdict:"COMPLIANT",notes}}function checkFrontmatter(content){let match=/^---\n([\s\S]*?)\n---/.exec(content);if(!match)return"missing frontmatter block";let fm=match[1];if(!/^name:\s*\S/m.test(fm)&&!/^slug:\s*\S/m.test(fm))return"frontmatter missing name/slug";if(!/^description:\s*\S/m.test(fm))return"frontmatter missing description";return null}function readIncumbentContent(directory,skillSlug){let incumbent=path182.join(directory,".opencode","skills","generated",skillSlug,"SKILL.md");if(!existsSync91(incumbent))return"";try{return readFileSync70(incumbent,"utf8")}catch{return""}}var _internals145;var init_smoke=__esm(()=>{init_knowledge_validator();init_spawn_helper();init_skill_evaluator();_internals145={validateSkillPath,isSymbolicLink:(p)=>{try{return lstatSync22(p).isSymbolicLink()}catch{return!1}},escapedRoot:(root,target)=>{let rel=path182.relative(path182.resolve(root),path182.resolve(target));return rel.startsWith("..")||path182.isAbsolute(rel)},realpath:(p)=>realpathSync30(p),evaluateSkillChange,isRejectedSkillContent,spawnAsync}});import{randomUUID as randomUUID23}from"node:crypto";import{existsSync as existsSync92,mkdirSync as mkdirSync49,readFileSync as readFileSync71,writeFileSync as writeFileSync31}from"node:fs";import*as path183 from"node:path";async function prepareCandidatePayloads(inputRoot,candidateId2,skillSlug,baselineModel,candidateModel,baselineContent,candidateContent){let payloadSubdir=path183.join(inputRoot,"candidates",candidateId2);if(!existsSync92(payloadSubdir))mkdirSync49(payloadSubdir,{recursive:!0});let baselinePayloadRel=path183.join("candidates",candidateId2,"baseline.md"),candidatePayloadRel=path183.join("candidates",candidateId2,"candidate.md");writeFileSync31(path183.join(payloadSubdir,"baseline.md"),baselineContent,"utf8"),writeFileSync31(path183.join(payloadSubdir,"candidate.md"),candidateContent,"utf8");let{computeCandidateInputContentHash:computeCandidateInputContentHash2}=await Promise.resolve().then(() => (init_hashing(),exports_hashing)),baseline={v:1,id:`${skillSlug}-baseline`,kind:"skill",payloadPath:baselinePayloadRel,model:baselineModel,contentHash:""},candidate2={v:1,id:`${skillSlug}-candidate-${randomUUID23().slice(0,8)}`,kind:"skill",payloadPath:candidatePayloadRel,model:candidateModel,contentHash:""};return baseline.contentHash=await computeCandidateInputContentHash2(inputRoot,baseline),candidate2.contentHash=await computeCandidateInputContentHash2(inputRoot,candidate2),{baseline,candidate:candidate2}}async function acquireProjectLock(directory){assertProjectRoot(directory);let result=await _internals146.tryAcquireLock(directory,PROJECT_LOCK_PATH,"skill-opt-controller","project-run");if(!result.acquired)return null;return async()=>{if(result.lock._release)try{await result.lock._release()}catch{}}}async function acquireSkillLock(directory,skillSlug){assertProjectRoot(directory);let lockPath=path183.join(".swarm","evolution","skills",skillSlug,".skill.lock"),result=await _internals146.tryAcquireLock(directory,lockPath,"skill-opt-controller",`skill-${skillSlug}`);if(!result.acquired)return null;return async()=>{if(result.lock._release)try{await result.lock._release()}catch{}}}async function runOptimizationRound(input){let candidateId2=mintCandidateId(),releaseProject=await acquireProjectLock(input.directory);if(!releaseProject)return{candidateId:candidateId2,decidedState:"discovered",stopped:!0,stopReason:"project-run-locked"};let releaseSkill=await acquireSkillLock(input.directory,input.skillSlug);if(!releaseSkill)return await releaseProject(),{candidateId:candidateId2,decidedState:"discovered",stopped:!0,stopReason:`skill-locked:${input.skillSlug}`};try{return await runRoundLocked(input,candidateId2)}finally{await releaseSkill(),await releaseProject()}}async function runRoundLocked(input,candidateId2){let incumbent=readIncumbentContent(input.directory,input.skillSlug),baselineHash=computeContentHash2(incumbent);await recordTransition({directory:input.directory,skillSlug:input.skillSlug,candidateId:candidateId2,toState:"discovered",eventType:"discover",actor:input.sessionId??"unknown",origin:input.origin,reason:"optimization round started",contentHashBefore:baselineHash,contentHashAfter:baselineHash}),writeArtifact(input.directory,input.skillSlug,candidateId2,"baseline.md",incumbent);let seed=input.seedEvidence!==void 0?input.seedEvidence:(await deterministicSeed({directory:input.directory})).evidence,generatorInputs=buildGeneratorInputs({baselineContent:incumbent,eligibleEvidence:seed,counterexamples:[],budget:input.config,claimedTestTaskIds:input.claimedTestTaskIds??new Set}),candidate2=draftCandidate(generatorInputs);if(await recordTransition({directory:input.directory,skillSlug:input.skillSlug,candidateId:candidateId2,toState:"drafted",eventType:"draft",actor:input.sessionId??"unknown",origin:input.origin,reason:candidate2.rationale,contentHashBefore:baselineHash,contentHashAfter:computeContentHash2(candidate2.content),payload:{metric:candidate2.metric,risks:candidate2.risks,diffSummary:candidate2.diffSummary}}),candidate2.content===incumbent)return await recordTransition({directory:input.directory,skillSlug:input.skillSlug,candidateId:candidateId2,toState:"rejected",eventType:"equivalent-patch",actor:input.sessionId??"unknown",origin:input.origin,reason:"drafted candidate is identical to baseline (convergence)",contentHashBefore:baselineHash,contentHashAfter:computeContentHash2(candidate2.content)}),{candidateId:candidateId2,decidedState:"rejected",stopped:!0,stopReason:"equivalent-patch"};if(writeArtifact(input.directory,input.skillSlug,candidateId2,"candidate.md",candidate2.content),input.dryRun)return{candidateId:candidateId2,decidedState:"drafted",stopped:!1,stopReason:"dry-run"};let smoke=await validateSkillSmoke({directory:input.directory,skillSlug:input.skillSlug,candidateContent:candidate2.content,incumbentContent:incumbent});if(!smoke.ok)return await recordTransition({directory:input.directory,skillSlug:input.skillSlug,candidateId:candidateId2,toState:"rejected",eventType:"smoke-failed",actor:input.sessionId??"unknown",origin:input.origin,reason:smoke.notes.join("; "),contentHashBefore:baselineHash,contentHashAfter:computeContentHash2(candidate2.content)}),{candidateId:candidateId2,decidedState:"rejected",stopped:!1,stopReason:`smoke:${smoke.verdict}`};await recordTransition({directory:input.directory,skillSlug:input.skillSlug,candidateId:candidateId2,toState:"smoke_validated",eventType:"smoke-passed",actor:input.sessionId??"unknown",origin:input.origin,reason:smoke.notes.join("; "),contentHashBefore:baselineHash,contentHashAfter:computeContentHash2(candidate2.content)}),await recordTransition({directory:input.directory,skillSlug:input.skillSlug,candidateId:candidateId2,toState:"validation_running",eventType:"validation-start",actor:input.sessionId??"unknown",origin:input.origin,reason:"PR1 validation via evaluateCandidateV1 (split:test)",contentHashBefore:baselineHash,contentHashAfter:computeContentHash2(candidate2.content)});let decision=await runValidationWithTransientRetry(input,candidate2.content,incumbent,candidateId2),toState=decision.status==="accept"?"accepted_pending_approval":decision.status==="reject"?"rejected":"inconclusive";return await recordTransition({directory:input.directory,skillSlug:input.skillSlug,candidateId:candidateId2,toState,eventType:`validation-${decision.status}`,actor:input.sessionId??"unknown",origin:input.origin,reason:decision.reasons.join("; "),contentHashBefore:baselineHash,contentHashAfter:computeContentHash2(candidate2.content),evidenceRefs:decision.runId?[decision.runId]:[],payload:{deadband:decision.deadband,baselineRunId:decision.baselineRunId,historicalBestRunId:decision.historicalBestRunId}}),{candidateId:candidateId2,decidedState:toState,decision:decision.raw,run:decision.run,stopped:toState==="rejected"||toState==="inconclusive",stopReason:`decision:${decision.status}`,hardStop:decision.hardStop===!0}}async function runValidationWithTransientRetry(input,candidateContent,baselineContent,candidateId2){let transientRetries=0,maxRetries=input.config.max_transient_retries;while(!0)try{let evalInputRoot=input.inputRoot??input.directory,{baseline,candidate:candidate2}=await _internals146.prepareCandidatePayloads(evalInputRoot,candidateId2,input.skillSlug,input.baselineModel,input.candidateModel,baselineContent,candidateContent);if(!input.dispatcher)throw Error("no evaluation dispatcher available (cannot run validation)");let{createModelEvaluationExecutor:createModelEvaluationExecutor2}=await Promise.resolve().then(() => (init_runner(),exports_runner)),executor=createModelEvaluationExecutor2(input.dispatcher,input.sessionId),result=await _internals146.evaluateCandidateV1({projectRoot:input.directory,inputRoot:input.inputRoot??input.directory,tasks:input.validationTasks,baseline,candidate:candidate2,split:"test",seed:randomUUID23(),models:input.models,budgets:{maxTasks:input.config.max_validations_per_round*6,maxRepetitions:1,maxConcurrency:1,maxTaskTimeMs:input.config.max_round_time_ms,maxRetries:input.config.max_transient_retries,maxOutputBytes:524288},executor,abortSignal:input.abortSignal,policy:{deadband:input.config.deadband}});return{status:result.decision.status,reasons:result.decision.reasons,deadband:result.decision.deadband,runId:result.run.runId,baselineRunId:result.decision.lineage.baselineRunId,historicalBestRunId:result.decision.lineage.historicalBestRunId,raw:result.decision,run:result.run}}catch(err){let message=err instanceof Error?err.message:String(err);if((err instanceof Error?err.name:"")==="TestAlreadyConsumedError"||message.includes("TestAlreadyConsumed")||message.includes("test-already-consumed"))return{status:"inconclusive",reasons:[`held-out-test-set-already-consumed: ${message.slice(0,160)}`],deadband:input.config.deadband};let isTransient=message.includes("timeout")||message.includes("infrastructure_failure")||message.includes("temporarily unavailable")||message.includes("503")||message.includes("429");if(isTransient&&transientRetries<maxRetries){transientRetries++,await new Promise((r)=>setTimeout(r,200*2**transientRetries));continue}if(isTransient)return{status:"inconclusive",reasons:[`transient-infra-failure-after-${transientRetries}-retries: ${message.slice(0,160)}`],deadband:input.config.deadband};return _internals146.emitTelemetry?.("loop_detected",{skillSlug:input.skillSlug,reason:message.slice(0,160),source:"skill-opt-controller"}),{status:"inconclusive",reasons:[`non-transient-hard-stop: ${message.slice(0,160)}`],deadband:input.config.deadband,hardStop:!0}}}function readConvergenceState(directory){let file3=path183.join(directory,CONVERGENCE_FILE);if(!existsSync92(file3))return{nonImprovements:0};try{return JSON.parse(readFileSync71(file3,"utf8"))}catch{return{nonImprovements:0}}}function writeConvergenceState(directory,nonImprovements){assertProjectRoot(directory);let dir=path183.dirname(path183.join(directory,CONVERGENCE_FILE));if(!existsSync92(dir))mkdirSync49(dir,{recursive:!0});writeFileSync31(path183.join(directory,CONVERGENCE_FILE),JSON.stringify({nonImprovements}),"utf8")}async function runOptimizationLoop(input){let rounds=[],nonImprovements=readConvergenceState(input.directory).nonImprovements;for(let round=0;round<input.config.max_rounds;round++){let result=await runOptimizationRound(input);if(rounds.push(result),result.stopReason==="equivalent-patch")return writeConvergenceState(input.directory,++nonImprovements),{rounds,stopped:!0,stopReason:"equivalent-patch-convergence"};if(result.stopReason?.startsWith("skill-locked")||result.stopReason==="project-run-locked")return{rounds,stopped:!0,stopReason:result.stopReason};if(result.stopReason?.startsWith("smoke:")){if(writeConvergenceState(input.directory,++nonImprovements),nonImprovements>=input.config.convergence_non_improvements)return{rounds,stopped:!0,stopReason:`convergence-non-improvements:${nonImprovements}`};continue}if(result.hardStop)return{rounds,stopped:!0,stopReason:"non-transient-hard-stop"};if(result.decidedState==="accepted_pending_approval"||result.decidedState==="rejected"||result.decidedState==="inconclusive"){if(result.decidedState!=="accepted_pending_approval")writeConvergenceState(input.directory,++nonImprovements);else nonImprovements=0,writeConvergenceState(input.directory,nonImprovements);return{rounds,stopped:!0,stopReason:result.decidedState==="accepted_pending_approval"?"accepted-pending-approval":`validation-terminal:${result.decidedState}`}}}return{rounds,stopped:!0,stopReason:`max-rounds:${input.config.max_rounds}`}}var PROJECT_LOCK_PATH,CONVERGENCE_FILE,_internals146;var init_controller=__esm(()=>{init_public_api();init_file_locks();init_telemetry();init_project_boundary();init_candidates();init_deterministic_seed();init_lifecycle();init_smoke();init_store2();PROJECT_LOCK_PATH=path183.join(".swarm","evolution","skills",".run.lock"),CONVERGENCE_FILE=path183.join(".swarm","evolution","skills",".convergence.json");_internals146={tryAcquireLock,emitTelemetry:emit,evaluateCandidateV1,prepareCandidatePayloads}});import{existsSync as existsSync93,mkdirSync as mkdirSync50,writeFileSync as writeFileSync32}from"node:fs";import*as path184 from"node:path";function buildSkillEvalTasks(args2){let tasks=args2.tasks??DEFAULT_SKILL_EVAL_TASKS,result=[];for(let spec of tasks){let taskDir=path184.join(args2.inputRoot,"skill-eval",spec.id);if(!existsSync93(taskDir))mkdirSync50(taskDir,{recursive:!0});let instructionPath=path184.join("skill-eval",spec.id,"instruction.md");writeFileSync32(path184.join(args2.inputRoot,instructionPath),`${spec.instruction}
2323
+ `),max=Math.max(aLines.length,bLines.length),changed2=0;for(let i=0;i<max;i++)if(aLines[i]!==bLines[i])changed2++;return changed2}function draftCandidate(inputs){let candidate2=_internals143.draftDeterministic(inputs);return enforceTrustRegion(candidate2,inputs.budget),candidate2}var _internals143;var init_candidates=__esm(()=>{_internals143={draftDeterministic:defaultDeterministicDraft}});async function deterministicSeed(input){let entries=await selectCandidateEntries(input.directory,{minConfidence:input.minConfidence??DEFAULT_SKILL_MIN_CONFIDENCE,minConfirmations:input.minConfirmations??DEFAULT_SKILL_MIN_CONFIRMATIONS}),evidence2=[],filteredOut=0;for(let entry of entries){let triggers=(entry.triggers??[]).slice(0,8).map(String),requiredActions=(entry.required_actions??[]).slice(0,8).map(String),forbiddenActions=(entry.forbidden_actions??[]).slice(0,8).map(String);if(triggers.length===0&&requiredActions.length===0){filteredOut++;continue}evidence2.push({id:String(entry.id),triggers,requiredActions,forbiddenActions,confidence:typeof entry.confidence==="number"?entry.confidence:0})}let capped=evidence2.slice(0,24);return{evidence:capped,filteredOut:filteredOut+Math.max(0,evidence2.length-capped.length)}}var init_deterministic_seed=__esm(()=>{init_skill_generator()});import*as child_process9 from"node:child_process";function spawnAsync(command,cwd,timeoutMs){return new Promise((resolve74)=>{try{let[rawCmd,...args2]=command,cmd=process.platform==="win32"&&WIN32_CMD_BINARIES.has(rawCmd)&&!rawCmd.includes(".")?`${rawCmd}.cmd`:rawCmd,proc=_internals144.spawn(cmd,args2,{cwd,stdio:["ignore","pipe","pipe"]}),stdout="",stderr="",done=!1,MAX_OUTPUT=524288;proc.stdout.on("data",(d)=>{if(stdout.length<MAX_OUTPUT){if(stdout+=d,stdout.length>=MAX_OUTPUT){stdout=stdout.slice(0,MAX_OUTPUT);try{proc.stdout.destroy()}catch{}}}}),proc.stderr.on("data",(d)=>{if(stderr.length<MAX_OUTPUT){if(stderr+=d,stderr.length>=MAX_OUTPUT){stderr=stderr.slice(0,MAX_OUTPUT);try{proc.stderr.destroy()}catch{}}}});let timer=setTimeout(()=>{if(done)return;done=!0;try{proc.stdout.destroy()}catch{}try{proc.stderr.destroy()}catch{}try{proc.kill()}catch{}resolve74(null)},timeoutMs);proc.on("close",(code)=>{if(done)return;done=!0,clearTimeout(timer),resolve74({exitCode:code??1,stdout,stderr})}),proc.on("error",()=>{if(done)return;done=!0,clearTimeout(timer),resolve74(null)})}catch{resolve74(null)}})}var WIN32_CMD_BINARIES,_internals144;var init_spawn_helper=__esm(()=>{WIN32_CMD_BINARIES=new Set(["npm","npx","pnpm","yarn"]),_internals144={spawn:child_process9.spawn}});import{existsSync as existsSync92,lstatSync as lstatSync22,readFileSync as readFileSync70,realpathSync as realpathSync30}from"node:fs";import*as path182 from"node:path";async function validateSkillSmoke(input){let notes=[],repoRel=path182.join(".opencode","skills","generated",input.skillSlug,"SKILL.md");if(!_internals145.validateSkillPath(repoRel))return{ok:!1,verdict:"VIOLATED",notes:[`skill path not in an allowlisted root: ${repoRel}`]};let skillRoot=path182.join(input.directory,".opencode","skills","generated",input.skillSlug);if(existsSync92(skillRoot)){if(_internals145.isSymbolicLink(skillRoot))return{ok:!1,verdict:"VIOLATED",notes:["skill root is a symlink (reparse denied)"]};let realRoot=_internals145.realpath(skillRoot),realProjectDir=_internals145.realpath(input.directory);if(_internals145.escapedRoot(realProjectDir,realRoot))return{ok:!1,verdict:"VIOLATED",notes:["skill root escaped project root after realpath (reparse denied)"]}}let fmError=checkFrontmatter(input.candidateContent);if(fmError)return{ok:!1,verdict:"VIOLATED",notes:[`frontmatter: ${fmError}`]};if(await _internals145.isRejectedSkillContent(input.directory,input.skillSlug,input.candidateContent))return{ok:!1,verdict:"VIOLATED",notes:["candidate matches a previously-rejected edit (rejection ledger)"]};let evalResult=await _internals145.evaluateSkillChange({directory:input.directory,slug:input.skillSlug,candidateContent:input.candidateContent,incumbentContent:input.incumbentContent||void 0,operation:"skill-opt-smoke"});if(evalResult.status==="invalid_eval_set")notes.push(`invalid eval set: ${evalResult.reason}`);else if(evalResult.status==="rejected")return{ok:!1,verdict:"VIOLATED",notes:[`phrase-eval gate rejected: ${evalResult.reason}`]};else if(evalResult.status==="passed")notes.push(`phrase-eval passed (score ${evalResult.candidateScore.toFixed(2)})`);if(input.checkCommand&&input.checkCommand.length>0){let cmdResult=await _internals145.spawnAsync(input.checkCommand,input.directory,input.checkTimeoutMs??60000);if(!cmdResult||cmdResult.exitCode!==0)return{ok:!1,verdict:"VIOLATED",notes:[`check command exited ${cmdResult?cmdResult.exitCode:"null"}: ${(cmdResult?.stderr??"").slice(0,200)}`]};notes.push("check command passed")}return{ok:!0,verdict:"COMPLIANT",notes}}function checkFrontmatter(content){let match=/^---\n([\s\S]*?)\n---/.exec(content);if(!match)return"missing frontmatter block";let fm=match[1];if(!/^name:\s*\S/m.test(fm)&&!/^slug:\s*\S/m.test(fm))return"frontmatter missing name/slug";if(!/^description:\s*\S/m.test(fm))return"frontmatter missing description";return null}function readIncumbentContent(directory,skillSlug){let incumbent=path182.join(directory,".opencode","skills","generated",skillSlug,"SKILL.md");if(!existsSync92(incumbent))return"";try{return readFileSync70(incumbent,"utf8")}catch{return""}}var _internals145;var init_smoke=__esm(()=>{init_knowledge_validator();init_spawn_helper();init_skill_evaluator();_internals145={validateSkillPath,isSymbolicLink:(p)=>{try{return lstatSync22(p).isSymbolicLink()}catch{return!1}},escapedRoot:(root,target)=>{let rel=path182.relative(path182.resolve(root),path182.resolve(target));return rel.startsWith("..")||path182.isAbsolute(rel)},realpath:(p)=>realpathSync30(p),evaluateSkillChange,isRejectedSkillContent,spawnAsync}});import{randomUUID as randomUUID23}from"node:crypto";import{existsSync as existsSync93,mkdirSync as mkdirSync49,readFileSync as readFileSync71,writeFileSync as writeFileSync31}from"node:fs";import*as path183 from"node:path";async function prepareCandidatePayloads(inputRoot,candidateId2,skillSlug,baselineModel,candidateModel,baselineContent,candidateContent){let payloadSubdir=path183.join(inputRoot,"candidates",candidateId2);if(!existsSync93(payloadSubdir))mkdirSync49(payloadSubdir,{recursive:!0});let baselinePayloadRel=path183.join("candidates",candidateId2,"baseline.md"),candidatePayloadRel=path183.join("candidates",candidateId2,"candidate.md");writeFileSync31(path183.join(payloadSubdir,"baseline.md"),baselineContent,"utf8"),writeFileSync31(path183.join(payloadSubdir,"candidate.md"),candidateContent,"utf8");let{computeCandidateInputContentHash:computeCandidateInputContentHash2}=await Promise.resolve().then(() => (init_hashing(),exports_hashing)),baseline={v:1,id:`${skillSlug}-baseline`,kind:"skill",payloadPath:baselinePayloadRel,model:baselineModel,contentHash:""},candidate2={v:1,id:`${skillSlug}-candidate-${randomUUID23().slice(0,8)}`,kind:"skill",payloadPath:candidatePayloadRel,model:candidateModel,contentHash:""};return baseline.contentHash=await computeCandidateInputContentHash2(inputRoot,baseline),candidate2.contentHash=await computeCandidateInputContentHash2(inputRoot,candidate2),{baseline,candidate:candidate2}}async function acquireProjectLock(directory){assertProjectRoot(directory);let result=await _internals146.tryAcquireLock(directory,PROJECT_LOCK_PATH,"skill-opt-controller","project-run");if(!result.acquired)return null;return async()=>{if(result.lock._release)try{await result.lock._release()}catch{}}}async function acquireSkillLock(directory,skillSlug){assertProjectRoot(directory);let lockPath=path183.join(".swarm","evolution","skills",skillSlug,".skill.lock"),result=await _internals146.tryAcquireLock(directory,lockPath,"skill-opt-controller",`skill-${skillSlug}`);if(!result.acquired)return null;return async()=>{if(result.lock._release)try{await result.lock._release()}catch{}}}async function runOptimizationRound(input){let candidateId2=mintCandidateId(),releaseProject=await acquireProjectLock(input.directory);if(!releaseProject)return{candidateId:candidateId2,decidedState:"discovered",stopped:!0,stopReason:"project-run-locked"};let releaseSkill=await acquireSkillLock(input.directory,input.skillSlug);if(!releaseSkill)return await releaseProject(),{candidateId:candidateId2,decidedState:"discovered",stopped:!0,stopReason:`skill-locked:${input.skillSlug}`};try{return await runRoundLocked(input,candidateId2)}finally{await releaseSkill(),await releaseProject()}}async function runRoundLocked(input,candidateId2){let incumbent=readIncumbentContent(input.directory,input.skillSlug),baselineHash=computeContentHash2(incumbent);await recordTransition({directory:input.directory,skillSlug:input.skillSlug,candidateId:candidateId2,toState:"discovered",eventType:"discover",actor:input.sessionId??"unknown",origin:input.origin,reason:"optimization round started",contentHashBefore:baselineHash,contentHashAfter:baselineHash}),writeArtifact(input.directory,input.skillSlug,candidateId2,"baseline.md",incumbent);let seed=input.seedEvidence!==void 0?input.seedEvidence:(await deterministicSeed({directory:input.directory})).evidence,generatorInputs=buildGeneratorInputs({baselineContent:incumbent,eligibleEvidence:seed,counterexamples:[],budget:input.config,claimedTestTaskIds:input.claimedTestTaskIds??new Set}),candidate2=draftCandidate(generatorInputs);if(await recordTransition({directory:input.directory,skillSlug:input.skillSlug,candidateId:candidateId2,toState:"drafted",eventType:"draft",actor:input.sessionId??"unknown",origin:input.origin,reason:candidate2.rationale,contentHashBefore:baselineHash,contentHashAfter:computeContentHash2(candidate2.content),payload:{metric:candidate2.metric,risks:candidate2.risks,diffSummary:candidate2.diffSummary}}),candidate2.content===incumbent)return await recordTransition({directory:input.directory,skillSlug:input.skillSlug,candidateId:candidateId2,toState:"rejected",eventType:"equivalent-patch",actor:input.sessionId??"unknown",origin:input.origin,reason:"drafted candidate is identical to baseline (convergence)",contentHashBefore:baselineHash,contentHashAfter:computeContentHash2(candidate2.content)}),{candidateId:candidateId2,decidedState:"rejected",stopped:!0,stopReason:"equivalent-patch"};if(writeArtifact(input.directory,input.skillSlug,candidateId2,"candidate.md",candidate2.content),input.dryRun)return{candidateId:candidateId2,decidedState:"drafted",stopped:!1,stopReason:"dry-run"};let smoke=await validateSkillSmoke({directory:input.directory,skillSlug:input.skillSlug,candidateContent:candidate2.content,incumbentContent:incumbent});if(!smoke.ok)return await recordTransition({directory:input.directory,skillSlug:input.skillSlug,candidateId:candidateId2,toState:"rejected",eventType:"smoke-failed",actor:input.sessionId??"unknown",origin:input.origin,reason:smoke.notes.join("; "),contentHashBefore:baselineHash,contentHashAfter:computeContentHash2(candidate2.content)}),{candidateId:candidateId2,decidedState:"rejected",stopped:!1,stopReason:`smoke:${smoke.verdict}`};await recordTransition({directory:input.directory,skillSlug:input.skillSlug,candidateId:candidateId2,toState:"smoke_validated",eventType:"smoke-passed",actor:input.sessionId??"unknown",origin:input.origin,reason:smoke.notes.join("; "),contentHashBefore:baselineHash,contentHashAfter:computeContentHash2(candidate2.content)}),await recordTransition({directory:input.directory,skillSlug:input.skillSlug,candidateId:candidateId2,toState:"validation_running",eventType:"validation-start",actor:input.sessionId??"unknown",origin:input.origin,reason:"PR1 validation via evaluateCandidateV1 (split:test)",contentHashBefore:baselineHash,contentHashAfter:computeContentHash2(candidate2.content)});let decision=await runValidationWithTransientRetry(input,candidate2.content,incumbent,candidateId2),toState=decision.status==="accept"?"accepted_pending_approval":decision.status==="reject"?"rejected":"inconclusive";return await recordTransition({directory:input.directory,skillSlug:input.skillSlug,candidateId:candidateId2,toState,eventType:`validation-${decision.status}`,actor:input.sessionId??"unknown",origin:input.origin,reason:decision.reasons.join("; "),contentHashBefore:baselineHash,contentHashAfter:computeContentHash2(candidate2.content),evidenceRefs:decision.runId?[decision.runId]:[],payload:{deadband:decision.deadband,baselineRunId:decision.baselineRunId,historicalBestRunId:decision.historicalBestRunId}}),{candidateId:candidateId2,decidedState:toState,decision:decision.raw,run:decision.run,stopped:toState==="rejected"||toState==="inconclusive",stopReason:`decision:${decision.status}`,hardStop:decision.hardStop===!0}}async function runValidationWithTransientRetry(input,candidateContent,baselineContent,candidateId2){let transientRetries=0,maxRetries=input.config.max_transient_retries;while(!0)try{let evalInputRoot=input.inputRoot??input.directory,{baseline,candidate:candidate2}=await _internals146.prepareCandidatePayloads(evalInputRoot,candidateId2,input.skillSlug,input.baselineModel,input.candidateModel,baselineContent,candidateContent);if(!input.dispatcher)throw Error("no evaluation dispatcher available (cannot run validation)");let{createModelEvaluationExecutor:createModelEvaluationExecutor2}=await Promise.resolve().then(() => (init_runner(),exports_runner)),executor=createModelEvaluationExecutor2(input.dispatcher,input.sessionId),result=await _internals146.evaluateCandidateV1({projectRoot:input.directory,inputRoot:input.inputRoot??input.directory,tasks:input.validationTasks,baseline,candidate:candidate2,split:"test",seed:randomUUID23(),models:input.models,budgets:{maxTasks:input.config.max_validations_per_round*6,maxRepetitions:1,maxConcurrency:1,maxTaskTimeMs:input.config.max_round_time_ms,maxRetries:input.config.max_transient_retries,maxOutputBytes:524288},executor,abortSignal:input.abortSignal,policy:{deadband:input.config.deadband}});return{status:result.decision.status,reasons:result.decision.reasons,deadband:result.decision.deadband,runId:result.run.runId,baselineRunId:result.decision.lineage.baselineRunId,historicalBestRunId:result.decision.lineage.historicalBestRunId,raw:result.decision,run:result.run}}catch(err){let message=err instanceof Error?err.message:String(err);if((err instanceof Error?err.name:"")==="TestAlreadyConsumedError"||message.includes("TestAlreadyConsumed")||message.includes("test-already-consumed"))return{status:"inconclusive",reasons:[`held-out-test-set-already-consumed: ${message.slice(0,160)}`],deadband:input.config.deadband};let isTransient=message.includes("timeout")||message.includes("infrastructure_failure")||message.includes("temporarily unavailable")||message.includes("503")||message.includes("429");if(isTransient&&transientRetries<maxRetries){transientRetries++,await new Promise((r)=>setTimeout(r,200*2**transientRetries));continue}if(isTransient)return{status:"inconclusive",reasons:[`transient-infra-failure-after-${transientRetries}-retries: ${message.slice(0,160)}`],deadband:input.config.deadband};return _internals146.emitTelemetry?.("loop_detected",{skillSlug:input.skillSlug,reason:message.slice(0,160),source:"skill-opt-controller"}),{status:"inconclusive",reasons:[`non-transient-hard-stop: ${message.slice(0,160)}`],deadband:input.config.deadband,hardStop:!0}}}function readConvergenceState(directory){let file3=path183.join(directory,CONVERGENCE_FILE);if(!existsSync93(file3))return{nonImprovements:0};try{return JSON.parse(readFileSync71(file3,"utf8"))}catch{return{nonImprovements:0}}}function writeConvergenceState(directory,nonImprovements){assertProjectRoot(directory);let dir=path183.dirname(path183.join(directory,CONVERGENCE_FILE));if(!existsSync93(dir))mkdirSync49(dir,{recursive:!0});writeFileSync31(path183.join(directory,CONVERGENCE_FILE),JSON.stringify({nonImprovements}),"utf8")}async function runOptimizationLoop(input){let rounds=[],nonImprovements=readConvergenceState(input.directory).nonImprovements;for(let round=0;round<input.config.max_rounds;round++){let result=await runOptimizationRound(input);if(rounds.push(result),result.stopReason==="equivalent-patch")return writeConvergenceState(input.directory,++nonImprovements),{rounds,stopped:!0,stopReason:"equivalent-patch-convergence"};if(result.stopReason?.startsWith("skill-locked")||result.stopReason==="project-run-locked")return{rounds,stopped:!0,stopReason:result.stopReason};if(result.stopReason?.startsWith("smoke:")){if(writeConvergenceState(input.directory,++nonImprovements),nonImprovements>=input.config.convergence_non_improvements)return{rounds,stopped:!0,stopReason:`convergence-non-improvements:${nonImprovements}`};continue}if(result.hardStop)return{rounds,stopped:!0,stopReason:"non-transient-hard-stop"};if(result.decidedState==="accepted_pending_approval"||result.decidedState==="rejected"||result.decidedState==="inconclusive"){if(result.decidedState!=="accepted_pending_approval")writeConvergenceState(input.directory,++nonImprovements);else nonImprovements=0,writeConvergenceState(input.directory,nonImprovements);return{rounds,stopped:!0,stopReason:result.decidedState==="accepted_pending_approval"?"accepted-pending-approval":`validation-terminal:${result.decidedState}`}}}return{rounds,stopped:!0,stopReason:`max-rounds:${input.config.max_rounds}`}}var PROJECT_LOCK_PATH,CONVERGENCE_FILE,_internals146;var init_controller=__esm(()=>{init_public_api();init_file_locks();init_telemetry();init_project_boundary();init_candidates();init_deterministic_seed();init_lifecycle();init_smoke();init_store2();PROJECT_LOCK_PATH=path183.join(".swarm","evolution","skills",".run.lock"),CONVERGENCE_FILE=path183.join(".swarm","evolution","skills",".convergence.json");_internals146={tryAcquireLock,emitTelemetry:emit,evaluateCandidateV1,prepareCandidatePayloads}});import{existsSync as existsSync94,mkdirSync as mkdirSync50,writeFileSync as writeFileSync32}from"node:fs";import*as path184 from"node:path";function buildSkillEvalTasks(args2){let tasks=args2.tasks??DEFAULT_SKILL_EVAL_TASKS,result=[];for(let spec of tasks){let taskDir=path184.join(args2.inputRoot,"skill-eval",spec.id);if(!existsSync94(taskDir))mkdirSync50(taskDir,{recursive:!0});let instructionPath=path184.join("skill-eval",spec.id,"instruction.md");writeFileSync32(path184.join(args2.inputRoot,instructionPath),`${spec.instruction}
2324
2324
  `,"utf8");let envRelPath=path184.join("skill-eval",spec.id,"environment.md");writeFileSync32(path184.join(args2.inputRoot,envRelPath),spec.environmentBody,"utf8");let phraseSpecPath=path184.join("skill-eval",spec.id,"phrase-spec.json");writeFileSync32(path184.join(args2.inputRoot,phraseSpecPath),JSON.stringify({required_phrases:spec.requiredPhrases,forbidden_phrases:spec.forbiddenPhrases}),"utf8");let task2={v:1,id:spec.id,source:"curated",split:"test",category:spec.category,protected:spec.protected??!1,instructionPath,environment:{kind:"fixture",path:envRelPath},scorer:{kind:"project",argv:[args2.scorerRelPath,phraseSpecPath],timeoutMs:15000,scoreRange:[0,1]},provenance:{origin:"opencode-swarm skill-opt default skill-eval set (issue #1822)",license:"MIT",collectedAt:"2026-07-13T00:00:00Z",review:{reviewer:"opencode-swarm team",reviewedAt:"2026-07-13T00:00:00Z",instruction:!0,fixture:!0,scorer:!0,secretsPrivacy:!0,license:!0,split:!0}},contentHash:""};task2.contentHash=computeTaskContentHash(task2),result.push(task2)}return result}var DEFAULT_SKILL_EVAL_TASKS;var init_skill_eval_tasks=__esm(()=>{init_hashing();DEFAULT_SKILL_EVAL_TASKS=[{id:"skill-eval-trigger-clarity",category:"clarity",protected:!1,instruction:"Read the candidate SKILL.md and confirm it declares a clear trigger condition. Return the trigger verbatim.",requiredPhrases:["trigger","when"],forbiddenPhrases:["maybe","sometimes"],environmentBody:`## Trigger
2325
2325
 
2326
2326
  When the agent is about to delegate a coding task.`},{id:"skill-eval-required-actions",category:"completeness",protected:!0,instruction:"Read the candidate SKILL.md and confirm it lists the required actions an agent must take. Return them verbatim.",requiredPhrases:["required","must"],forbiddenPhrases:["shortcut","skip"],environmentBody:`## Required Procedure
2327
2327
 
2328
2328
  1. Confirm scope. 2. Delegate. 3. Verify.`},{id:"skill-eval-reviewer-checks",category:"safety",protected:!0,instruction:"Read the candidate SKILL.md and confirm it specifies reviewer checks. Return them verbatim.",requiredPhrases:["reviewer","check"],forbiddenPhrases:["trust","assume"],environmentBody:`## Reviewer Checks
2329
2329
 
2330
- - Scope matches. - Tests pass.`}]});import{copyFileSync as copyFileSync6,existsSync as existsSync94,mkdirSync as mkdirSync51,readFileSync as readFileSync72}from"node:fs";import*as path185 from"node:path";function validateIds(skillSlug,candidateId2,json3){if(!isValidSkillSlug(skillSlug))return emit2({status:"error",error:`invalid skill slug: ${skillSlug}`},json3);if(candidateId2!==void 0&&!isValidCandidateId(candidateId2))return emit2({status:"error",error:`invalid candidate id: ${candidateId2}`},json3);return null}function resolveSkillOptConfig(input){if(input===void 0||input===null||typeof input!=="object"||Array.isArray(input))return{...DEFAULT_SKILL_OPT_CONFIG};return{...DEFAULT_SKILL_OPT_CONFIG,...input}}function parseSkillOptArgs(args2){let json3=args2.includes("--json"),confirm=args2.includes("--confirm"),dryRun=args2.includes("--dry-run")||args2.includes("--plan"),positional=args2.filter((a)=>!a.startsWith("--")),skillSlug=positional[0]??"",candidateId2=positional[1],hashIdx=args2.indexOf("--expected-content-hash"),expectedContentHash=hashIdx>=0?args2[hashIdx+1]:void 0,modelsIdx=args2.indexOf("--models"),modelsArg=modelsIdx>=0?args2[modelsIdx+1]:void 0,models=modelsArg?modelsArg.split(",").map((s)=>s.trim()).filter(Boolean):[];return{json:json3,confirm,skillSlug,candidateId:candidateId2,expectedContentHash,models,dryRun}}function emit2(result,json3){if(json3)return JSON.stringify(result,null,2);return`\`\`\`json
2330
+ - Scope matches. - Tests pass.`}]});import{copyFileSync as copyFileSync6,existsSync as existsSync95,mkdirSync as mkdirSync51,readFileSync as readFileSync72}from"node:fs";import*as path185 from"node:path";function validateIds(skillSlug,candidateId2,json3){if(!isValidSkillSlug(skillSlug))return emit2({status:"error",error:`invalid skill slug: ${skillSlug}`},json3);if(candidateId2!==void 0&&!isValidCandidateId(candidateId2))return emit2({status:"error",error:`invalid candidate id: ${candidateId2}`},json3);return null}function resolveSkillOptConfig(input){if(input===void 0||input===null||typeof input!=="object"||Array.isArray(input))return{...DEFAULT_SKILL_OPT_CONFIG};return{...DEFAULT_SKILL_OPT_CONFIG,...input}}function parseSkillOptArgs(args2){let json3=args2.includes("--json"),confirm=args2.includes("--confirm"),dryRun=args2.includes("--dry-run")||args2.includes("--plan"),positional=args2.filter((a)=>!a.startsWith("--")),skillSlug=positional[0]??"",candidateId2=positional[1],hashIdx=args2.indexOf("--expected-content-hash"),expectedContentHash=hashIdx>=0?args2[hashIdx+1]:void 0,modelsIdx=args2.indexOf("--models"),modelsArg=modelsIdx>=0?args2[modelsIdx+1]:void 0,models=modelsArg?modelsArg.split(",").map((s)=>s.trim()).filter(Boolean):[];return{json:json3,confirm,skillSlug,candidateId:candidateId2,expectedContentHash,models,dryRun}}function emit2(result,json3){if(json3)return JSON.stringify(result,null,2);return`\`\`\`json
2331
2331
  ${JSON.stringify(result,null,2)}
2332
- \`\`\``}function readSkillOptConfigFromProject(directory){try{let cfgPath=path185.join(directory,"opencode.json");if(!existsSync94(cfgPath))return{...DEFAULT_SKILL_OPT_CONFIG};let raw=JSON.parse(readFileSync72(cfgPath,"utf8")),block=raw?.skill_opt??raw?.swarm?.skill_opt;return resolveSkillOptConfig(block)}catch{return{...DEFAULT_SKILL_OPT_CONFIG}}}async function handleSkillOptPlan(directory,args2,runtime={}){let parsed=parseSkillOptArgs(args2);if(!parsed.skillSlug)return emit2({status:"error",error:"missing skill slug"},parsed.json);let config3=runtime.config??readSkillOptConfigFromProject(directory),models=parsed.models.length>0?parsed.models:["default"],result=await runOptimizationRound({directory,skillSlug:parsed.skillSlug,config:config3,sessionId:runtime.parentSessionId,dispatcher:runtime.dispatcher,models,validationTasks:[],inputRoot:directory,baselineModel:models[0],candidateModel:models[0],origin:"command:skill-opt:plan",dryRun:!0});return emit2({status:"ok",...result,dryRun:!0},parsed.json)}async function handleSkillOptRun(directory,args2,runtime={}){let parsed=parseSkillOptArgs(args2);if(!parsed.skillSlug)return emit2({status:"error",error:"missing skill slug"},parsed.json);let config3=runtime.config??readSkillOptConfigFromProject(directory);if(!config3.enabled)return emit2({status:"disabled",error:"skill_opt.enabled is false — set to true to execute rounds (proposal-only by default)"},parsed.json);if(!parsed.confirm)return emit2({status:"needs-confirm",error:"pass --confirm to execute a round (this consumes a held-out test set)"},parsed.json);let models=parsed.models.length>0?parsed.models:["default"],inputRoot=path185.join(directory,".swarm","evolution","skills","_eval-input");if(!existsSync94(inputRoot))mkdirSync51(inputRoot,{recursive:!0});let scorerDir=path185.join(inputRoot,"scoring");if(!existsSync94(scorerDir))mkdirSync51(scorerDir,{recursive:!0});let scorerSource=path185.join(directory,"evaluation-fixtures","skill-eval","scoring","score-skill-eval.cjs"),scorerDest=path185.join(scorerDir,"score-skill-eval.cjs");if(existsSync94(scorerSource))copyFileSync6(scorerSource,scorerDest);let scorerRelPath=path185.join("scoring","score-skill-eval.cjs"),validationTasks=buildSkillEvalTasks({inputRoot,scorerRelPath}),result=await runOptimizationLoop({directory,skillSlug:parsed.skillSlug,config:config3,sessionId:runtime.parentSessionId,dispatcher:runtime.dispatcher,models,validationTasks,inputRoot,baselineModel:models[0],candidateModel:models[0],origin:"command:skill-opt:run"});return emit2({status:"ok",...result},parsed.json)}async function handleSkillOptStatus(directory,args2){let parsed=parseSkillOptArgs(args2);if(!parsed.skillSlug)return emit2({status:"error",error:"missing skill slug"},parsed.json);let candidateId2=parsed.candidateId;if(!candidateId2)return emit2({status:"error",error:"missing candidateId (usage: status <slug> <candidateId>)"},parsed.json);let idError=validateIds(parsed.skillSlug,candidateId2,parsed.json);if(idError)return idError;let state=currentCandidateState(directory,parsed.skillSlug,candidateId2);return emit2({status:"ok",skillSlug:parsed.skillSlug,candidateId:candidateId2,...state},parsed.json)}async function handleSkillOptDiff(directory,args2){let parsed=parseSkillOptArgs(args2);if(!parsed.skillSlug||!parsed.candidateId)return emit2({status:"error",error:"usage: diff <slug> <candidateId>"},parsed.json);let idError=validateIds(parsed.skillSlug,parsed.candidateId,parsed.json);if(idError)return idError;let baseline=readArtifact(directory,parsed.skillSlug,parsed.candidateId,"baseline.md")??"",candidate2=readArtifact(directory,parsed.skillSlug,parsed.candidateId,"candidate.md")??"",replay=replayCandidate(directory,parsed.skillSlug,parsed.candidateId),baselineLines=baseline.split(`
2332
+ \`\`\``}function readSkillOptConfigFromProject(directory){try{let cfgPath=path185.join(directory,"opencode.json");if(!existsSync95(cfgPath))return{...DEFAULT_SKILL_OPT_CONFIG};let raw=JSON.parse(readFileSync72(cfgPath,"utf8")),block=raw?.skill_opt??raw?.swarm?.skill_opt;return resolveSkillOptConfig(block)}catch{return{...DEFAULT_SKILL_OPT_CONFIG}}}async function handleSkillOptPlan(directory,args2,runtime={}){let parsed=parseSkillOptArgs(args2);if(!parsed.skillSlug)return emit2({status:"error",error:"missing skill slug"},parsed.json);let config3=runtime.config??readSkillOptConfigFromProject(directory),models=parsed.models.length>0?parsed.models:["default"],result=await runOptimizationRound({directory,skillSlug:parsed.skillSlug,config:config3,sessionId:runtime.parentSessionId,dispatcher:runtime.dispatcher,models,validationTasks:[],inputRoot:directory,baselineModel:models[0],candidateModel:models[0],origin:"command:skill-opt:plan",dryRun:!0});return emit2({status:"ok",...result,dryRun:!0},parsed.json)}async function handleSkillOptRun(directory,args2,runtime={}){let parsed=parseSkillOptArgs(args2);if(!parsed.skillSlug)return emit2({status:"error",error:"missing skill slug"},parsed.json);let config3=runtime.config??readSkillOptConfigFromProject(directory);if(!config3.enabled)return emit2({status:"disabled",error:"skill_opt.enabled is false — set to true to execute rounds (proposal-only by default)"},parsed.json);if(!parsed.confirm)return emit2({status:"needs-confirm",error:"pass --confirm to execute a round (this consumes a held-out test set)"},parsed.json);let models=parsed.models.length>0?parsed.models:["default"],inputRoot=path185.join(directory,".swarm","evolution","skills","_eval-input");if(!existsSync95(inputRoot))mkdirSync51(inputRoot,{recursive:!0});let scorerDir=path185.join(inputRoot,"scoring");if(!existsSync95(scorerDir))mkdirSync51(scorerDir,{recursive:!0});let scorerSource=path185.join(directory,"evaluation-fixtures","skill-eval","scoring","score-skill-eval.cjs"),scorerDest=path185.join(scorerDir,"score-skill-eval.cjs");if(existsSync95(scorerSource))copyFileSync6(scorerSource,scorerDest);let scorerRelPath=path185.join("scoring","score-skill-eval.cjs"),validationTasks=buildSkillEvalTasks({inputRoot,scorerRelPath}),result=await runOptimizationLoop({directory,skillSlug:parsed.skillSlug,config:config3,sessionId:runtime.parentSessionId,dispatcher:runtime.dispatcher,models,validationTasks,inputRoot,baselineModel:models[0],candidateModel:models[0],origin:"command:skill-opt:run"});return emit2({status:"ok",...result},parsed.json)}async function handleSkillOptStatus(directory,args2){let parsed=parseSkillOptArgs(args2);if(!parsed.skillSlug)return emit2({status:"error",error:"missing skill slug"},parsed.json);let candidateId2=parsed.candidateId;if(!candidateId2)return emit2({status:"error",error:"missing candidateId (usage: status <slug> <candidateId>)"},parsed.json);let idError=validateIds(parsed.skillSlug,candidateId2,parsed.json);if(idError)return idError;let state=currentCandidateState(directory,parsed.skillSlug,candidateId2);return emit2({status:"ok",skillSlug:parsed.skillSlug,candidateId:candidateId2,...state},parsed.json)}async function handleSkillOptDiff(directory,args2){let parsed=parseSkillOptArgs(args2);if(!parsed.skillSlug||!parsed.candidateId)return emit2({status:"error",error:"usage: diff <slug> <candidateId>"},parsed.json);let idError=validateIds(parsed.skillSlug,parsed.candidateId,parsed.json);if(idError)return idError;let baseline=readArtifact(directory,parsed.skillSlug,parsed.candidateId,"baseline.md")??"",candidate2=readArtifact(directory,parsed.skillSlug,parsed.candidateId,"candidate.md")??"",replay=replayCandidate(directory,parsed.skillSlug,parsed.candidateId),baselineLines=baseline.split(`
2333
2333
  `),candidateLines=candidate2.split(`
2334
2334
  `),max=Math.max(baselineLines.length,candidateLines.length),added=0,removed=0;for(let i=0;i<max;i++)if(baselineLines[i]!==candidateLines[i])if(i>=baselineLines.length)added++;else if(i>=candidateLines.length)removed++;else added++,removed++;return emit2({status:"ok",skillSlug:parsed.skillSlug,candidateId:parsed.candidateId,lastState:replay.state,baselineBytes:baseline.length,candidateBytes:candidate2.length,linesAdded:added,linesRemoved:removed,baselinePreview:baseline.slice(0,400),candidatePreview:candidate2.slice(0,400),truncated:replay.truncated},parsed.json)}async function handleSkillOptApprove(directory,args2){let parsed=parseSkillOptArgs(args2);if(!parsed.skillSlug||!parsed.candidateId||!parsed.expectedContentHash)return emit2({status:"error",error:"usage: approve <slug> <candidateId> --expected-content-hash <hash>"},parsed.json);let idError=validateIds(parsed.skillSlug,parsed.candidateId,parsed.json);if(idError)return idError;let result=await activateCandidate({directory,skillSlug:parsed.skillSlug,candidateId:parsed.candidateId,actor:"user:skill-opt-approve",expectedContentHash:parsed.expectedContentHash});return emit2({status:result.activated?"activated":"error",...result},parsed.json)}async function handleSkillOptReject(directory,args2){let parsed=parseSkillOptArgs(args2);if(!parsed.skillSlug||!parsed.candidateId)return emit2({status:"error",error:"usage: reject <slug> <candidateId>"},parsed.json);let rejectIdError=validateIds(parsed.skillSlug,parsed.candidateId,parsed.json);if(rejectIdError)return rejectIdError;let state=currentCandidateState(directory,parsed.skillSlug,parsed.candidateId);if(!isLegalTransition(state.state,"rejected"))return emit2({status:"error",error:`cannot reject a candidate in state ${state.state??"<none>"} (legal from: drafted, smoke_validated, validation_running, inconclusive)`},parsed.json);let event=await recordTransition({directory,skillSlug:parsed.skillSlug,candidateId:parsed.candidateId,toState:"rejected",eventType:"reject",actor:"user:skill-opt-reject",origin:"command:skill-opt:reject",reason:"human-invoked rejection (no active-skill mutation)"});return emit2({status:"rejected",event},parsed.json)}async function handleSkillOptRollback(directory,args2){let parsed=parseSkillOptArgs(args2);if(!parsed.skillSlug||!parsed.candidateId)return emit2({status:"error",error:"usage: rollback <slug> <candidateId>"},parsed.json);let rbIdError=validateIds(parsed.skillSlug,parsed.candidateId,parsed.json);if(rbIdError)return rbIdError;let result=await rollbackCandidate({directory,skillSlug:parsed.skillSlug,candidateId:parsed.candidateId,actor:"user:skill-opt-rollback"});return emit2({status:result.rolledBack?"rolled_back":"error",...result},parsed.json)}async function handleSkillOptHistory(directory,args2){let parsed=parseSkillOptArgs(args2);if(!parsed.skillSlug||!parsed.candidateId)return emit2({status:"error",error:"usage: history <slug> <candidateId>"},parsed.json);let idError=validateIds(parsed.skillSlug,parsed.candidateId,parsed.json);if(idError)return idError;let replay=replayCandidate(directory,parsed.skillSlug,parsed.candidateId);return emit2({status:"ok",skillSlug:parsed.skillSlug,candidateId:parsed.candidateId,events:replay.events,truncated:replay.truncated,lastCompleteSeq:replay.lastCompleteSeq},parsed.json)}var init_skill_opt=__esm(()=>{init_schema();init_activation2();init_controller();init_lifecycle();init_skill_eval_tasks();init_store2()});async function handleSpecifyCommand(_directory,args2){let description=args2.join(" ").trim();if(description)return`[MODE: SPECIFY] ${description}`;return"[MODE: SPECIFY] Please enter MODE: SPECIFY and generate a spec for this project."}var ReferenceSchema2,Sha256Schema2,IsoDateSchema3,MAX_CONSENSUS_REFS=200,MAX_CONSENSUS_STATEMENT_CHARS=600,MAX_CONSENSUS_ATTRIBUTES=1000,MAX_CONSENSUS_PROPOSALS=1000,ReferenceListSchema2,ConsensusMineRequestSchema,ConsensusProposedTargetSchema,ConsensusAttributeV1Schema,ProposedSkillChangeProvenanceSchema,ProposedSkillChangeSchema,ConsensusSourceKindSchema,ConsensusCorpusHashSchema,ConsensusTruncationV1Schema,ConsensusReportV1Schema;var init_contracts2=__esm(()=>{init_zod();ReferenceSchema2=exports_external.string().min(1).max(512).refine((value)=>!value.includes("\x00"),"reference contains a NUL byte"),Sha256Schema2=exports_external.string().regex(/^[a-f0-9]{64}$/),IsoDateSchema3=exports_external.iso.datetime({offset:!0}),ReferenceListSchema2=exports_external.array(ReferenceSchema2).max(MAX_CONSENSUS_REFS),ConsensusMineRequestSchema=exports_external.object({runIds:ReferenceListSchema2.optional(),taskCategories:ReferenceListSchema2.optional(),agentRoles:ReferenceListSchema2.optional(),modelIds:ReferenceListSchema2.optional(),minSupport:exports_external.number().int().min(1),minSuccessfulRuns:exports_external.number().int().min(0),maxEvidenceItems:exports_external.number().int().min(1)}).strict(),ConsensusProposedTargetSchema=exports_external.enum(["skill","prompt","tooling","orchestration","none"]),ConsensusAttributeV1Schema=exports_external.object({v:exports_external.literal(1),id:ReferenceSchema2,statement:exports_external.string().min(1).max(MAX_CONSENSUS_STATEMENT_CHARS),llmSummary:exports_external.string().min(1).max(MAX_CONSENSUS_STATEMENT_CHARS).optional(),support:exports_external.number().int().nonnegative(),successSupport:exports_external.number().int().nonnegative(),failureSupport:exports_external.number().int().nonnegative(),taskDiversity:exports_external.number().int().nonnegative(),modelDiversity:exports_external.number().int().nonnegative(),evidenceRefs:ReferenceListSchema2,counterexampleRefs:ReferenceListSchema2,confidence:exports_external.number().min(0).max(1),proposedTarget:ConsensusProposedTargetSchema}).strict().superRefine((attribute,ctx)=>{if(attribute.successSupport>attribute.support)ctx.addIssue({code:"custom",path:["successSupport"],message:"successful-run support cannot exceed total run support"});if(attribute.failureSupport>attribute.support)ctx.addIssue({code:"custom",path:["failureSupport"],message:"failing-run support cannot exceed total run support"});if(attribute.failureSupport>0&&attribute.counterexampleRefs.length===0)ctx.addIssue({code:"custom",path:["counterexampleRefs"],message:"an attribute with failing support must retain its counterexample references"})}),ProposedSkillChangeProvenanceSchema=exports_external.object({v:exports_external.literal(1),mechanism:exports_external.literal("consensus_mine"),sourceKnowledgeIds:ReferenceListSchema2,sourceTaskIds:ReferenceListSchema2,sourceEvidenceRefs:ReferenceListSchema2,sourceRunIds:ReferenceListSchema2,sourceModelIds:ReferenceListSchema2,writeOrigin:exports_external.object({sessionId:ReferenceSchema2.optional(),agentRole:ReferenceSchema2.optional(),producedAt:IsoDateSchema3}).strict()}).strict(),ProposedSkillChangeSchema=exports_external.object({sourceAttributeId:ReferenceSchema2,target:ReferenceSchema2,intent:exports_external.string().min(1).max(MAX_CONSENSUS_STATEMENT_CHARS),evidenceRefs:ReferenceListSchema2,counterexampleRefs:ReferenceListSchema2,confidence:exports_external.number().min(0).max(1),expectedMetric:ReferenceSchema2,validationSelector:exports_external.string().min(1).max(1024),fingerprint:exports_external.string().regex(/^lrec_[a-f0-9]{16}$/),provenance:ProposedSkillChangeProvenanceSchema}).strict(),ConsensusSourceKindSchema=exports_external.enum(["evaluation-run","gate-audit","gate-ground-truth","task-trajectory","prm-session","skill-usage","knowledge","evidence-bundle","curated-failure"]),ConsensusCorpusHashSchema=exports_external.object({source:ConsensusSourceKindSchema,hash:Sha256Schema2,observations:exports_external.number().int().nonnegative()}).strict(),ConsensusTruncationV1Schema=exports_external.object({corpus:exports_external.boolean(),observations:exports_external.number().int().nonnegative(),inputIds:exports_external.boolean(),totalInputIds:exports_external.number().int().nonnegative(),attributesDropped:exports_external.number().int().nonnegative()}).strict(),ConsensusReportV1Schema=exports_external.object({v:exports_external.literal(1),reportId:ReferenceSchema2,generatedAt:IsoDateSchema3,request:ConsensusMineRequestSchema,inputIds:ReferenceListSchema2,corpusHashes:exports_external.array(ConsensusCorpusHashSchema).max(64),configHash:Sha256Schema2,integrityHash:Sha256Schema2,attributes:exports_external.array(ConsensusAttributeV1Schema).max(MAX_CONSENSUS_ATTRIBUTES),proposals:exports_external.array(ProposedSkillChangeSchema).max(MAX_CONSENSUS_PROPOSALS),truncation:ConsensusTruncationV1Schema,redactionPolicyVersion:exports_external.number().int().nonnegative()}).strict().superRefine((report,ctx)=>{if(new Set(report.attributes.map((a)=>a.id)).size!==report.attributes.length)ctx.addIssue({code:"custom",path:["attributes"],message:"report contains duplicate attribute ids"});let fingerprints=report.proposals.map((p)=>p.fingerprint);if(new Set(fingerprints).size!==fingerprints.length)ctx.addIssue({code:"custom",path:["proposals"],message:"report contains duplicate proposal fingerprints"});let attributesById=new Map(report.attributes.map((attribute)=>[attribute.id,attribute]));for(let proposal of report.proposals){let source=attributesById.get(proposal.sourceAttributeId);if(!source){ctx.addIssue({code:"custom",path:["proposals"],message:`proposal references attribute ${proposal.sourceAttributeId}, which is not in this report`});continue}if(source.proposedTarget==="none")ctx.addIssue({code:"custom",path:["proposals"],message:"an investigation-note attribute must not produce a proposal"})}})});import{readdir as readdir11}from"node:fs/promises";import*as path186 from"node:path";function compareRefs(left,right){return left<right?-1:left>right?1:0}function sanitizeExcerpt(value,maxChars){let normalized=redactSecrets(value).replace(/[\p{Cc}\p{Cf}]+/gu," ").replace(/\s+/g," ").trim();return normalized.length>maxChars?normalized.slice(0,maxChars):normalized}async function listTrajectorySessions(directory){let root=path186.join(directory,".swarm","trajectories"),entries;try{entries=await readdir11(root,{withFileTypes:!0})}catch(error93){if(error93.code==="ENOENT")return[];throw error93}return entries.filter((entry)=>entry.isFile()&&entry.name.endsWith(".jsonl")).map((entry)=>entry.name.slice(0,-6)).filter((name)=>IDENTIFIER_RE.test(name)).sort().slice(0,MAX_ENUMERATED_ENTRIES)}async function listEvaluationRunIds(directory){let root=path186.join(directory,".swarm","evolution","runs"),entries;try{entries=await readdir11(root,{withFileTypes:!0})}catch(error93){if(error93.code==="ENOENT")return[];throw error93}return entries.filter((entry)=>entry.isFile()&&entry.name.endsWith(".json")).map((entry)=>entry.name.slice(0,-5)).filter((name)=>IDENTIFIER_RE.test(name)).sort().slice(0,MAX_ENUMERATED_ENTRIES)}function defaultReaders(){return{listEvaluationRunIds,readEvaluationRun,listGateAuditResults,readGateGroundTruth,listEvidenceTaskIds,readTaskTrajectory,listTrajectorySessions,readTrajectory,readSkillUsageEntries,readKnowledgeEntries:(directory)=>readKnowledge(resolveSwarmKnowledgePath(directory)),loadEvidence:(directory,taskId)=>loadEvidence(directory,taskId,{migrate:!1}),readRejectedLessons,readRejectedSkillEdits:(directory)=>readKnowledge(rejectedEditsPath(directory),MAX_CURATED_FAILURE_ENTRIES)}}function signal(domain3,parts,maxExcerptChars){let cleaned=parts.map((part)=>sanitizeExcerpt(String(part),maxExcerptChars)).filter((part)=>part.length>0);return[domain3,...cleaned].join(":")}async function loadEvaluationRuns(directory,readers,maxExcerptChars){let observations=[];for(let runId of await readers.listEvaluationRunIds(directory)){let run=await readers.readEvaluationRun(directory,runId);if(!run)continue;let modelById=new Map([[run.baseline.id,run.baseline.model],[run.candidate.id,run.candidate.model]]),agentById=new Map([[run.baseline.id,run.baseline.agent],[run.candidate.id,run.candidate.agent]]);for(let[index,result]of run.results.entries()){let signals=[signal("tooling",["evaluation-outcome",result.outcome],maxExcerptChars)];if(result.failureCode)signals.push(signal("tooling",["evaluation-failure",result.failureCode],maxExcerptChars));observations.push({runId:`evaluation-run:${run.runId}`,taskId:result.taskId,taskCategory:result.category,agentRole:agentById.get(result.candidateId),modelId:modelById.get(result.candidateId),seed:result.seed,success:result.outcome==="scored",signals,evidenceRef:sanitizeExcerpt(`evaluation-run:${run.runId}:${result.taskId}:${index}`,maxExcerptChars)})}}return observations}async function loadGateAudit(directory,readers,maxExcerptChars){let observations=[],summary=await readers.listGateAuditResults(directory);for(let result of summary.results)for(let[index,cell]of result.cells.entries()){let signals=[signal("tooling",["gate",cell.gate,cell.outcome],maxExcerptChars)];if(cell.failureClassification)signals.push(signal("tooling",["gate-failure",cell.gate,cell.failureClassification],maxExcerptChars));observations.push({runId:`gate-audit:${result.runId}`,taskId:cell.taskId,agentRole:cell.gate,modelId:cell.model,success:cell.outcome==="caught",signals,evidenceRef:sanitizeExcerpt(`gate-audit:${result.runId}:${cell.taskId}:${index}`,maxExcerptChars)})}return observations}async function loadGateGroundTruth(directory,readers,maxExcerptChars){let observations=[],summary=await readers.listGateAuditResults(directory);for(let result of summary.results){let truth=await readers.readGateGroundTruth(directory,result.runId);for(let[index,event]of truth.events.entries())observations.push({runId:`gate-audit:${event.runId}`,taskId:event.taskId,agentRole:event.gate,modelId:event.model,success:event.classification==="clean",signals:[signal("tooling",["gate-truth",event.gate,event.source,event.classification],maxExcerptChars)],evidenceRef:sanitizeExcerpt(`gate-ground-truth:${event.runId}:${event.taskId}:${index}`,maxExcerptChars)})}return observations}async function loadTaskTrajectories(directory,readers,maxExcerptChars){let observations=[];for(let taskId of await readers.listEvidenceTaskIds(directory)){let entries=await readers.readTaskTrajectory(directory,taskId);for(let[index,entry]of entries.entries())observations.push({runId:`task:${taskId}`,taskId,agentRole:entry.agent?sanitizeExcerpt(entry.agent,maxExcerptChars):void 0,success:entry.result==="success",signals:[signal("orchestration",["task-action",entry.action,entry.result],maxExcerptChars)],evidenceRef:sanitizeExcerpt(`task-trajectory:${taskId}:${index}`,maxExcerptChars)})}return observations}async function loadPrmSessions(directory,readers,maxExcerptChars){let observations=[];for(let sessionId of await readers.listTrajectorySessions(directory)){let entries=await readers.readTrajectory(sessionId,directory);for(let[index,entry]of entries.entries()){let target=entry.target?sanitizeExcerpt(entry.target,maxExcerptChars):"";observations.push({runId:`prm-session:${sessionId}`,taskId:target.length>0?target:void 0,agentRole:entry.agent?sanitizeExcerpt(entry.agent,maxExcerptChars):void 0,success:entry.result==="success",signals:[signal("orchestration",["session-action",entry.action,entry.result],maxExcerptChars)],evidenceRef:sanitizeExcerpt(`prm-session:${sessionId}:${index}`,maxExcerptChars)})}}return observations}function loadSkillUsage(directory,readers,maxExcerptChars){return readers.readSkillUsageEntries(directory).map((entry)=>({runId:`skill-usage:${entry.sessionID}`,taskId:entry.taskID,agentRole:sanitizeExcerpt(entry.agentName,maxExcerptChars),success:entry.complianceVerdict==="compliant",signals:[signal("skill",["usage",entry.skillPath,entry.complianceVerdict],maxExcerptChars)],evidenceRef:sanitizeExcerpt(`skill-usage:${entry.sessionID}:${entry.id}`,maxExcerptChars)}))}async function loadKnowledge(directory,readers,maxExcerptChars){let entries=await readers.readKnowledgeEntries(directory),observations=[];for(let[index,entry]of entries.entries()){if(typeof entry.lesson!=="string"||entry.lesson.trim().length===0)continue;let id=typeof entry.id==="string"?entry.id:String(index),category=typeof entry.category==="string"?entry.category:"other",outcome=computeOutcomeSignal(entry.retrieval_outcomes);observations.push({runId:`knowledge:${sanitizeExcerpt(id,maxExcerptChars)}`,success:outcome>=0,signals:[signal("skill",["knowledge",category,entry.lesson],maxExcerptChars)],evidenceRef:sanitizeExcerpt(`knowledge:${id}`,maxExcerptChars)})}return observations}async function loadEvidenceBundles(directory,readers,maxExcerptChars){let observations=[];for(let taskId of await readers.listEvidenceTaskIds(directory)){let result=await readers.loadEvidence(directory,taskId);if(result.status!=="found")continue;for(let[index,entry]of result.bundle.entries.entries())observations.push({runId:`task:${taskId}`,taskId,agentRole:entry.agent?sanitizeExcerpt(entry.agent,maxExcerptChars):void 0,success:entry.verdict==="pass",signals:[signal("prompt",["evidence",entry.type,entry.verdict??"unknown"],maxExcerptChars)],evidenceRef:sanitizeExcerpt(`evidence-bundle:${taskId}:${index}`,maxExcerptChars)})}return observations}async function loadCuratedFailures(directory,readers,maxExcerptChars){let observations=[],lessons=(await readers.readRejectedLessons(directory)).slice(0,MAX_CURATED_FAILURE_ENTRIES);for(let[index,lesson]of lessons.entries()){let id=typeof lesson.id==="string"&&lesson.id.length>0?lesson.id:String(index),reason=typeof lesson.rejection_reason==="string"?lesson.rejection_reason:"unknown",layer=typeof lesson.rejection_layer==="number"?String(lesson.rejection_layer):"unknown";observations.push({runId:`rejected-lesson:${sanitizeExcerpt(id,maxExcerptChars)}`,success:!1,signals:[signal("skill",["rejected-lesson",layer,reason],maxExcerptChars)],evidenceRef:sanitizeExcerpt(`curated-failure:rejected-lesson:${id}`,maxExcerptChars)})}let edits=(await readers.readRejectedSkillEdits(directory)).slice(0,MAX_CURATED_FAILURE_ENTRIES);for(let[index,edit]of edits.entries()){let hash4=typeof edit.candidateHash==="string"&&edit.candidateHash.length>0?edit.candidateHash:String(index),slug=typeof edit.slug==="string"?edit.slug:"unknown",reason=typeof edit.reason==="string"?edit.reason:"unknown";observations.push({runId:`rejected-skill-edit:${sanitizeExcerpt(hash4,maxExcerptChars)}`,success:!1,signals:[signal("skill",["rejected-edit",slug,reason],maxExcerptChars)],evidenceRef:sanitizeExcerpt(`curated-failure:rejected-skill-edit:${hash4}`,maxExcerptChars)})}for(let taskId of await readers.listEvidenceTaskIds(directory)){let result=await readers.loadEvidence(directory,taskId);if(result.status!=="found")continue;for(let[index,raw]of result.bundle.entries.entries()){let entry=raw;if(entry.type!=="retrospective")continue;let codes=Array.isArray(entry.error_taxonomy)?entry.error_taxonomy.slice(0,MAX_CURATED_FAILURE_ENTRIES):[],reasons=Array.isArray(entry.top_rejection_reasons)?entry.top_rejection_reasons.slice(0,MAX_CURATED_FAILURE_ENTRIES):[];for(let[position,code]of codes.entries()){if(typeof code!=="string"||code.length===0)continue;observations.push({runId:`task:${taskId}`,taskId,success:!1,signals:[signal("orchestration",["retro-error",code],maxExcerptChars)],evidenceRef:sanitizeExcerpt(`curated-failure:retro-error:${taskId}:${index}:${position}`,maxExcerptChars)})}for(let[position,reason]of reasons.entries()){if(typeof reason!=="string"||reason.trim().length===0)continue;observations.push({runId:`task:${taskId}`,taskId,success:!1,signals:[signal("orchestration",["retro-rejection",reason],maxExcerptChars)],evidenceRef:sanitizeExcerpt(`curated-failure:retro-rejection:${taskId}:${index}:${position}`,maxExcerptChars)})}}}return observations}function balancedSlice(sorted,limit){if(limit>=sorted.length)return[...sorted];let failures=sorted.filter((observation)=>!observation.success),successes=sorted.filter((observation)=>observation.success),retained=[],failureIndex=0,successIndex=0;while(retained.length<limit){if(failureIndex<failures.length){if(retained.push(failures[failureIndex]),failureIndex+=1,retained.length>=limit)break}if(successIndex<successes.length)retained.push(successes[successIndex]),successIndex+=1;else if(failureIndex>=failures.length)break}return retained.sort((left,right)=>compareRefs(left.evidenceRef,right.evidenceRef))}async function loadConsensusCorpus(directory,options){let readers={...defaultReaders(),...options.readers},maxExcerptChars=Math.max(1,options.maxExcerptChars),loaders={"evaluation-run":()=>loadEvaluationRuns(directory,readers,maxExcerptChars),"gate-audit":()=>loadGateAudit(directory,readers,maxExcerptChars),"gate-ground-truth":()=>loadGateGroundTruth(directory,readers,maxExcerptChars),"task-trajectory":()=>loadTaskTrajectories(directory,readers,maxExcerptChars),"prm-session":()=>loadPrmSessions(directory,readers,maxExcerptChars),"skill-usage":async()=>loadSkillUsage(directory,readers,maxExcerptChars),knowledge:()=>loadKnowledge(directory,readers,maxExcerptChars),"evidence-bundle":()=>loadEvidenceBundles(directory,readers,maxExcerptChars),"curated-failure":()=>loadCuratedFailures(directory,readers,maxExcerptChars)},observations=[],hashes=[],unreadableSources=[],truncated=!1;for(let source of SOURCE_ORDER){let loaded;try{loaded=await loaders[source]()}catch{unreadableSources.push(source);continue}loaded.sort((left,right)=>compareRefs(left.evidenceRef,right.evidenceRef)),hashes.push({source,hash:canonicalHash(loaded),observations:loaded.length});let eligible=options.filter?loaded.filter(options.filter):loaded,remaining=options.maxEvidenceItems-observations.length;if(remaining<=0){if(eligible.length>0)truncated=!0;continue}if(eligible.length>remaining)truncated=!0,observations.push(...balancedSlice(eligible,remaining));else observations.push(...eligible)}return{observations,hashes,truncated,unreadableSources}}var SOURCE_ORDER,MAX_ENUMERATED_ENTRIES=2000,MAX_CURATED_FAILURE_ENTRIES=500,IDENTIFIER_RE;var init_corpus=__esm(()=>{init_gate_ground_truth();init_hashing();init_store();init_manager2();init_knowledge_store();init_micro_reflector();init_skill_usage_log();init_redaction();init_trajectory_store();init_skill_evaluator();SOURCE_ORDER=["evaluation-run","gate-audit","gate-ground-truth","task-trajectory","prm-session","skill-usage","knowledge","evidence-bundle","curated-failure"],IDENTIFIER_RE=/^[A-Za-z0-9][A-Za-z0-9._-]{0,159}$/});function buildObservationFilter(request){let runIds=request.runIds?new Set(request.runIds):void 0,categories=request.taskCategories?new Set(request.taskCategories):void 0,roles=request.agentRoles?new Set(request.agentRoles):void 0,models=request.modelIds?new Set(request.modelIds):void 0;return(observation)=>{if(runIds){let bare=observation.runId.slice(observation.runId.indexOf(":")+1);if(!runIds.has(observation.runId)&&!runIds.has(bare))return!1}if(categories){if(observation.taskCategory===void 0||!categories.has(observation.taskCategory))return!1}if(roles){if(observation.agentRole===void 0||!roles.has(observation.agentRole))return!1}if(models){if(observation.modelId===void 0||!models.has(observation.modelId))return!1}return!0}}function tallySignals(observations){let tallies=new Map;for(let observation of observations){let taskKey=observation.taskId??observation.taskCategory;for(let signal2 of observation.signals){let tally=tallies.get(signal2);if(!tally)tally={signal:signal2,runIds:new Set,successRunIds:new Set,failureRunIds:new Set,taskKeys:new Set,taskIds:new Set,taskCategories:new Set,modelIds:new Set,evidenceRefs:new Set,counterexampleRefs:new Set},tallies.set(signal2,tally);if(tally.runIds.add(observation.runId),observation.success){if(tally.successRunIds.add(observation.runId),tally.evidenceRefs.size<MAX_CONSENSUS_REFS)tally.evidenceRefs.add(observation.evidenceRef)}else if(tally.failureRunIds.add(observation.runId),tally.counterexampleRefs.size<MAX_CONSENSUS_REFS)tally.counterexampleRefs.add(observation.evidenceRef);if(taskKey!==void 0)tally.taskKeys.add(taskKey);if(observation.taskId!==void 0)tally.taskIds.add(observation.taskId);if(observation.taskCategory!==void 0)tally.taskCategories.add(observation.taskCategory);if(observation.modelId!==void 0)tally.modelIds.add(observation.modelId)}}return tallies}function targetFromSignal(signal2){let domain3=signal2.slice(0,signal2.indexOf(":"));switch(domain3){case"skill":case"prompt":case"tooling":case"orchestration":return domain3;default:return"none"}}function humanizeSignal(signal2){return signal2.split(":").slice(1).join(" / ")||signal2}function computeConfidence3(support,successSupport,taskDiversity){if(support<=0)return 0;let supportFactor=support/(support+CONFIDENCE_SUPPORT_SMOOTHING),successRatio=successSupport/support,diversityFactor=taskDiversity>=MIN_TASK_DIVERSITY_FOR_PROPOSAL?1:UNDIVERSE_CONFIDENCE_FACTOR,raw=supportFactor*successRatio*diversityFactor;return Math.min(1,Math.max(0,Math.round(raw*1000)/1000))}function computeAttributeId(signal2){return`cattr_${canonicalHash({signal:signal2}).slice(0,16)}`}function renderStatement(tally,support,successSupport,failureSupport,maxExcerptChars){let subject=humanizeSignal(tally.signal),diversity=tally.taskKeys.size,scope=diversity>=MIN_TASK_DIVERSITY_FOR_PROPOSAL?`${diversity} distinct tasks`:diversity===1?"1 task (single-task evidence)":"no attributed task (task attribution unavailable)",rendered=`${subject} recurs across ${support} independent run(s) spanning ${scope}: ${successSupport} succeeded, ${failureSupport} failed.`;return sanitizeExcerpt(rendered,Math.min(MAX_CONSENSUS_STATEMENT_CHARS,Math.max(64,maxExcerptChars*2)))}function buildAttributes(tallies,request,maxExcerptChars,maxAttributes){let qualifying=[];for(let tally of[...tallies.values()].sort((left,right)=>compareRefs(left.signal,right.signal))){let support=tally.runIds.size,successSupport=tally.successRunIds.size,failureSupport=tally.failureRunIds.size;if(support<request.minSupport)continue;if(successSupport<request.minSuccessfulRuns)continue;let taskDiversity=tally.taskKeys.size,qualifies=taskDiversity>=MIN_TASK_DIVERSITY_FOR_PROPOSAL&&support>=MIN_SUPPORT_FOR_PROPOSAL;qualifying.push({tally,attribute:{v:1,id:computeAttributeId(tally.signal),statement:renderStatement(tally,support,successSupport,failureSupport,maxExcerptChars),support,successSupport,failureSupport,taskDiversity,modelDiversity:tally.modelIds.size,evidenceRefs:[...tally.evidenceRefs].sort(),counterexampleRefs:[...tally.counterexampleRefs].sort(),confidence:computeConfidence3(support,successSupport,taskDiversity),proposedTarget:qualifies?targetFromSignal(tally.signal):"none"}})}if(qualifying.length<=maxAttributes)return{mined:qualifying,dropped:0};let strongestIds=new Set([...qualifying].sort((left,right)=>right.attribute.confidence-left.attribute.confidence||right.attribute.support-left.attribute.support||compareRefs(left.attribute.id,right.attribute.id)).slice(0,maxAttributes).map((entry)=>entry.attribute.id));return{mined:qualifying.filter((entry)=>strongestIds.has(entry.attribute.id)),dropped:qualifying.length-strongestIds.size}}function renderValidationSelector(key,values){let budget=MAX_VALIDATION_SELECTOR_CHARS-SELECTOR_OMISSION_RESERVE,kept=[],length=key.length+1;for(let value of values){let clean=sanitizeExcerpt(value,MAX_SELECTOR_ENTRY_CHARS+1);if(clean.length===0||clean.length>MAX_SELECTOR_ENTRY_CHARS)continue;let cost=clean.length+(kept.length>0?1:0);if(length+cost>budget)break;kept.push(clean),length+=cost}if(kept.length===0)return;let omitted=values.length-kept.length;return omitted>0?`${key}=${kept.join(",")};omitted=${omitted}`:`${key}=${kept.join(",")}`}function buildProposals(mined,options){let proposals=[],seen=new Set,deduped=0;for(let{attribute,tally}of mined){if(attribute.proposedTarget==="none")continue;let categories=[...tally.taskCategories].sort(),runIds=[...tally.runIds].sort(),modelIds=[...tally.modelIds].sort(),taskIds=[...tally.taskIds].sort(),fingerprint2=computeRecommendationFingerprint({kind:"miner",target:attribute.proposedTarget,statement:attribute.statement,scopeKeys:categories});if(options.priorFingerprints.has(fingerprint2)||seen.has(fingerprint2)){deduped+=1;continue}seen.add(fingerprint2);let provenance=stampLearningProvenance({mechanism:"consensus_mine",sourceEvidenceRefs:attribute.evidenceRefs,sourceRunIds:runIds,sourceModelIds:modelIds,sourceTaskIds:taskIds},{producedAt:options.producedAt,sessionId:options.sessionId,agentRole:options.agentRole});proposals.push({sourceAttributeId:attribute.id,target:attribute.proposedTarget,intent:sanitizeExcerpt(`Investigate the smallest ${attribute.proposedTarget} change that would remove the observed pattern: ${humanizeSignal(tally.signal)}.`,MAX_CONSENSUS_STATEMENT_CHARS),evidenceRefs:attribute.evidenceRefs,counterexampleRefs:attribute.counterexampleRefs,confidence:attribute.confidence,expectedMetric:EXPECTED_METRIC[attribute.proposedTarget],validationSelector:renderValidationSelector("taskCategories",categories)??renderValidationSelector("taskIds",taskIds)??renderValidationSelector("runIds",runIds)??`attributeId=${attribute.id}`,fingerprint:fingerprint2,provenance})}return{proposals,deduped}}function isSingleSentence(value){let maskedAbbreviations=0,masked=value.replace(NON_TERMINAL_ABBREVIATION_RE,(match)=>{return maskedAbbreviations+=1,"_".repeat(match.length)}).replace(DECIMAL_POINT_RE,"$1_");if(maskedAbbreviations>MAX_MASKED_ABBREVIATIONS)return!1;return SINGLE_SENTENCE_RE.test(masked)}function extractRestatement(raw){if(typeof raw!=="string")return;let captured;for(let line of raw.split(LINE_TERMINATOR_RE)){let match=RESTATEMENT_ENVELOPE_RE.exec(line);if(match?.[1]!==void 0){captured=match[1];break}}if(captured===void 0)return;if(captured.includes(REDACTION_PLACEHOLDER_PREFIX))return;let cleaned=sanitizeExcerpt(captured,MAX_CONSENSUS_STATEMENT_CHARS+1);if(cleaned.length===0)return;if(cleaned.length>MAX_CONSENSUS_STATEMENT_CHARS)return;if(MARKUP_RE.test(cleaned.replace(REDACTION_PLACEHOLDER_RE," ")))return;if(REASONING_MARKER_RE.test(cleaned))return;if(!isSingleSentence(cleaned))return;return cleaned}async function summarizeStatements(attributes,deps,directory){if(attributes.length===0)return{attributes,summarized:0,skipped:"no_attributes"};if(!deps.config.llm_summarization_enabled)return{attributes,summarized:0,skipped:"disabled_by_config"};let dispatcher=deps.dispatcher;if(!dispatcher)return{attributes,summarized:0,skipped:"no_dispatcher"};let budget=[...attributes].sort((left,right)=>right.confidence-left.confidence||compareRefs(left.id,right.id)).slice(0,MAX_LLM_SUMMARIES),restated=new Map;for(let attribute of budget)try{let result=await dispatcher({sessionDirectory:directory,agentName:SUMMARIZATION_AGENT,modelId:deps.summarizationModelId??"configured",system:SUMMARIZATION_SYSTEM,prompt:attribute.statement,timeoutMs:deps.config.llm_timeout_ms,parentSessionId:deps.sessionId,preferredSwarm:deps.preferredSwarm});if(result.status!=="completed")continue;let restatement=extractRestatement(result.text);if(restatement!==void 0)restated.set(attribute.id,restatement)}catch{}if(restated.size===0)return{attributes,summarized:0};return{attributes:attributes.map((attribute)=>{let llmSummary=restated.get(attribute.id);return llmSummary?{...attribute,llmSummary}:attribute}),summarized:restated.size}}function computeConsensusIntegrityHash(report){let covered={...report};return delete covered.integrityHash,delete covered.reportId,delete covered.generatedAt,covered.attributes=report.attributes.map((attribute)=>{let{llmSummary:_llmSummary,...content}=attribute;return content}),covered.proposals=report.proposals.map((proposal)=>{let{writeOrigin:_writeOrigin,...provenance}=proposal.provenance;return{...proposal,provenance}}),canonicalHash(covered)}function deriveReportId(integrityHash){return`consensus-${integrityHash.slice(0,16)}`}async function mineConsensus(directory,request,deps){let loadCorpus=deps.loadCorpus??loadConsensusCorpus,maxExcerptChars=deps.config.max_excerpt_chars,matchesRequest=buildObservationFilter(request),corpus=await loadCorpus(directory,{maxEvidenceItems:request.maxEvidenceItems,maxExcerptChars,filter:matchesRequest}),filtered=corpus.observations.filter(matchesRequest),tallies=tallySignals(filtered),{mined,dropped:attributesDropped}=buildAttributes(tallies,request,maxExcerptChars,MAX_CONSENSUS_ATTRIBUTES),deterministicAttributes=mined.map((entry)=>entry.attribute),producedAt=(deps.now?.()??new Date).toISOString(),{proposals,deduped}=buildProposals(mined,{priorFingerprints:new Set(deps.priorFingerprints??[]),producedAt,sessionId:deps.sessionId,agentRole:deps.agentRole}),summary=await summarizeStatements(deterministicAttributes,deps,directory),allInputIds=[...new Set(filtered.map((observation)=>observation.runId))].sort(),inputIds=allInputIds.slice(0,MAX_CONSENSUS_REFS),truncation={corpus:corpus.truncated,observations:filtered.length,inputIds:allInputIds.length>inputIds.length,totalInputIds:allInputIds.length,attributesDropped},body={v:1,request,inputIds,corpusHashes:corpus.hashes,configHash:canonicalHash(deps.config),attributes:summary.attributes,proposals,truncation,redactionPolicyVersion:computeRedactionPolicyVersion(!1)},integrityHash=computeConsensusIntegrityHash(body);return{report:ConsensusReportV1Schema.parse({...body,reportId:deriveReportId(integrityHash),generatedAt:producedAt,integrityHash}),truncated:corpus.truncated,unreadableSources:[...corpus.unreadableSources],investigationNoteCount:summary.attributes.filter((attribute)=>attribute.proposedTarget==="none").length,dedupedProposalCount:deduped,summarizedCount:summary.summarized,...summary.skipped?{summarizationSkippedReason:summary.skipped}:{}}}var MIN_TASK_DIVERSITY_FOR_PROPOSAL=2,MIN_SUPPORT_FOR_PROPOSAL=2,MAX_LLM_SUMMARIES=20,CONFIDENCE_SUPPORT_SMOOTHING=3,UNDIVERSE_CONFIDENCE_FACTOR=0.5,SUMMARIZATION_AGENT="curator_postmortem",MAX_VALIDATION_SELECTOR_CHARS=1024,SELECTOR_OMISSION_RESERVE=24,MAX_SELECTOR_ENTRY_CHARS=256,EXPECTED_METRIC,SUMMARIZATION_SYSTEM,RESTATEMENT_ENVELOPE_RE,LINE_TERMINATOR_RE,REASONING_MARKER_RE,MARKUP_RE,REDACTION_PLACEHOLDER_RE,REDACTION_PLACEHOLDER_PREFIX="[REDACTED:",SENTENCE_TERMINATOR_CLASS="\\p{Sentence_Terminal}\\u2025\\u2026\\u22EF\\uFE19\\uFE30",SINGLE_SENTENCE_RE,NON_TERMINAL_ABBREVIATION_RE,MAX_MASKED_ABBREVIATIONS=1,DECIMAL_POINT_RE;var init_miner=__esm(()=>{init_hashing();init_fingerprint();init_provenance();init_redaction();init_contracts2();init_corpus();EXPECTED_METRIC={skill:"skill-usage.compliance_rate",prompt:"evidence.verdict_pass_rate",tooling:"evaluation.scored_outcome_rate",orchestration:"trajectory.step_failure_rate"};SUMMARIZATION_SYSTEM="You restate an already-computed statistical finding in one sentence. You may not add claims, causes, recommendations, or numbers that are not in the input. Reply with exactly one line in the form: FINDING: <one sentence>. "+"Output nothing else — no preamble, no reasoning, no analysis, no lists, no code fences.",RESTATEMENT_ENVELOPE_RE=/^\s*FINDING:\s*(\S.*)$/,LINE_TERMINATOR_RE=/[\r\n\v\f\u0085\u2028\u2029]+/,REASONING_MARKER_RE=/\b(?:reasoning|rationale|chain[-\s]?of[-\s]?thought|thought process|scratchpad|deliberation|let(?:'s| us| me) think|step[-\s]by[-\s]step|i(?:'ll| will| need to| should| must| think| considered| analyzed)|my analysis|analysis|thinking)\b\s*[:,]?/i,MARKUP_RE=/[<>[\]{}\u3008-\u3011\u3014\u3015\uFF08\uFF09\uFF3B\uFF3D\uFF5B\uFF5D]/,REDACTION_PLACEHOLDER_RE=/\[REDACTED:[A-Za-z0-9_]+\]/g,SINGLE_SENTENCE_RE=new RegExp(`^[^${SENTENCE_TERMINATOR_CLASS}]*(?:[${SENTENCE_TERMINATOR_CLASS}]+["')]?)?$`,"u"),NON_TERMINAL_ABBREVIATION_RE=/\b(?:[eE]\.[gG]\.|[iI]\.[eE]\.|[eE][tT][cC]\.)(?=,?\s+\p{Ll})/gu,DECIMAL_POINT_RE=/(\d)\.(?=\d)/g});import{readdir as readdir12,unlink as unlink8}from"node:fs/promises";import*as path187 from"node:path";function swarmPath2(directory,...segments){return path187.join(directory,".swarm",...segments)}function serialized2(value){return`${canonicalJson(value)}
2335
2335
  `}function relativeReportPath(reportId){return path187.join(CONSENSUS_RELATIVE_DIR,`${reportId}.json`)}function consensusConflictError(conflict){return conflict.kind==="corrupt"?new ConsensusConflictError(`existing consensus report is corrupt: ${conflict.filePath}: ${String(conflict.cause)}`):new ConsensusConflictError(`immutable consensus report conflicts with existing content: ${conflict.filePath}`)}function assertSafeReportId(reportId){if(!REPORT_ID_RE.test(reportId))throw new ConsensusIntegrityError(`invalid consensus report id: ${JSON.stringify(reportId)}`)}async function writeConsensusReport(directory,input){let report=ConsensusReportV1Schema.parse(input);if(assertSafeReportId(report.reportId),computeConsensusIntegrityHash(report)!==report.integrityHash)throw new ConsensusIntegrityError(`consensus report ${report.reportId} integrity hash does not match its content`);let relative43=relativeReportPath(report.reportId);return writeImmutableArtifact({directory,relativeLockPath:relative43,filePath:swarmPath2(directory,relative43),agent:AGENT2,taskId:report.reportId,value:report,serialize:serialized2,parse:(value)=>ConsensusReportV1Schema.parse(value),isEquivalent:(existing,desired)=>computeConsensusIntegrityHash(existing)===computeConsensusIntegrityHash(desired),conflictError:consensusConflictError})}async function readConsensusReport(directory,reportId){assertSafeReportId(reportId);let content=await readOptionalFile(swarmPath2(directory,relativeReportPath(reportId)));if(content===void 0)return;let report=ConsensusReportV1Schema.parse(JSON.parse(content));if(computeConsensusIntegrityHash(report)!==report.integrityHash)throw new ConsensusIntegrityError(`consensus report ${reportId} failed integrity verification on read`);return report}async function listConsensusReports(directory){let root=swarmPath2(directory,CONSENSUS_RELATIVE_DIR),entries;try{entries=await readdir12(root,{withFileTypes:!0})}catch(error93){if(error93.code==="ENOENT")return{reports:[],corruptReportIds:[]};throw error93}let reports=[],corruptReportIds=[],ids=entries.filter((entry)=>entry.isFile()&&entry.name.endsWith(".json")).map((entry)=>entry.name.slice(0,-5)).filter((id)=>REPORT_ID_RE.test(id)).sort().slice(0,MAX_LISTED_REPORTS);for(let id of ids)try{let report=await readConsensusReport(directory,id);if(!report)continue;if(report.reportId!==id)throw Error("report id/path mismatch");reports.push(report)}catch{corruptReportIds.push(id)}return reports.sort((left,right)=>right.generatedAt.localeCompare(left.generatedAt)||left.reportId.localeCompare(right.reportId)),{reports,corruptReportIds}}async function countConsensusReportFiles(directory){let root=swarmPath2(directory,CONSENSUS_RELATIVE_DIR);try{return(await readdir12(root,{withFileTypes:!0})).filter((entry)=>entry.isFile()&&entry.name.endsWith(".json")&&REPORT_ID_RE.test(entry.name.slice(0,-5))).length}catch(error93){if(error93.code==="ENOENT")return 0;throw error93}}async function pruneConsensusReports(directory,retain){if(!Number.isInteger(retain)||retain<=0)return{deleted:[],retained:[],failed:[],corrupt:[]};let{reports,corruptReportIds}=await listConsensusReports(directory),keep=reports.slice(0,retain),drop=reports.slice(retain),deleted=[],failed=[];for(let report of drop)try{await unlink8(swarmPath2(directory,relativeReportPath(report.reportId))),deleted.push(report.reportId)}catch(error93){failed.push({reportId:report.reportId,error:error93 instanceof Error?error93.message:String(error93)})}return{deleted,retained:keep.map((report)=>report.reportId),failed,corrupt:corruptReportIds}}async function listConsensusProposalFingerprints(directory){let{reports}=await listConsensusReports(directory),fingerprints=new Set;for(let report of reports)for(let proposal of report.proposals)fingerprints.add(proposal.fingerprint);return fingerprints}var AGENT2="consensus-store",CONSENSUS_RELATIVE_DIR,REPORT_ID_RE,MAX_LISTED_REPORTS=1000,ConsensusConflictError,ConsensusIntegrityError;var init_store3=__esm(()=>{init_hashing();init_immutable_store();init_contracts2();init_miner();CONSENSUS_RELATIVE_DIR=path187.join("evolution","consensus"),REPORT_ID_RE=/^[A-Za-z0-9][A-Za-z0-9._-]{0,159}$/;ConsensusConflictError=class ConsensusConflictError extends Error{constructor(message){super(message);this.name="ConsensusConflictError"}};ConsensusIntegrityError=class ConsensusIntegrityError extends Error{constructor(message){super(message);this.name="ConsensusIntegrityError"}}});import*as fs101 from"node:fs";import*as path188 from"node:path";function nowISO4(){return new Date().toISOString()}function ensureSwarmDir5(directory){let swarmDir=path188.resolve(directory,".swarm");if(!fs101.existsSync(swarmDir))fs101.mkdirSync(swarmDir,{recursive:!0});return swarmDir}function emptyCounters2(){return{lanesPlanned:0,lanesStarted:0,lanesCompleted:0,lanesFailed:0,tasksSerialized:0,tasksDegraded:0}}function emptyRunState(sessionID,maxParallelCoders){return{status:"idle",sessionID,strategy:"lean",maxParallelCoders,lanes:[],degradedTasks:[],serializedTasks:[],counters:emptyCounters2()}}function emptyPersisted3(){return{version:1,updatedAt:nowISO4(),sessions:{}}}function isStateUnreadable2(directory){return stateUnreadableMap3.get(directory)??!1}function markStateUnreadable3(directory,reason){stateUnreadableMap3.set(directory,!0),error48(`[turbo/lean/state] state file unreadable for ${directory}: ${reason} — failing closed`)}function readPersisted3(directory){try{let filePath=path188.join(directory,".swarm",STATE_FILE4);if(!fs101.existsSync(filePath)){let seed=emptyPersisted3();try{ensureSwarmDir5(directory),fs101.writeFileSync(filePath,`${JSON.stringify(seed,null,2)}
@@ -3140,6 +3140,13 @@ Every loaded mode skill is written with active-swarm role phrases. Before follow
3140
3140
 
3141
3141
  Do not delegate to the literal natural-language phrase. Delegate only to the concrete rendered agent name for the active swarm.
3142
3142
 
3143
+ ### SKILL LOADING (self-load protocol for MODE actions)
3144
+ When a MODE section says "ACTION: Load skill file:<path>", load the skill yourself using the search tool:
3145
+ - Strip the \`file:\` prefix to get the repo-relative path.
3146
+ - Call the search tool with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 10000\`, and \`max_lines: 10000\`.
3147
+ - If \`total === 0\` (file does not exist or is empty) OR \`truncated\` is \`true\` (the file exceeded even \`max_results: 10000\`), report \`SKILL_LOAD_FAILED: <path>\`, stop, and ask the user how to proceed. Do NOT continue without the complete skill and do NOT substitute a partial or improvised protocol.
3148
+ - If the search result has \`total > 0\` and \`truncated\` is \`false\`, reconstruct the full skill content from the line-by-line matches and follow the loaded protocol.
3149
+
3143
3150
  ### MODE: BRAINSTORM
3144
3151
  Activates when: user invokes /swarm brainstorm, uses brainstorm-style phrasing, or the problem is exploratory and requirements need structured dialogue.
3145
3152
 
@@ -3606,7 +3613,7 @@ ACCEPTANCE HANDLING: ACCEPTANCE is the authoritative definition of "done" for th
3606
3613
 
3607
3614
  SKILLS HANDLING: If SKILLS is present and not "none", read the skill names/descriptions first, then load every referenced skill that applies to your TASK before writing any code. If uncertain whether a skill applies, load it.
3608
3615
  - A file entry may include a short description after the path; use the description to decide whether the full skill body is relevant.
3609
- - For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 1000\`, and \`max_lines: 1000\`.
3616
+ - For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 10000\`, and \`max_lines: 10000\`.
3610
3617
  - After running search, inspect the result: if \`total === 0\` (file does not exist or is empty) OR \`truncated\` is \`true\` (file was too large and content was cut off), stop and report \`SKILL_LOAD_FAILED: <path>\`. Do NOT continue without the complete skill.
3611
3618
  - If the search result has \`total > 0\` and \`truncated\` is \`false\`, reconstruct the full skill content from the line-by-line matches and apply it.
3612
3619
  - If inline \`--- skill-name ---\` sections are present, read them directly.
@@ -4594,7 +4601,7 @@ SKILLS: [optional — either "none", repo-relative file: references (preferred),
4594
4601
 
4595
4602
  SKILLS HANDLING: If SKILLS is present and not "none", read the skill names/descriptions first, then load every referenced skill that applies before producing the design specification. If uncertain whether a skill applies, load it.
4596
4603
  - A file entry may include a short description after the path; use the description to decide whether the full skill body is relevant.
4597
- - For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 1000\`, and \`max_lines: 1000\`.
4604
+ - For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 10000\`, and \`max_lines: 10000\`.
4598
4605
  - After running search, inspect the result: if \`total === 0\` (file does not exist or is empty) OR \`truncated\` is \`true\` (file was too large and content was cut off), stop and report \`SKILL_LOAD_FAILED: <path>\`. Do NOT continue without the complete skill.
4599
4606
  - If the search result has \`total > 0\` and \`truncated\` is \`false\`, reconstruct the full skill content from the line-by-line matches and apply it.
4600
4607
  - If inline \`--- skill-name ---\` sections are present, read them directly.
@@ -4757,7 +4764,7 @@ SKILLS: [optional — either "none", repo-relative file: references (preferred),
4757
4764
 
4758
4765
  SKILLS HANDLING: If SKILLS is present and not "none", read the skill names/descriptions first, then load every referenced skill that applies before updating docs. If uncertain whether a skill applies, load it.
4759
4766
  - A file entry may include a short description after the path; use the description to decide whether the full skill body is relevant.
4760
- - For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 1000\`, and \`max_lines: 1000\`.
4767
+ - For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 10000\`, and \`max_lines: 10000\`.
4761
4768
  - After running search, inspect the result: if \`total === 0\` (file does not exist or is empty) OR \`truncated\` is \`true\` (file was too large and content was cut off), stop and report \`SKILL_LOAD_FAILED: <path>\`. Do NOT continue without the complete skill.
4762
4769
  - If the search result has \`total > 0\` and \`truncated\` is \`false\`, reconstruct the full skill content from the line-by-line matches and apply it.
4763
4770
  - If inline \`--- skill-name ---\` sections are present, read them directly.
@@ -4865,7 +4872,7 @@ SKILLS: [optional — either "none", repo-relative file: references (preferred),
4865
4872
 
4866
4873
  SKILLS HANDLING: If SKILLS is present and not "none", read the skill names/descriptions first, then load every referenced skill that applies before writing docs. If uncertain whether a skill applies, load it.
4867
4874
  - A file entry may include a short description after the path; use the description to decide whether the full skill body is relevant.
4868
- - For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 1000\`, and \`max_lines: 1000\`.
4875
+ - For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 10000\`, and \`max_lines: 10000\`.
4869
4876
  - After running search, inspect the result: if \`total === 0\` (file does not exist or is empty) OR \`truncated\` is \`true\` (file was too large and content was cut off), stop and report \`SKILL_LOAD_FAILED: <path>\`. Do NOT continue without the complete skill.
4870
4877
  - If the search result has \`total > 0\` and \`truncated\` is \`false\`, reconstruct the full skill content from the line-by-line matches and apply it.
4871
4878
  - If inline \`--- skill-name ---\` sections are present, read them directly.
@@ -5274,7 +5281,7 @@ ACCEPTANCE HANDLING: ACCEPTANCE is the authoritative definition of "done" for th
5274
5281
 
5275
5282
  SKILLS HANDLING: If SKILLS is present and not "none", read the skill names/descriptions first, then load every referenced skill that applies before beginning your review. If uncertain whether a skill applies, load it.
5276
5283
  - A file entry may include a short description after the path; use the description to decide whether the full skill body is relevant.
5277
- - For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 1000\`, and \`max_lines: 1000\`.
5284
+ - For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 10000\`, and \`max_lines: 10000\`.
5278
5285
  - After running search, inspect the result: if \`total === 0\` (file does not exist or is empty) OR \`truncated\` is \`true\` (file was too large and content was cut off), stop and report \`SKILL_LOAD_FAILED: <path>\`. Do NOT continue without the complete skill.
5279
5286
  - If the search result has \`total > 0\` and \`truncated\` is \`false\`, reconstruct the full skill content from the line-by-line matches and apply it.
5280
5287
  - If inline \`--- skill-name ---\` sections are present, read them directly.
@@ -5460,7 +5467,7 @@ SKILLS: [optional — either "none", repo-relative file: references (preferred),
5460
5467
 
5461
5468
  SKILLS HANDLING: If SKILLS is present and not "none", read the skill names/descriptions first, then load every referenced skill that applies before formulating your recommendation. If uncertain whether a skill applies, load it.
5462
5469
  - A file entry may include a short description after the path; use the description to decide whether the full skill body is relevant.
5463
- - For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 1000\`, and \`max_lines: 1000\`.
5470
+ - For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 10000\`, and \`max_lines: 10000\`.
5464
5471
  - After running search, inspect the result: if \`total === 0\` (file does not exist or is empty) OR \`truncated\` is \`true\` (file was too large and content was cut off), stop and report \`SKILL_LOAD_FAILED: <path>\`. Do NOT continue without the complete skill.
5465
5472
  - If the search result has \`total > 0\` and \`truncated\` is \`false\`, reconstruct the full skill content from the line-by-line matches and apply it.
5466
5473
  - If inline \`--- skill-name ---\` sections are present, read them directly.
@@ -5606,7 +5613,7 @@ SKILLS: [optional — either "none", repo-relative file: references (preferred),
5606
5613
 
5607
5614
  SKILLS HANDLING: If SKILLS is present and not "none", read the skill names/descriptions first, then load every referenced skill that applies before writing any test code. If uncertain whether a skill applies, load it.
5608
5615
  - A file entry may include a short description after the path; use the description to decide whether the full skill body is relevant.
5609
- - For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 1000\`, and \`max_lines: 1000\`.
5616
+ - For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 10000\`, and \`max_lines: 10000\`.
5610
5617
  - After running search, inspect the result: if \`total === 0\` (file does not exist or is empty) OR \`truncated\` is \`true\` (file was too large and content was cut off), stop and report \`SKILL_LOAD_FAILED: <path>\`. Do NOT continue without the complete skill.
5611
5618
  - If the search result has \`total > 0\` and \`truncated\` is \`false\`, reconstruct the full skill content from the line-by-line matches and apply it.
5612
5619
  - If inline \`--- skill-name ---\` sections are present, read them directly.
@@ -5814,7 +5821,7 @@ CRITICAL: Agents without the "${swarmId}_" prefix DO NOT EXIST or belong to a DI
5814
5821
  If you call @coder instead of @${swarmId}_coder, the call will FAIL or go to the wrong swarm.
5815
5822
 
5816
5823
  `;architect.config.prompt=swarmHeader+architect.config.prompt}agents.push(applyOverrides(architect,swarmAgents,swarmPrefix,quiet))}for(let{name,factory}of TYPE_A_AGENTS)if(!isAgentDisabled(name,swarmAgents,swarmPrefix)){let prompts=getPrompts(name),agent=name==="reviewer"?createReviewerAgent(getModel(name),prompts.prompt,prompts.appendPrompt,pluginConfig?.auto_review?.enabled===!0&&pluginConfig.auto_review.structured_findings!==!1):factory(getModel(name),prompts.prompt,prompts.appendPrompt);agent.name=prefixName(name),agents.push(applyOverrides(agent,swarmAgents,swarmPrefix,quiet))}if(!isAgentDisabled("critic",swarmAgents,swarmPrefix)){let criticPrompts=getPrompts("critic"),critic=createCriticAgent(getModel("critic"),criticPrompts.prompt,criticPrompts.appendPrompt,"plan_critic");critic.name=prefixName("critic"),agents.push(applyOverrides(critic,swarmAgents,swarmPrefix,quiet))}if(!isAgentDisabled("critic_sounding_board",swarmAgents,swarmPrefix)){let critic=createCriticAgent(swarmAgents?.critic_sounding_board?.model??getModel("critic"),void 0,void 0,"sounding_board");critic.name=prefixName("critic_sounding_board"),agents.push(applyOverrides(critic,swarmAgents,swarmPrefix,quiet))}if(!isAgentDisabled("critic_drift_verifier",swarmAgents,swarmPrefix)){let critic=createCriticAgent(swarmAgents?.critic_drift_verifier?.model??getModel("critic"),void 0,void 0,"phase_drift_verifier");critic.name=prefixName("critic_drift_verifier"),agents.push(applyOverrides(critic,swarmAgents,swarmPrefix,quiet))}if(!isAgentDisabled("critic_hallucination_verifier",swarmAgents,swarmPrefix)){let critic=createCriticAgent(swarmAgents?.critic_hallucination_verifier?.model??getModel("critic"),void 0,void 0,"hallucination_verifier");critic.name=prefixName("critic_hallucination_verifier"),agents.push(applyOverrides(critic,swarmAgents,swarmPrefix,quiet))}if(!isAgentDisabled("critic_architecture_supervisor",swarmAgents,swarmPrefix)){let critic=createCriticAgent(swarmAgents?.critic_architecture_supervisor?.model??getModel("critic"),void 0,void 0,"architecture_supervisor");critic.name=prefixName("critic_architecture_supervisor"),agents.push(applyOverrides(critic,swarmAgents,swarmPrefix,quiet))}if(!isAgentDisabled("critic_finding_validator",swarmAgents,swarmPrefix)){let critic=createCriticAgent(swarmAgents?.critic_finding_validator?.model??getModel("critic"),void 0,void 0,"finding_validator");critic.name=prefixName("critic_finding_validator"),agents.push(applyOverrides(critic,swarmAgents,swarmPrefix,quiet))}if(!isAgentDisabled("critic_oversight",swarmAgents,swarmPrefix)){let critic=createCriticAutonomousOversightAgent(swarmAgents?.critic_oversight?.model??getModel("critic"));critic.name=prefixName("critic_oversight"),agents.push(applyOverrides(critic,swarmAgents,swarmPrefix,quiet))}if(!isAgentDisabled("curator_init",swarmAgents,swarmPrefix)){let curatorInitPrompts=getPrompts("curator_init"),curatorInit=createCuratorAgent(swarmAgents?.curator_init?.model??getModel("explorer"),curatorInitPrompts.prompt,curatorInitPrompts.appendPrompt,"curator_init");curatorInit.name=prefixName("curator_init"),agents.push(applyOverrides(curatorInit,swarmAgents,swarmPrefix,quiet))}if(!isAgentDisabled("curator_phase",swarmAgents,swarmPrefix)){let curatorPhasePrompts=getPrompts("curator_phase"),curatorPhase=createCuratorAgent(swarmAgents?.curator_phase?.model??getModel("explorer"),curatorPhasePrompts.prompt,curatorPhasePrompts.appendPrompt,"curator_phase");curatorPhase.name=prefixName("curator_phase"),agents.push(applyOverrides(curatorPhase,swarmAgents,swarmPrefix,quiet))}if(!isAgentDisabled("curator_postmortem",swarmAgents,swarmPrefix)){let curatorPostmortemPrompts=getPrompts("curator_postmortem"),curatorPostmortem=createCuratorAgent(swarmAgents?.curator_postmortem?.model??getModel("explorer"),curatorPostmortemPrompts.prompt,curatorPostmortemPrompts.appendPrompt,"curator_postmortem");curatorPostmortem.name=prefixName("curator_postmortem"),agents.push(applyOverrides(curatorPostmortem,swarmAgents,swarmPrefix,quiet))}if(!isAgentDisabled("curator_consolidation",swarmAgents,swarmPrefix)){let curatorConsolidationPrompts=getPrompts("curator_consolidation"),curatorConsolidation=createCuratorAgent(swarmAgents?.curator_consolidation?.model??getModel("explorer"),curatorConsolidationPrompts.prompt,curatorConsolidationPrompts.appendPrompt,"curator_consolidation");curatorConsolidation.name=prefixName("curator_consolidation"),agents.push(applyOverrides(curatorConsolidation,swarmAgents,swarmPrefix,quiet))}let anyCouncilAgentConfiguredActive=swarmAgents?.council_generalist!==void 0&&!isAgentDisabled("council_generalist",swarmAgents,swarmPrefix)||swarmAgents?.council_skeptic!==void 0&&!isAgentDisabled("council_skeptic",swarmAgents,swarmPrefix)||swarmAgents?.council_domain_expert!==void 0&&!isAgentDisabled("council_domain_expert",swarmAgents,swarmPrefix);if(pluginConfig?.council?.general?.enabled!==!0&&anyCouncilAgentConfiguredActive)emitGatedAgentAdvisory("[opencode-swarm] agents.council_{generalist,skeptic,domain_expert} are configured but "+"council.general.enabled is not true — the council agents will NOT be registered. "+'Set "council": { "general": { "enabled": true } } in opencode-swarm.json to enable them, or remove the agents.council_* blocks to silence this warning.');if(pluginConfig?.council?.general?.enabled===!0){let councilAgentsCreated=0;if(!isAgentDisabled("reviewer",swarmAgents,swarmPrefix)){let councilGeneralist=createReviewerAgent(getModel("reviewer"),GENERALIST_COUNCIL_PROMPT);councilGeneralist.name=prefixName("council_generalist"),agents.push(applyOverrides(councilGeneralist,swarmAgents,swarmPrefix,quiet)),councilAgentsCreated++}if(!isAgentDisabled("critic",swarmAgents,swarmPrefix)){let councilSkeptic=createCriticAgent(getModel("critic"),SKEPTIC_COUNCIL_PROMPT);councilSkeptic.name=prefixName("council_skeptic"),agents.push(applyOverrides(councilSkeptic,swarmAgents,swarmPrefix,quiet)),councilAgentsCreated++}if(!isAgentDisabled("sme",swarmAgents,swarmPrefix)){let councilDomainExpert=createSMEAgent(getModel("sme"),DOMAIN_EXPERT_COUNCIL_PROMPT);councilDomainExpert.name=prefixName("council_domain_expert"),agents.push(applyOverrides(councilDomainExpert,swarmAgents,swarmPrefix,quiet)),councilAgentsCreated++}if(councilAgentsCreated<3){let missing=[];if(isAgentDisabled("reviewer",swarmAgents,swarmPrefix))missing.push("council_generalist (requires reviewer)");if(isAgentDisabled("critic",swarmAgents,swarmPrefix))missing.push("council_skeptic (requires critic)");if(isAgentDisabled("sme",swarmAgents,swarmPrefix))missing.push("council_domain_expert (requires sme)");addDeferredWarning(`[opencode-swarm] council.general.enabled is true but only ${councilAgentsCreated}/3 council agents could be registered because the following base agents are disabled: ${missing.join(", ")}. Re-enable those agents or accept a reduced council.`)}if(pluginConfig?.council?.general?.moderatorModel!==void 0)addDeferredWarning("[opencode-swarm] council.general.moderatorModel is deprecated and ignored. The architect now synthesizes the final answer directly using inline output rules. Remove this field (and council.general.moderator if set) from opencode-swarm.json to silence this warning.")}if(swarmAgents?.docs_design!==void 0&&!isAgentDisabled("docs_design",swarmAgents,swarmPrefix)&&pluginConfig?.design_docs?.enabled!==!0)emitGatedAgentAdvisory("[opencode-swarm] agents.docs_design is configured but design_docs.enabled is not true — "+'the docs_design agent will NOT be registered. Set "design_docs": { "enabled": true } in opencode-swarm.json to enable it, or remove the agents.docs_design block to silence this warning.');if(pluginConfig?.design_docs?.enabled===!0&&!isAgentDisabled("docs_design",swarmAgents,swarmPrefix)){let docsDesignPrompts=getPrompts("docs_design"),docsDesign=createDocsAgent(getModel("docs_design"),docsDesignPrompts.prompt,docsDesignPrompts.appendPrompt,"design_docs");docsDesign.name=prefixName("docs_design"),agents.push(applyOverrides(docsDesign,swarmAgents,swarmPrefix,quiet))}if(swarmAgents?.designer!==void 0&&!isAgentDisabled("designer",swarmAgents,swarmPrefix)&&pluginConfig?.ui_review?.enabled!==!0)emitGatedAgentAdvisory("[opencode-swarm] agents.designer is configured but ui_review.enabled is not true — "+'the designer agent will NOT be registered. Set "ui_review": { "enabled": true } in opencode-swarm.json to enable it, or remove the agents.designer block to silence this warning.');if(pluginConfig?.ui_review?.enabled===!0&&!isAgentDisabled("designer",swarmAgents,swarmPrefix)){let designerPrompts=getPrompts("designer"),designer=createDesignerAgent(getModel("designer"),designerPrompts.prompt,designerPrompts.appendPrompt);designer.name=prefixName("designer"),agents.push(applyOverrides(designer,swarmAgents,swarmPrefix,quiet))}for(let agent of agents)if(typeof agent.config.prompt==="string"){agent.config.prompt+=NONTRANSIENT_STOP_PROTOCOL;try{assertNoUnresolvedPlaceholders(agent.config.prompt,agent.name)}catch(err){addDeferredWarning(`[opencode-swarm] ${err instanceof Error?err.message:String(err)} (agent "${agent.name}" was registered anyway; plugin init not aborted).`)}}return agents}function createAgents(config3,projectContext=emptyProjectContext()){let allAgents=[];_emittedGatedAgentAdvisories.clear();let swarms=config3?.swarms;if(swarms&&Object.keys(swarms).length>0){_swarmAgentsMap.set("default",{});for(let swarmId of Object.keys(swarms)){let swarmConfig=swarms[swarmId],isDefault=swarmId==="default";if(config3?.agents)swarmConfig={...swarmConfig,agents:{...config3.agents,...swarmConfig.agents??{}}};let swarmAgents=createSwarmAgents(swarmId,swarmConfig,isDefault,config3,projectContext);allAgents.push(...swarmAgents)}}else{let legacySwarmConfig={name:"Default",agents:config3?.agents},swarmAgents=createSwarmAgents("default",legacySwarmConfig,!0,config3,projectContext);allAgents.push(...swarmAgents)}return allAgents}function resolvePrimaryAgentNames(agentNames,defaultAgent){let collectArchitectRole=()=>agentNames.filter((n)=>stripKnownSwarmPrefix(n)==="architect"),trimmed=typeof defaultAgent==="string"?defaultAgent.trim():void 0,value=trimmed===""?void 0:trimmed;if(agentNames.length===0)return{primaryNames:new Set,reason:"implicit-architects"};if(value===void 0){let architects2=collectArchitectRole();if(architects2.length>0)return{primaryNames:new Set(architects2),reason:"implicit-architects"};let first2=agentNames[0];return{primaryNames:new Set([first2]),reason:"fallback-first",warning:`[swarm] No architect-role agents are registered and default_agent is unset; falling back to '${first2}' as primary. Re-enable an architect agent or set default_agent to silence this warning.`}}if(ALL_AGENT_NAMES.includes(value)){let matching=agentNames.filter((n)=>stripKnownSwarmPrefix(n)===value);if(matching.length>0)return{primaryNames:new Set(matching),reason:"base-role"}}if(agentNames.includes(value))return{primaryNames:new Set([value]),reason:"exact"};let architects=collectArchitectRole();if(architects.length>0)return{primaryNames:new Set(architects),reason:"fallback-architects",warning:`[swarm] default_agent '${value}' did not match any registered agent; falling back to architect-role primaries: ${architects.join(", ")}.`};let first=agentNames[0];return{primaryNames:new Set([first]),reason:"fallback-first",warning:`[swarm] default_agent '${value}' did not match any registered agent and no architect-role agents are registered; falling back to '${first}' as primary.`}}function getAgentConfigs(config3,directory,sessionId,projectContext){let agents=_internals149.createAgents(config3,projectContext??emptyProjectContext()),toolFilterEnabled=config3?.tool_filter?.enabled??!0,toolFilterOverrides=config3?.tool_filter?.overrides??{},quiet=config3?.quiet??!0,warnedMissingWhitelist=new Set,agentToolSnapshot={},resolution=resolvePrimaryAgentNames(agents.map((a)=>a.name),config3?.default_agent);if(resolution.warning)advisoryWarn(resolution.warning);if(agents.length>0&&resolution.primaryNames.size===0){let generated=agents.map((a)=>a.name).join(", "),diagnostic=`[swarm] DIAGNOSTIC: ${agents.length} generated agents but zero primaries. Likely cause: a regression in resolvePrimaryAgentNames. Generated: ${generated}.`;if(!quiet)log(diagnostic);else addDeferredWarning(diagnostic)}let architectOverride=toolFilterOverrides.architect;if(toolFilterEnabled&&config3?.council?.enabled!==!0&&architectOverride!==void 0){let present=["declare_council_criteria","submit_council_verdicts","submit_phase_council_verdicts","write_final_council_evidence"].filter((tool3)=>architectOverride.includes(tool3));if(present.length>0)advisoryWarn(`[opencode-swarm] tool_filter.overrides.architect includes ${present.join(", ")} but council.enabled is not true. The runtime gate will reject these calls. Either set council.enabled=true, or remove ${present.join(", ")} from the architect override.`)}let isPermissionRecord=(value)=>typeof value==="object"&&value!==null,result=Object.fromEntries(agents.map((agent)=>{let sdkConfig={...agent.config,description:agent.description};if(resolution.primaryNames.has(agent.name)){sdkConfig.mode="primary";let mergedPermission={...isPermissionRecord(agent.config.permission)?agent.config.permission:void 0};delete mergedPermission.task,mergedPermission.task="allow",sdkConfig.permission=mergedPermission}else sdkConfig.mode="subagent";if(sdkConfig.mode==="primary")delete sdkConfig.model;let baseAgentName=stripKnownSwarmPrefix(agent.name);if(!toolFilterEnabled)return sdkConfig.tools=agent.config.tools??{},agentToolSnapshot[agent.name]=Object.keys(sdkConfig.tools??{}).filter((k)=>sdkConfig.tools[k]!==!1),[agent.name,sdkConfig];let allowedTools,override=toolFilterOverrides[baseAgentName];if(override!==void 0)allowedTools=override;else allowedTools=AGENT_TOOL_MAP[baseAgentName];if(config3?.memory?.enabled===!0){let memoryTools=MEMORY_AGENT_TOOL_MAP[baseAgentName]??[];if(memoryTools.length>0)allowedTools=Array.from(new Set([...allowedTools??[],...memoryTools]))}if(config3?.external_skills?.curation_enabled===!0){let externalSkillTools=EXTERNAL_SKILL_AGENT_TOOL_MAP[baseAgentName]??[];if(externalSkillTools.length>0)allowedTools=Array.from(new Set([...allowedTools??[],...externalSkillTools]))}if(config3?.council?.enabled===!0){let councilTools=COUNCIL_AGENT_TOOL_MAP[baseAgentName]??[];if(councilTools.length>0)allowedTools=Array.from(new Set([...allowedTools??[],...councilTools]))}if(config3?.council?.general?.enabled===!0){let generalCouncilTools=GENERAL_COUNCIL_AGENT_TOOL_MAP[baseAgentName]??[];if(generalCouncilTools.length>0)allowedTools=Array.from(new Set([...allowedTools??[],...generalCouncilTools]))}if(config3?.turbo!==void 0){let turboTools=TURBO_AGENT_TOOL_MAP[baseAgentName]??[];if(turboTools.length>0)allowedTools=Array.from(new Set([...allowedTools??[],...turboTools]))}{let skillTools=SKILL_AGENT_TOOL_MAP[baseAgentName]??[];if(skillTools.length>0&&allowedTools)if(config3?.skills?.enabled===!0)allowedTools=Array.from(new Set([...allowedTools,...skillTools]));else{let skillToolsSet=new Set(skillTools);allowedTools=allowedTools.filter((t)=>!skillToolsSet.has(t))}}if(!allowedTools&&!Object.hasOwn(toolFilterOverrides,baseAgentName)){if(!warnedMissingWhitelist.has(baseAgentName)&&!quiet)log(`[getAgentConfigs] Unknown agent '${baseAgentName}', defaulting to minimal toolset.`),warnedMissingWhitelist.add(baseAgentName)}let originalTools=agent.config.tools?{...agent.config.tools}:void 0;if(allowedTools){let filteredTools={...Object.fromEntries(Object.entries(originalTools??{}).filter(([,value])=>value===!1))};for(let tool3 of allowedTools){if(filteredTools[tool3]===!1)continue;filteredTools[tool3]=!0}sdkConfig.tools=filteredTools}else sdkConfig.tools={write:!1,edit:!1};return agentToolSnapshot[agent.name]=Object.keys(sdkConfig.tools??{}).filter((k)=>sdkConfig.tools[k]!==!1),[agent.name,sdkConfig]}));if(directory){let sid=sessionId??`init-${Date.now()}`,evidenceDir=path194.join(directory,".swarm","evidence"),filename=`agent-tools-${sid}.json`,snapshotPath=path194.join(evidenceDir,filename),snapshotData=JSON.stringify({sessionId:sid,generatedAt:new Date().toISOString(),agents:agentToolSnapshot},null,2);mkdir43(evidenceDir,{recursive:!0}).then(()=>writeFile26(snapshotPath,snapshotData)).then(()=>{invalidateCachedArtifact(snapshotPath)}).catch(()=>{})}return result}var _internals149,warnedAgents,NONTRANSIENT_STOP_PROTOCOL,_swarmAgentsMap,_emittedGatedAgentAdvisories,TYPE_A_AGENTS;var init_agents2=__esm(()=>{init_config();init_agent_model();init_constants();init_schema();init_planning_profile();init_warning_buffer();init_logger();init_swarm_artifact_cache();init_architect();init_coder();init_council_prompts();init_critic();init_curator_agent();init_designer();init_docs();init_explorer();init_researcher();init_reviewer();init_skill_improver2();init_sme();init_spec_writer();init_test_engineer();init_architect();init_coder();init_council_prompts();init_critic();init_curator_agent();init_designer();init_docs();init_explorer();init_researcher();init_reviewer();init_sme();init_test_engineer();_internals149={createAgents},warnedAgents=new Set,NONTRANSIENT_STOP_PROTOCOL=["","## NON-TRANSIENT TOOL FAILURE PROTOCOL — MANDATORY","Apply this protocol when a tool reports ParserError, ParseError, MissingEndCurlyBrace, CommandNotFoundException, a command-not-found/not-recognized error, or [sandbox] BLOCKED.","It also applies when guardrails report NON-TRANSIENT STOP or NON-TRANSIENT CIRCUIT BREAKER — including the third same-category permanent failure:","1. STOP. Do not retry the same operation with a different command, shell, tool, quoting style, or wrapper.","2. Treat the failure as structural, not transient. Do not spend retry budget on it.","3. Report BLOCKED with the exact error category and the command/tool that failed.","4. Wait for corrected input, environment, scope, or a verified new invocation before continuing."].join(`
5817
- `),_swarmAgentsMap=new Map,_emittedGatedAgentAdvisories=new Set;TYPE_A_AGENTS=[{name:"explorer",factory:createExplorerAgent},{name:"sme",factory:createSMEAgent},{name:"researcher",factory:createResearcherAgent},{name:"coder",factory:createCoderAgent},{name:"reviewer",factory:createReviewerAgent},{name:"test_engineer",factory:createTestEngineerAgent},{name:"docs",factory:createDocsAgent},{name:"skill_improver",factory:createSkillImproverAgent},{name:"spec_writer",factory:createSpecWriterAgent}]});var exports_evidence_summary_integration={};__export(exports_evidence_summary_integration,{createEvidenceSummaryIntegration:()=>createEvidenceSummaryIntegration,EvidenceSummaryIntegration:()=>EvidenceSummaryIntegration});import{existsSync as existsSync97,mkdirSync as mkdirSync53,writeFileSync as writeFileSync34}from"node:fs";import*as path195 from"node:path";function persistSummary(projectDir,artifact,filename){let swarmPath3=path195.join(projectDir,".swarm");if(!existsSync97(swarmPath3))mkdirSync53(swarmPath3,{recursive:!0});let artifactPath=path195.join(swarmPath3,filename),content=JSON.stringify(artifact,null,2);return writeFileSync34(artifactPath,content,"utf-8"),log("[EvidenceSummaryIntegration] Summary persisted",{path:artifactPath,size:content.length}),artifactPath}class EvidenceSummaryIntegration{config;eventBus;unsubscribes=[];constructor(config3){this.config=config3,this.eventBus=getGlobalEventBus()}isEnabled(){return isAutoSummaryEnabled(this.config.automationConfig)}initialize(){if(!this.isEnabled()){log("[EvidenceSummaryIntegration] Disabled via feature flags (evidence_auto_summaries=false or mode=manual)");return}log("[EvidenceSummaryIntegration] Initializing..."),this.subscribeToEvent("preflight.completed",async(event)=>{let phase=event.payload?.phase??1;await this.generateSummary(phase,"preflight.completed")}),this.subscribeToEvent("phase.boundary.detected",async(event)=>{let phase=event.payload?.currentPhase??1;await this.generateSummary(phase,"phase.boundary.detected")}),log("[EvidenceSummaryIntegration] Initialized and subscribed to events")}subscribeToEvent(type,handler){let unsubscribe2=this.eventBus.subscribe(type,handler);this.unsubscribes.push(unsubscribe2)}async generateSummary(phase,trigger){log("[EvidenceSummaryIntegration] Generating summary",{phase,trigger,directory:this.config.directory});try{let artifact=await buildEvidenceSummary(this.config.directory,phase);if(!artifact)return log("[EvidenceSummaryIntegration] No plan found, skipping"),null;let filename=this.config.summaryFilename??"evidence-summary.json",artifactPath=persistSummary(this.config.projectDir,artifact,filename);return log("[EvidenceSummaryIntegration] Summary generated and persisted",{path:artifactPath,completionRatio:artifact.overallCompletionRatio,blockers:artifact.overallBlockers.length}),await this.eventBus.publish("evidence.summary.generated",{trigger,phase,artifactPath,completionRatio:artifact.overallCompletionRatio,blockerCount:artifact.overallBlockers.length,timestamp:Date.now()}),artifact}catch(error93){return log("[EvidenceSummaryIntegration] Error generating summary",{error:error93 instanceof Error?error93.message:String(error93)}),await this.eventBus.publish("evidence.summary.error",{trigger,phase,error:error93 instanceof Error?error93.message:String(error93),timestamp:Date.now()}),null}}async triggerManual(phase){let isDisabled=!this.isEnabled();if(isDisabled)log("[EvidenceSummaryIntegration] Manual trigger with feature disabled - generating anyway for CLI use");return log("[EvidenceSummaryIntegration] Manual trigger",{phase,isDisabled}),this.generateSummary(phase??1,"preflight.completed")}cleanup(){for(let unsubscribe2 of this.unsubscribes)unsubscribe2();this.unsubscribes=[],log("[EvidenceSummaryIntegration] Cleanup complete")}}function createEvidenceSummaryIntegration(config3,autoInitialize=!0){let integration=new EvidenceSummaryIntegration(config3);if(autoInitialize)integration.initialize();return integration}var init_evidence_summary_integration=__esm(()=>{init_event_bus();init_evidence_summary_service();init_utils()});import*as path197 from"node:path";function projectSessionKey(directory,sessionID){return`${path197.resolve(directory)}\x00${sessionID.trim()}`}function rememberBounded(map3,key,value){map3.delete(key),map3.set(key,value);while(map3.size>MAX_TRACKED_PR_WORKFLOW_WAKE_STATES){let oldest=map3.keys().next().value;if(typeof oldest!=="string")break;map3.delete(oldest)}}function asRecord2(value){return typeof value==="object"&&value!==null?value:void 0}function eventEnvelope(event){return asRecord2(event.properties)??asRecord2(event.data)??{}}function eventSessionID(event){let envelope=eventEnvelope(event),info=asRecord2(envelope.info),candidate2=envelope.sessionID??envelope.sessionId??info?.sessionID??info?.sessionId??(event.type==="session.deleted"||event.type==="session.removed"?info?.id:void 0);return typeof candidate2==="string"&&candidate2.trim()?candidate2.trim():void 0}function isExactAbortEvent(event){let envelope=eventEnvelope(event);if(event.type==="session.error")return asRecord2(envelope.error)?.name==="MessageAbortedError";if(event.type!=="message.updated")return!1;let info=asRecord2(envelope.info);return info?.role==="assistant"&&asRecord2(info.error)?.name==="MessageAbortedError"}function isUserMessageEvent(event){if(event.type!=="message.updated")return!1;return asRecord2(eventEnvelope(event).info)?.role==="user"}function pruneMarkers(key,now2=Date.now()){let current=pluginWakeMarkers.get(key)??[],live=current.filter((marker)=>now2-marker.createdAt<=PLUGIN_WAKE_MARKER_TTL_MS);if(live.length===0)pluginWakeMarkers.delete(key);else if(live.length!==current.length)pluginWakeMarkers.set(key,live);return live}function consumePluginWakeMarker(key,messageID){let live=pruneMarkers(key),markerIndex=live.findIndex((marker)=>marker.messageID===messageID);if(markerIndex<0)return!1;if(live.splice(markerIndex,1),live.length===0)pluginWakeMarkers.delete(key);else rememberBounded(pluginWakeMarkers,key,live);return!0}function markPrWorkflowPluginWake(directory,sessionID){let key=projectSessionKey(directory,sessionID),messageID=`msg_swarm_wake_${Date.now().toString(36)}_${(++nextMarkerID).toString(36)}`,markers=pruneMarkers(key);return markers.push({messageID,createdAt:Date.now()}),rememberBounded(pluginWakeMarkers,key,markers),messageID}function cancelPrWorkflowPluginWake(directory,sessionID,messageID){let key=projectSessionKey(directory,sessionID),remaining=pruneMarkers(key).filter((marker)=>marker.messageID!==messageID);if(remaining.length===0)pluginWakeMarkers.delete(key);else rememberBounded(pluginWakeMarkers,key,remaining)}function isPrWorkflowAutoWakeSuppressed(directory,sessionID){return pauseStates.has(projectSessionKey(directory,sessionID))}function clearPrWorkflowAutoWakeState(directory,sessionID){pauseStates.delete(projectSessionKey(directory,sessionID))}function clearPrWorkflowAutoWakeSession(directory,sessionID){let key=projectSessionKey(directory,sessionID);pauseStates.delete(key),pluginWakeMarkers.delete(key)}async function observePrWorkflowAutoWakeEvent(directory,rawEvent){let event=asRecord2(rawEvent);if(!event)return{suppressWake:!1};let sessionID=eventSessionID(event);if(!sessionID)return{suppressWake:!1};let key=projectSessionKey(directory,sessionID);if(event.type==="session.deleted"||event.type==="session.removed")return clearPrWorkflowAutoWakeSession(directory,sessionID),{sessionID,suppressWake:!1};if(isExactAbortEvent(event)){rememberBounded(pauseStates,key,{phase:"awaiting-idle",pausedAt:Date.now()});try{if(await _internals150.readPrWorkflowGateState(directory,sessionID))return{sessionID,suppressWake:!0};return clearPrWorkflowAutoWakeState(directory,sessionID),{sessionID,suppressWake:!1}}catch{return{sessionID,suppressWake:!0}}}let paused=pauseStates.get(key);if(isUserMessageEvent(event)){let info=asRecord2(eventEnvelope(event).info),messageID=typeof info?.id==="string"?info.id:void 0;if(messageID&&consumePluginWakeMarker(key,messageID))return{sessionID,suppressWake:Boolean(paused)};if(paused)return rememberBounded(pauseStates,key,{...paused,phase:"resuming"}),{sessionID,suppressWake:!0};return{sessionID,suppressWake:!1}}if(event.type==="session.idle"&&paused){try{if(!await _internals150.readPrWorkflowGateState(directory,sessionID))return clearPrWorkflowAutoWakeState(directory,sessionID),{sessionID,suppressWake:!1}}catch{return{sessionID,suppressWake:!0}}let currentPause=pauseStates.get(key);if(!currentPause)return{sessionID,suppressWake:!0};if(currentPause.phase==="awaiting-idle")return rememberBounded(pauseStates,key,{...currentPause,phase:"paused"}),{sessionID,suppressWake:!0};if(currentPause.phase==="resuming")return pauseStates.delete(key),{sessionID,suppressWake:!0};return{sessionID,suppressWake:!0}}return{sessionID,suppressWake:Boolean(paused)}}var _internals150,MAX_TRACKED_PR_WORKFLOW_WAKE_STATES=200,PLUGIN_WAKE_MARKER_TTL_MS=60000,pauseStates,pluginWakeMarkers,nextMarkerID=0;var init_pr_workflow_auto_wake=__esm(()=>{init_pr_workflow_gate();_internals150={readPrWorkflowGateState},pauseStates=new Map,pluginWakeMarkers=new Map});import{randomUUID as randomUUID24}from"node:crypto";import*as fsp5 from"node:fs/promises";import*as path198 from"node:path";async function enqueuePrFeedbackMonitorEvent(directory,sessionID,event){let normalizedSessionID=normalizeSessionID2(sessionID),normalizedEvent=normalizeEvent(event);return withQueueMutation(directory,normalizedSessionID,async()=>{let current=await readPrFeedbackMonitorQueueFromDisk(directory,normalizedSessionID)??emptyQueueRecord(normalizedSessionID),events=[...current.events.filter((existing)=>existing.dedupToken!==normalizedEvent.dedupToken),normalizedEvent].slice(-MAX_PR_FEEDBACK_MONITOR_EVENTS),nextRecord=QueueRecordSchema.parse({...current,revision:current.revision+1,events});return await writeQueueRecord(directory,nextRecord),nextRecord})}async function readPrFeedbackMonitorQueue(directory,sessionID){let normalizedSessionID=normalizeSessionID2(sessionID),record3=await readPrFeedbackMonitorQueueFromDisk(directory,normalizedSessionID);return rememberQueue(directory,normalizedSessionID,record3),record3}async function claimPrFeedbackMonitorEvents(directory,sessionID,workflowInstanceId,prUrl,dedupTokens){let normalizedSessionID=normalizeSessionID2(sessionID),normalizedWorkflowInstanceId=workflowInstanceId.trim();if(!normalizedWorkflowInstanceId)throw Error("BLOCKED: PR feedback monitor queue claim requires a workflow instance id");let canonicalPrUrl=canonicalGitHubPrUrl2(prUrl);if(!canonicalPrUrl)throw Error("BLOCKED: PR feedback monitor queue claim requires a canonical GitHub PR URL");let selectedTokens=dedupTokens?new Set(dedupTokens.map((token)=>token.trim()).filter(Boolean)):null;if(selectedTokens&&selectedTokens.size===0)return[];return withQueueMutation(directory,normalizedSessionID,async()=>{let current=await readPrFeedbackMonitorQueueFromDisk(directory,normalizedSessionID);if(!current||current.events.length===0)return[];let claimedAt=new Date().toISOString(),changed2=!1,claimedEvents=current.events.map((event)=>{if(canonicalGitHubPrUrl2(event.prUrl)!==canonicalPrUrl||selectedTokens&&!selectedTokens.has(event.dedupToken))return event;if(event.claimedWorkflowInstanceId===normalizedWorkflowInstanceId)return event;if(event.claimedWorkflowInstanceId)return event;return changed2=!0,{...event,claimedWorkflowInstanceId:normalizedWorkflowInstanceId,claimedAt}});if(!changed2)return claimedEvents.filter((event)=>event.claimedWorkflowInstanceId===normalizedWorkflowInstanceId&&canonicalGitHubPrUrl2(event.prUrl)===canonicalPrUrl&&(!selectedTokens||selectedTokens.has(event.dedupToken)));let nextRecord=QueueRecordSchema.parse({...current,revision:current.revision+1,events:claimedEvents});return await writeQueueRecord(directory,nextRecord),nextRecord.events.filter((event)=>event.claimedWorkflowInstanceId===normalizedWorkflowInstanceId&&canonicalGitHubPrUrl2(event.prUrl)===canonicalPrUrl&&(!selectedTokens||selectedTokens.has(event.dedupToken)))})}function normalizeEvent(event){let parsed=PrFeedbackMonitorEventSchema.parse(event);if(!canonicalGitHubPrUrl2(parsed.prUrl))throw Error("BLOCKED: PR feedback monitor queue events require a canonical GitHub PR URL");return parsed}function emptyQueueRecord(sessionID){return{schemaVersion:1,revision:0,sessionID,events:[]}}async function writeQueueRecord(directory,record3){await ensureQueueDirectory(directory,!0);let filePath=validateSwarmPath(directory,queueRelativePath(record3.sessionID));await writePrWorkflowAtomicJson(directory,filePath,record3),rememberQueue(directory,record3.sessionID,record3)}async function withQueueMutation(directory,sessionID,action){let cacheKey=queueCacheKey(directory,sessionID),previous=pendingQueueMutationsByProjectSession.get(cacheKey)??Promise.resolve(),release,current=new Promise((resolve79)=>{release=resolve79}),queued=previous.then(()=>current);pendingQueueMutationsByProjectSession.set(cacheKey,queued),await previous;try{let lock=await acquireQueueLock(directory,sessionID);try{return await action()}finally{await releaseQueueLock(lock)}}finally{if(release(),pendingQueueMutationsByProjectSession.get(cacheKey)===queued)pendingQueueMutationsByProjectSession.delete(cacheKey)}}async function acquireQueueLock(directory,sessionID){let verifiedQueueDirectory=await ensureQueueDirectory(directory,!0);if(!verifiedQueueDirectory)throw Error("BLOCKED: PR feedback monitor queue directory is unavailable");let lockPath=validateSwarmPath(directory,queueLockRelativePath(sessionID));for(let attempt=0;attempt<LOCK_MAX_ATTEMPTS;attempt++)try{let handle=await fsp5.open(lockPath,"wx"),lock={ownerToken:randomUUID24(),pid:process.pid,createdAtMs:_internals151.nowMs()},writeError;try{await _internals151.beforeQueueLockWrite?.();let[openedStat,postQueueDirectory,pathStat,realLockPath]=await Promise.all([handle.stat({bigint:!0}),ensureQueueDirectory(directory,!1),fsp5.lstat(lockPath,{bigint:!0}),fsp5.realpath(lockPath)]);if(!postQueueDirectory||!openedStat.isFile()||pathStat.isSymbolicLink()||!pathStat.isFile()||!sameFileIdentity3(openedStat,pathStat)||normalizeComparablePath(postQueueDirectory)!==normalizeComparablePath(verifiedQueueDirectory)||normalizeComparablePath(path198.dirname(realLockPath))!==normalizeComparablePath(verifiedQueueDirectory))throw Error("BLOCKED: PR feedback monitor queue lock changed or escaped before initialization");await handle.writeFile(JSON.stringify(lock),"utf-8")}catch(error93){writeError=error93}finally{await handle.close().catch(()=>{return})}if(writeError)throw await removeQueueLockIfOwned(lockPath,lock.ownerToken),writeError;return{path:lockPath,ownerToken:lock.ownerToken}}catch(error93){if(error93.code!=="EEXIST")throw error93;if(await reclaimAbandonedQueueLock(lockPath))continue;if(attempt<LOCK_MAX_ATTEMPTS-1)await delay2(LOCK_RETRY_DELAY_MS)}throw Error("BLOCKED: PR feedback monitor queue is being mutated by another process; retry after that transition finishes")}async function releaseQueueLock(lock){try{await removeQueueLockIfOwned(lock.path,lock.ownerToken)}catch{}}async function reclaimAbandonedQueueLock(lockPath){let lock=await readQueueLock(lockPath);if(lock){if(_internals151.isProcessAlive(lock.pid))return!1;return removeQueueLockIfOwned(lockPath,lock.ownerToken)}try{let stat17=await fsp5.stat(lockPath);if(_internals151.nowMs()-stat17.mtimeMs<LOCK_UNINITIALIZED_STALE_MS)return!1;return await fsp5.rm(lockPath,{force:!0}),!0}catch(error93){if(error93.code==="ENOENT")return!0;throw error93}}async function readQueueLock(lockPath){let raw;try{raw=await fsp5.readFile(lockPath,"utf-8")}catch(error93){if(error93.code==="ENOENT")return null;throw error93}try{let parsed=JSON.parse(raw);if(typeof parsed==="object"&&parsed!==null&&typeof parsed.ownerToken==="string"&&parsed.ownerToken.length>0&&typeof parsed.pid==="number"&&Number.isInteger(parsed.pid)&&parsed.pid>0&&typeof parsed.createdAtMs==="number"&&Number.isFinite(parsed.createdAtMs))return parsed}catch{}return null}async function removeQueueLockIfOwned(lockPath,ownerToken){let lock=await readQueueLock(lockPath);if(!lock||lock.ownerToken!==ownerToken)return!1;try{return await fsp5.rm(lockPath),!0}catch(error93){if(error93.code==="ENOENT")return!1;throw error93}}function isProcessAlive4(pid){try{return process.kill(pid,0),!0}catch(error93){return error93.code!=="ESRCH"}}async function readPrFeedbackMonitorQueueFromDisk(directory,sessionID){let verifiedQueueDirectory=await ensureQueueDirectory(directory,!1);if(!verifiedQueueDirectory)return null;let filePath=validateSwarmPath(directory,queueRelativePath(sessionID)),handle,fileIdentity;try{let lstat8=await fsp5.lstat(filePath,{bigint:!0});if(lstat8.isSymbolicLink()||!lstat8.isFile()||lstat8.size>BigInt(MAX_QUEUE_BYTES))throw Error(`BLOCKED: PR feedback monitor queue for session "${sessionID}" must be a bounded regular file`);fileIdentity=lstat8,await _internals151.beforeQueueFileOpen?.(),handle=await fsp5.open(filePath,"r")}catch(error93){if(error93.code==="ENOENT")return null;throw error93}let raw;try{let stat17=await handle.stat({bigint:!0});if(!stat17.isFile()||stat17.size>BigInt(MAX_QUEUE_BYTES)||!sameFileIdentity3(fileIdentity,stat17))throw Error(`BLOCKED: PR feedback monitor queue for session "${sessionID}" changed during its bounded read`);let[postQueueDirectory,postPathStat,postRealPath]=await Promise.all([ensureQueueDirectory(directory,!1),fsp5.lstat(filePath,{bigint:!0}),fsp5.realpath(filePath)]);if(!postQueueDirectory||normalizeComparablePath(postQueueDirectory)!==normalizeComparablePath(verifiedQueueDirectory)||postPathStat.isSymbolicLink()||!postPathStat.isFile()||!sameFileIdentity3(fileIdentity,postPathStat)||!sameFileIdentity3(stat17,postPathStat)||normalizeComparablePath(path198.dirname(postRealPath))!==normalizeComparablePath(verifiedQueueDirectory))throw Error(`BLOCKED: PR feedback monitor queue for session "${sessionID}" changed or escaped during its bounded read`);let buffer=Buffer.allocUnsafe(MAX_QUEUE_BYTES+1),{bytesRead}=await handle.read(buffer,0,buffer.length,0);if(bytesRead>MAX_QUEUE_BYTES)throw Error(`BLOCKED: PR feedback monitor queue for session "${sessionID}" exceeds its size limit`);raw=buffer.subarray(0,bytesRead).toString("utf8")}finally{await handle.close()}let parsedJson;try{parsedJson=JSON.parse(raw)}catch{throw Error(`BLOCKED: PR feedback monitor queue for session "${sessionID}" is not valid JSON`)}let parsed=QueueRecordSchema.safeParse(parsedJson);if(!parsed.success)throw Error(`BLOCKED: PR feedback monitor queue for session "${sessionID}" is invalid`);return parsed.data}function sameFileIdentity3(left,right){return left.dev===right.dev&&left.ino===right.ino}async function ensureQueueDirectory(directory,create){let swarmRoot=path198.resolve(directory,".swarm"),queueDirectory=path198.join(swarmRoot,PR_FEEDBACK_EVENT_QUEUE_DIR);if(create)await ensurePrWorkflowSafeParentDirectory(directory,path198.join(queueDirectory,".containment-probe"));else try{await rejectUnsafeDirectory(swarmRoot,".swarm"),await rejectUnsafeDirectory(queueDirectory,`.swarm/${PR_FEEDBACK_EVENT_QUEUE_DIR}`)}catch(error93){if(error93.code==="ENOENT")return null;throw error93}await rejectUnsafeDirectory(queueDirectory,`.swarm/${PR_FEEDBACK_EVENT_QUEUE_DIR}`);let[realRoot,realQueue]=await Promise.all([fsp5.realpath(swarmRoot),fsp5.realpath(queueDirectory)]),expectedParent=normalizeComparablePath(realRoot);if(normalizeComparablePath(path198.dirname(realQueue))!==expectedParent)throw Error("BLOCKED: PR feedback monitor queue directory escapes the project .swarm root");return realQueue}async function rejectUnsafeDirectory(directoryPath,label){let stat17=await fsp5.lstat(directoryPath);if(stat17.isSymbolicLink()||!stat17.isDirectory())throw Error(`BLOCKED: PR feedback monitor queue ${label} path must be a real directory`)}function normalizeComparablePath(value){let normalized=path198.normalize(path198.resolve(value));return process.platform==="win32"?normalized.toLowerCase():normalized}function rememberQueue(directory,sessionID,record3){let cacheKey=queueCacheKey(directory,sessionID);trackedQueuesByProjectSession.delete(cacheKey),trackedQueuesByProjectSession.set(cacheKey,record3);while(trackedQueuesByProjectSession.size>MAX_TRACKED_SESSIONS2){let oldestKey=trackedQueuesByProjectSession.keys().next().value;if(!oldestKey)break;trackedQueuesByProjectSession.delete(oldestKey)}}function queueCacheKey(directory,sessionID){let resolved=path198.normalize(path198.resolve(directory));return`${process.platform==="win32"?resolved.toLowerCase():resolved}\x00${sessionID}`}function normalizeSessionID2(sessionID){let normalized=sessionID.trim();if(!normalized||normalized.length>512)throw Error("BLOCKED: PR feedback monitor queue requires a non-empty sessionID");return normalized}function canonicalGitHubPrUrl2(value){try{let url3=new URL(value),matched=url3.pathname.match(/^\/([^/]+)\/([^/]+)\/pull\/(\d+)\/?$/);if(url3.protocol!=="https:"||url3.hostname.toLowerCase()!=="github.com"||!matched)return null;let prNumber=Number(matched[3]);if(!Number.isSafeInteger(prNumber)||prNumber<=0)return null;return`github.com/${matched[1].toLowerCase()}/${matched[2].toLowerCase()}/pull/${prNumber}`}catch{return null}}function queueRelativePath(sessionID){return path198.join(PR_FEEDBACK_EVENT_QUEUE_DIR,`${prWorkflowSessionFileStem(sessionID)}.json`)}function queueLockRelativePath(sessionID){return path198.join(PR_FEEDBACK_EVENT_QUEUE_DIR,`${prWorkflowSessionFileStem(sessionID)}.lock`)}function delay2(ms){return new Promise((resolve79)=>setTimeout(resolve79,ms))}var PR_FEEDBACK_EVENT_QUEUE_DIR="pr-feedback-events",MAX_PR_FEEDBACK_MONITOR_EVENTS=20,MAX_QUEUE_BYTES=524288,MAX_TRACKED_SESSIONS2=200,LOCK_MAX_ATTEMPTS=50,LOCK_RETRY_DELAY_MS=10,LOCK_UNINITIALIZED_STALE_MS=30000,PrFeedbackMonitorEventSchema,QueueRecordSchema,trackedQueuesByProjectSession,pendingQueueMutationsByProjectSession,_internals151;var init_pr_feedback_event_queue=__esm(()=>{init_zod();init_pr_workflow_gate();init_utils2();PrFeedbackMonitorEventSchema=exports_external.object({type:exports_external.string().min(1).max(128),repoFullName:exports_external.string().min(1).max(512),prNumber:exports_external.number().int().positive(),prUrl:exports_external.string().url().max(2000),message:exports_external.string().min(1).max(20000),dedupToken:exports_external.string().min(1).max(512),authorized:exports_external.boolean(),queuedAt:exports_external.string().min(1),claimedWorkflowInstanceId:exports_external.string().min(1).max(128).optional(),claimedAt:exports_external.string().min(1).optional()}).strict(),QueueRecordSchema=exports_external.object({schemaVersion:exports_external.literal(1),revision:exports_external.number().int().nonnegative(),sessionID:exports_external.string().min(1),events:exports_external.array(PrFeedbackMonitorEventSchema).max(MAX_PR_FEEDBACK_MONITOR_EVENTS)}).strict(),trackedQueuesByProjectSession=new Map,pendingQueueMutationsByProjectSession=new Map;_internals151={queueRelativePath,queueLockRelativePath,resetQueueCache:()=>{trackedQueuesByProjectSession.clear(),pendingQueueMutationsByProjectSession.clear(),_internals151.beforeQueueFileOpen=void 0,_internals151.beforeQueueLockWrite=void 0},rename:fsp5.rename,nowMs:()=>Date.now(),isProcessAlive:isProcessAlive4,beforeQueueFileOpen:void 0,beforeQueueLockWrite:void 0}});var exports_pr_event_delivery={};__export(exports_pr_event_delivery,{unregisterPrEventDelivery:()=>unregisterPrEventDelivery,registerPrEventDelivery:()=>registerPrEventDelivery,noteSessionIdle:()=>noteSessionIdle,isPrEventDeliveryRegistered:()=>isPrEventDeliveryRegistered,deliverPrActivity:()=>deliverPrActivity,buildWakeMessage:()=>buildWakeMessage,_internals:()=>_internals152,_getTrackedSessionCount:()=>_getTrackedSessionCount,_getSessionQueueStats:()=>_getSessionQueueStats,WAKE_PROMPT_TIMEOUT_MS:()=>WAKE_PROMPT_TIMEOUT_MS,MAX_TRACKED_SESSIONS:()=>MAX_TRACKED_SESSIONS3,MAX_QUEUED_EVENTS_PER_SESSION:()=>MAX_QUEUED_EVENTS_PER_SESSION});function registerPrEventDelivery(options){registration=options,_internals152.log("[pr-monitor] Wake delivery registered",{directory:options.directory})}function unregisterPrEventDelivery(){registration=null,sessionStates2.clear()}function isPrEventDeliveryRegistered(){return registration!==null}function getSessionState2(sessionID){let state=sessionStates2.get(sessionID);if(!state){state={busy:!1,queue:[],droppedCount:0},sessionStates2.set(sessionID,state);while(sessionStates2.size>MAX_TRACKED_SESSIONS3){let oldest=sessionStates2.keys().next().value;if(oldest===void 0)break;sessionStates2.delete(oldest)}}return state}function enqueueBounded(state,events){for(let event of events){state.queue.push(event);while(state.queue.length>MAX_QUEUED_EVENTS_PER_SESSION)state.queue.shift(),state.droppedCount+=1}}async function deliverPrActivity(sessionID,events){try{if(!registration||!sessionID||events.length===0)return!1;let state=getSessionState2(sessionID),fresh=events.filter((event)=>!state.queue.some((queued)=>queued.dedupToken===event.dedupToken));if(fresh.length===0)return!0;if(state.busy||isPrWorkflowAutoWakeSuppressed(registration.directory,sessionID))return enqueueBounded(state,fresh),_internals152.log("[pr-monitor] Session busy — queued PR events",{sessionID,queued:state.queue.length,dropped:state.droppedCount}),!0;let previouslyQueued=state.queue.splice(0,state.queue.length),toSend=[...previouslyQueued,...fresh];if(state.busy=!0,!await sendWakePromptWithMarker(sessionID,toSend)){let current=sessionStates2.get(sessionID);if(current){if(current.busy=!1,previouslyQueued.length>0)enqueueBounded(current,previouslyQueued)}return!1}return!0}catch(err){return _internals152.log("[pr-monitor] deliverPrActivity failed",{error:err instanceof Error?err.message:String(err)}),!1}}function noteSessionIdle(sessionID){if(!registration||!sessionID)return;handleSessionIdle(sessionID).catch((err)=>{_internals152.log("[pr-monitor] noteSessionIdle failed",{error:err instanceof Error?err.message:String(err)})})}async function handleSessionIdle(sessionID){let active=registration;if(!active)return;let state=getSessionState2(sessionID);if(state.busy=!1,isPrWorkflowAutoWakeSuppressed(active.directory,sessionID))return;if(!active.config.auto_pr_feedback){if(state.queue.length===0)return;let queued=state.queue.splice(0,state.queue.length);if(state.busy=!0,!await sendWakePromptWithMarker(sessionID,queued))state.busy=!1,enqueueBounded(state,queued);return}let unclaimed=(await _internals152.readPrFeedbackMonitorQueue(active.directory,sessionID))?.events.filter((event)=>!event.claimedWorkflowInstanceId)??[],workflow=await _internals152.readPrWorkflowGateState(active.directory,sessionID),activatedFromQueue=!1;if(!workflow){let authorized=unclaimed.find((event)=>event.authorized);if(authorized)try{workflow=await _internals152.activatePrWorkflow(active.directory,sessionID,"PR_FEEDBACK",{requireCheckoutPreflight:!0,prUrl:authorized.prUrl}),activatedFromQueue=!0}catch(error93){_internals152.log("[pr-monitor] Deferred PR_FEEDBACK activation remains blocked",{sessionID,error:error93 instanceof Error?error93.message:String(error93)})}}let durableToSend=[],durablePrUrl;if(activatedFromQueue&&workflow?.mode==="PR_FEEDBACK"&&!workflow.prFeedbackInventory&&workflow.workflowInstanceId){let target=workflow.prFeedbackTargetUrl??workflow.prFeedbackReviewHandoff?.prUrl;if(target)durablePrUrl=target,durableToSend=unclaimed.filter((event)=>sameGitHubPr(event.prUrl,target)).map((event)=>({type:event.type,repoFullName:event.repoFullName,prNumber:event.prNumber,prUrl:event.prUrl,message:event.message,dedupToken:event.dedupToken}))}let inMemory=state.queue.splice(0,state.queue.length),toSend=dedupeFormattedEvents([...inMemory,...durableToSend]);if(toSend.length===0)return;if(state.busy=!0,!await sendWakePromptWithMarker(sessionID,toSend)){state.busy=!1,enqueueBounded(state,inMemory);return}if(durableToSend.length>0&&durablePrUrl&&workflow?.workflowInstanceId){let postWakeWorkflow=await _internals152.readPrWorkflowGateState(active.directory,sessionID),postWakeTarget=postWakeWorkflow?.prFeedbackTargetUrl??postWakeWorkflow?.prFeedbackReviewHandoff?.prUrl;if(postWakeWorkflow?.mode==="PR_FEEDBACK"&&postWakeWorkflow.workflowInstanceId===workflow.workflowInstanceId&&!postWakeWorkflow.prFeedbackInventory&&postWakeTarget&&sameGitHubPr(postWakeTarget,durablePrUrl))await _internals152.claimPrFeedbackMonitorEvents(active.directory,sessionID,workflow.workflowInstanceId,durablePrUrl,durableToSend.map((event)=>event.dedupToken))}}function dedupeFormattedEvents(events){let latestByToken=new Map;for(let event of events)latestByToken.delete(event.dedupToken),latestByToken.set(event.dedupToken,event);return[...latestByToken.values()].slice(-MAX_QUEUED_EVENTS_PER_SESSION)}function canonicalGitHubPrUrl3(value){try{let url3=new URL(value),match=url3.pathname.match(/^\/([^/]+)\/([^/]+)\/pull\/(\d+)\/?$/);if(url3.protocol!=="https:"||url3.hostname.toLowerCase()!=="github.com"||!match)return null;let number7=Number(match[3]);if(!Number.isSafeInteger(number7)||number7<=0)return null;return`github.com/${match[1].toLowerCase()}/${match[2].toLowerCase()}/pull/${number7}`}catch{return null}}function sameGitHubPr(left,right){let leftCanonical=canonicalGitHubPrUrl3(left);return leftCanonical!==null&&leftCanonical===canonicalGitHubPrUrl3(right)}async function sendWakePromptWithMarker(sessionID,events){let active=registration;if(!active)return!1;let messageID=markPrWorkflowPluginWake(active.directory,sessionID);return _internals152.sendWakePrompt(sessionID,events,messageID)}function sanitizeAttribute(value){return value.replace(/["<>\r\n]/g,"")}function sanitizeWakeBody(value){return value.replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\[(MODE|SYSTEM|DEVELOPER|USER|ASSISTANT)\s*:/gi,"($1:")}function buildWakeMessage(events){let groups=new Map;for(let event of events){let key=`${event.repoFullName}#${event.prNumber}`,group=groups.get(key);if(group)group.push(event);else groups.set(key,[event])}let blocks=[];for(let[prKey,groupEvents]of groups){let types2=[...new Set(groupEvents.map((e)=>e.type))].join(","),url3=sanitizeAttribute(groupEvents[0]?.prUrl??""),disposition=groupEvents.some((event)=>event.disposition==="queued-for-later")?"queued-for-later":"active",lines=groupEvents.map((e)=>sanitizeWakeBody(e.message)).join(`
5824
+ `),_swarmAgentsMap=new Map,_emittedGatedAgentAdvisories=new Set;TYPE_A_AGENTS=[{name:"explorer",factory:createExplorerAgent},{name:"sme",factory:createSMEAgent},{name:"researcher",factory:createResearcherAgent},{name:"coder",factory:createCoderAgent},{name:"reviewer",factory:createReviewerAgent},{name:"test_engineer",factory:createTestEngineerAgent},{name:"docs",factory:createDocsAgent},{name:"skill_improver",factory:createSkillImproverAgent},{name:"spec_writer",factory:createSpecWriterAgent}]});var exports_evidence_summary_integration={};__export(exports_evidence_summary_integration,{createEvidenceSummaryIntegration:()=>createEvidenceSummaryIntegration,EvidenceSummaryIntegration:()=>EvidenceSummaryIntegration});import{existsSync as existsSync98,mkdirSync as mkdirSync53,writeFileSync as writeFileSync34}from"node:fs";import*as path195 from"node:path";function persistSummary(projectDir,artifact,filename){let swarmPath3=path195.join(projectDir,".swarm");if(!existsSync98(swarmPath3))mkdirSync53(swarmPath3,{recursive:!0});let artifactPath=path195.join(swarmPath3,filename),content=JSON.stringify(artifact,null,2);return writeFileSync34(artifactPath,content,"utf-8"),log("[EvidenceSummaryIntegration] Summary persisted",{path:artifactPath,size:content.length}),artifactPath}class EvidenceSummaryIntegration{config;eventBus;unsubscribes=[];constructor(config3){this.config=config3,this.eventBus=getGlobalEventBus()}isEnabled(){return isAutoSummaryEnabled(this.config.automationConfig)}initialize(){if(!this.isEnabled()){log("[EvidenceSummaryIntegration] Disabled via feature flags (evidence_auto_summaries=false or mode=manual)");return}log("[EvidenceSummaryIntegration] Initializing..."),this.subscribeToEvent("preflight.completed",async(event)=>{let phase=event.payload?.phase??1;await this.generateSummary(phase,"preflight.completed")}),this.subscribeToEvent("phase.boundary.detected",async(event)=>{let phase=event.payload?.currentPhase??1;await this.generateSummary(phase,"phase.boundary.detected")}),log("[EvidenceSummaryIntegration] Initialized and subscribed to events")}subscribeToEvent(type,handler){let unsubscribe2=this.eventBus.subscribe(type,handler);this.unsubscribes.push(unsubscribe2)}async generateSummary(phase,trigger){log("[EvidenceSummaryIntegration] Generating summary",{phase,trigger,directory:this.config.directory});try{let artifact=await buildEvidenceSummary(this.config.directory,phase);if(!artifact)return log("[EvidenceSummaryIntegration] No plan found, skipping"),null;let filename=this.config.summaryFilename??"evidence-summary.json",artifactPath=persistSummary(this.config.projectDir,artifact,filename);return log("[EvidenceSummaryIntegration] Summary generated and persisted",{path:artifactPath,completionRatio:artifact.overallCompletionRatio,blockers:artifact.overallBlockers.length}),await this.eventBus.publish("evidence.summary.generated",{trigger,phase,artifactPath,completionRatio:artifact.overallCompletionRatio,blockerCount:artifact.overallBlockers.length,timestamp:Date.now()}),artifact}catch(error93){return log("[EvidenceSummaryIntegration] Error generating summary",{error:error93 instanceof Error?error93.message:String(error93)}),await this.eventBus.publish("evidence.summary.error",{trigger,phase,error:error93 instanceof Error?error93.message:String(error93),timestamp:Date.now()}),null}}async triggerManual(phase){let isDisabled=!this.isEnabled();if(isDisabled)log("[EvidenceSummaryIntegration] Manual trigger with feature disabled - generating anyway for CLI use");return log("[EvidenceSummaryIntegration] Manual trigger",{phase,isDisabled}),this.generateSummary(phase??1,"preflight.completed")}cleanup(){for(let unsubscribe2 of this.unsubscribes)unsubscribe2();this.unsubscribes=[],log("[EvidenceSummaryIntegration] Cleanup complete")}}function createEvidenceSummaryIntegration(config3,autoInitialize=!0){let integration=new EvidenceSummaryIntegration(config3);if(autoInitialize)integration.initialize();return integration}var init_evidence_summary_integration=__esm(()=>{init_event_bus();init_evidence_summary_service();init_utils()});import*as path197 from"node:path";function projectSessionKey(directory,sessionID){return`${path197.resolve(directory)}\x00${sessionID.trim()}`}function rememberBounded(map3,key,value){map3.delete(key),map3.set(key,value);while(map3.size>MAX_TRACKED_PR_WORKFLOW_WAKE_STATES){let oldest=map3.keys().next().value;if(typeof oldest!=="string")break;map3.delete(oldest)}}function asRecord2(value){return typeof value==="object"&&value!==null?value:void 0}function eventEnvelope(event){return asRecord2(event.properties)??asRecord2(event.data)??{}}function eventSessionID(event){let envelope=eventEnvelope(event),info=asRecord2(envelope.info),candidate2=envelope.sessionID??envelope.sessionId??info?.sessionID??info?.sessionId??(event.type==="session.deleted"||event.type==="session.removed"?info?.id:void 0);return typeof candidate2==="string"&&candidate2.trim()?candidate2.trim():void 0}function isExactAbortEvent(event){let envelope=eventEnvelope(event);if(event.type==="session.error")return asRecord2(envelope.error)?.name==="MessageAbortedError";if(event.type!=="message.updated")return!1;let info=asRecord2(envelope.info);return info?.role==="assistant"&&asRecord2(info.error)?.name==="MessageAbortedError"}function isUserMessageEvent(event){if(event.type!=="message.updated")return!1;return asRecord2(eventEnvelope(event).info)?.role==="user"}function pruneMarkers(key,now2=Date.now()){let current=pluginWakeMarkers.get(key)??[],live=current.filter((marker)=>now2-marker.createdAt<=PLUGIN_WAKE_MARKER_TTL_MS);if(live.length===0)pluginWakeMarkers.delete(key);else if(live.length!==current.length)pluginWakeMarkers.set(key,live);return live}function consumePluginWakeMarker(key,messageID){let live=pruneMarkers(key),markerIndex=live.findIndex((marker)=>marker.messageID===messageID);if(markerIndex<0)return!1;if(live.splice(markerIndex,1),live.length===0)pluginWakeMarkers.delete(key);else rememberBounded(pluginWakeMarkers,key,live);return!0}function markPrWorkflowPluginWake(directory,sessionID){let key=projectSessionKey(directory,sessionID),messageID=`msg_swarm_wake_${Date.now().toString(36)}_${(++nextMarkerID).toString(36)}`,markers=pruneMarkers(key);return markers.push({messageID,createdAt:Date.now()}),rememberBounded(pluginWakeMarkers,key,markers),messageID}function cancelPrWorkflowPluginWake(directory,sessionID,messageID){let key=projectSessionKey(directory,sessionID),remaining=pruneMarkers(key).filter((marker)=>marker.messageID!==messageID);if(remaining.length===0)pluginWakeMarkers.delete(key);else rememberBounded(pluginWakeMarkers,key,remaining)}function isPrWorkflowAutoWakeSuppressed(directory,sessionID){return pauseStates.has(projectSessionKey(directory,sessionID))}function clearPrWorkflowAutoWakeState(directory,sessionID){pauseStates.delete(projectSessionKey(directory,sessionID))}function clearPrWorkflowAutoWakeSession(directory,sessionID){let key=projectSessionKey(directory,sessionID);pauseStates.delete(key),pluginWakeMarkers.delete(key)}async function observePrWorkflowAutoWakeEvent(directory,rawEvent){let event=asRecord2(rawEvent);if(!event)return{suppressWake:!1};let sessionID=eventSessionID(event);if(!sessionID)return{suppressWake:!1};let key=projectSessionKey(directory,sessionID);if(event.type==="session.deleted"||event.type==="session.removed")return clearPrWorkflowAutoWakeSession(directory,sessionID),{sessionID,suppressWake:!1};if(isExactAbortEvent(event)){rememberBounded(pauseStates,key,{phase:"awaiting-idle",pausedAt:Date.now()});try{if(await _internals150.readPrWorkflowGateState(directory,sessionID))return{sessionID,suppressWake:!0};return clearPrWorkflowAutoWakeState(directory,sessionID),{sessionID,suppressWake:!1}}catch{return{sessionID,suppressWake:!0}}}let paused=pauseStates.get(key);if(isUserMessageEvent(event)){let info=asRecord2(eventEnvelope(event).info),messageID=typeof info?.id==="string"?info.id:void 0;if(messageID&&consumePluginWakeMarker(key,messageID))return{sessionID,suppressWake:Boolean(paused)};if(paused)return rememberBounded(pauseStates,key,{...paused,phase:"resuming"}),{sessionID,suppressWake:!0};return{sessionID,suppressWake:!1}}if(event.type==="session.idle"&&paused){try{if(!await _internals150.readPrWorkflowGateState(directory,sessionID))return clearPrWorkflowAutoWakeState(directory,sessionID),{sessionID,suppressWake:!1}}catch{return{sessionID,suppressWake:!0}}let currentPause=pauseStates.get(key);if(!currentPause)return{sessionID,suppressWake:!0};if(currentPause.phase==="awaiting-idle")return rememberBounded(pauseStates,key,{...currentPause,phase:"paused"}),{sessionID,suppressWake:!0};if(currentPause.phase==="resuming")return pauseStates.delete(key),{sessionID,suppressWake:!0};return{sessionID,suppressWake:!0}}return{sessionID,suppressWake:Boolean(paused)}}var _internals150,MAX_TRACKED_PR_WORKFLOW_WAKE_STATES=200,PLUGIN_WAKE_MARKER_TTL_MS=60000,pauseStates,pluginWakeMarkers,nextMarkerID=0;var init_pr_workflow_auto_wake=__esm(()=>{init_pr_workflow_gate();_internals150={readPrWorkflowGateState},pauseStates=new Map,pluginWakeMarkers=new Map});import{randomUUID as randomUUID24}from"node:crypto";import*as fsp5 from"node:fs/promises";import*as path198 from"node:path";async function enqueuePrFeedbackMonitorEvent(directory,sessionID,event){let normalizedSessionID=normalizeSessionID2(sessionID),normalizedEvent=normalizeEvent(event);return withQueueMutation(directory,normalizedSessionID,async()=>{let current=await readPrFeedbackMonitorQueueFromDisk(directory,normalizedSessionID)??emptyQueueRecord(normalizedSessionID),events=[...current.events.filter((existing)=>existing.dedupToken!==normalizedEvent.dedupToken),normalizedEvent].slice(-MAX_PR_FEEDBACK_MONITOR_EVENTS),nextRecord=QueueRecordSchema.parse({...current,revision:current.revision+1,events});return await writeQueueRecord(directory,nextRecord),nextRecord})}async function readPrFeedbackMonitorQueue(directory,sessionID){let normalizedSessionID=normalizeSessionID2(sessionID),record3=await readPrFeedbackMonitorQueueFromDisk(directory,normalizedSessionID);return rememberQueue(directory,normalizedSessionID,record3),record3}async function claimPrFeedbackMonitorEvents(directory,sessionID,workflowInstanceId,prUrl,dedupTokens){let normalizedSessionID=normalizeSessionID2(sessionID),normalizedWorkflowInstanceId=workflowInstanceId.trim();if(!normalizedWorkflowInstanceId)throw Error("BLOCKED: PR feedback monitor queue claim requires a workflow instance id");let canonicalPrUrl=canonicalGitHubPrUrl2(prUrl);if(!canonicalPrUrl)throw Error("BLOCKED: PR feedback monitor queue claim requires a canonical GitHub PR URL");let selectedTokens=dedupTokens?new Set(dedupTokens.map((token)=>token.trim()).filter(Boolean)):null;if(selectedTokens&&selectedTokens.size===0)return[];return withQueueMutation(directory,normalizedSessionID,async()=>{let current=await readPrFeedbackMonitorQueueFromDisk(directory,normalizedSessionID);if(!current||current.events.length===0)return[];let claimedAt=new Date().toISOString(),changed2=!1,claimedEvents=current.events.map((event)=>{if(canonicalGitHubPrUrl2(event.prUrl)!==canonicalPrUrl||selectedTokens&&!selectedTokens.has(event.dedupToken))return event;if(event.claimedWorkflowInstanceId===normalizedWorkflowInstanceId)return event;if(event.claimedWorkflowInstanceId)return event;return changed2=!0,{...event,claimedWorkflowInstanceId:normalizedWorkflowInstanceId,claimedAt}});if(!changed2)return claimedEvents.filter((event)=>event.claimedWorkflowInstanceId===normalizedWorkflowInstanceId&&canonicalGitHubPrUrl2(event.prUrl)===canonicalPrUrl&&(!selectedTokens||selectedTokens.has(event.dedupToken)));let nextRecord=QueueRecordSchema.parse({...current,revision:current.revision+1,events:claimedEvents});return await writeQueueRecord(directory,nextRecord),nextRecord.events.filter((event)=>event.claimedWorkflowInstanceId===normalizedWorkflowInstanceId&&canonicalGitHubPrUrl2(event.prUrl)===canonicalPrUrl&&(!selectedTokens||selectedTokens.has(event.dedupToken)))})}function normalizeEvent(event){let parsed=PrFeedbackMonitorEventSchema.parse(event);if(!canonicalGitHubPrUrl2(parsed.prUrl))throw Error("BLOCKED: PR feedback monitor queue events require a canonical GitHub PR URL");return parsed}function emptyQueueRecord(sessionID){return{schemaVersion:1,revision:0,sessionID,events:[]}}async function writeQueueRecord(directory,record3){await ensureQueueDirectory(directory,!0);let filePath=validateSwarmPath(directory,queueRelativePath(record3.sessionID));await writePrWorkflowAtomicJson(directory,filePath,record3),rememberQueue(directory,record3.sessionID,record3)}async function withQueueMutation(directory,sessionID,action){let cacheKey=queueCacheKey(directory,sessionID),previous=pendingQueueMutationsByProjectSession.get(cacheKey)??Promise.resolve(),release,current=new Promise((resolve79)=>{release=resolve79}),queued=previous.then(()=>current);pendingQueueMutationsByProjectSession.set(cacheKey,queued),await previous;try{let lock=await acquireQueueLock(directory,sessionID);try{return await action()}finally{await releaseQueueLock(lock)}}finally{if(release(),pendingQueueMutationsByProjectSession.get(cacheKey)===queued)pendingQueueMutationsByProjectSession.delete(cacheKey)}}async function acquireQueueLock(directory,sessionID){let verifiedQueueDirectory=await ensureQueueDirectory(directory,!0);if(!verifiedQueueDirectory)throw Error("BLOCKED: PR feedback monitor queue directory is unavailable");let lockPath=validateSwarmPath(directory,queueLockRelativePath(sessionID));for(let attempt=0;attempt<LOCK_MAX_ATTEMPTS;attempt++)try{let handle=await fsp5.open(lockPath,"wx"),lock={ownerToken:randomUUID24(),pid:process.pid,createdAtMs:_internals151.nowMs()},writeError;try{await _internals151.beforeQueueLockWrite?.();let[openedStat,postQueueDirectory,pathStat,realLockPath]=await Promise.all([handle.stat({bigint:!0}),ensureQueueDirectory(directory,!1),fsp5.lstat(lockPath,{bigint:!0}),fsp5.realpath(lockPath)]);if(!postQueueDirectory||!openedStat.isFile()||pathStat.isSymbolicLink()||!pathStat.isFile()||!sameFileIdentity3(openedStat,pathStat)||normalizeComparablePath(postQueueDirectory)!==normalizeComparablePath(verifiedQueueDirectory)||normalizeComparablePath(path198.dirname(realLockPath))!==normalizeComparablePath(verifiedQueueDirectory))throw Error("BLOCKED: PR feedback monitor queue lock changed or escaped before initialization");await handle.writeFile(JSON.stringify(lock),"utf-8")}catch(error93){writeError=error93}finally{await handle.close().catch(()=>{return})}if(writeError)throw await removeQueueLockIfOwned(lockPath,lock.ownerToken),writeError;return{path:lockPath,ownerToken:lock.ownerToken}}catch(error93){if(error93.code!=="EEXIST")throw error93;if(await reclaimAbandonedQueueLock(lockPath))continue;if(attempt<LOCK_MAX_ATTEMPTS-1)await delay2(LOCK_RETRY_DELAY_MS)}throw Error("BLOCKED: PR feedback monitor queue is being mutated by another process; retry after that transition finishes")}async function releaseQueueLock(lock){try{await removeQueueLockIfOwned(lock.path,lock.ownerToken)}catch{}}async function reclaimAbandonedQueueLock(lockPath){let lock=await readQueueLock(lockPath);if(lock){if(_internals151.isProcessAlive(lock.pid))return!1;return removeQueueLockIfOwned(lockPath,lock.ownerToken)}try{let stat17=await fsp5.stat(lockPath);if(_internals151.nowMs()-stat17.mtimeMs<LOCK_UNINITIALIZED_STALE_MS)return!1;return await fsp5.rm(lockPath,{force:!0}),!0}catch(error93){if(error93.code==="ENOENT")return!0;throw error93}}async function readQueueLock(lockPath){let raw;try{raw=await fsp5.readFile(lockPath,"utf-8")}catch(error93){if(error93.code==="ENOENT")return null;throw error93}try{let parsed=JSON.parse(raw);if(typeof parsed==="object"&&parsed!==null&&typeof parsed.ownerToken==="string"&&parsed.ownerToken.length>0&&typeof parsed.pid==="number"&&Number.isInteger(parsed.pid)&&parsed.pid>0&&typeof parsed.createdAtMs==="number"&&Number.isFinite(parsed.createdAtMs))return parsed}catch{}return null}async function removeQueueLockIfOwned(lockPath,ownerToken){let lock=await readQueueLock(lockPath);if(!lock||lock.ownerToken!==ownerToken)return!1;try{return await fsp5.rm(lockPath),!0}catch(error93){if(error93.code==="ENOENT")return!1;throw error93}}function isProcessAlive4(pid){try{return process.kill(pid,0),!0}catch(error93){return error93.code!=="ESRCH"}}async function readPrFeedbackMonitorQueueFromDisk(directory,sessionID){let verifiedQueueDirectory=await ensureQueueDirectory(directory,!1);if(!verifiedQueueDirectory)return null;let filePath=validateSwarmPath(directory,queueRelativePath(sessionID)),handle,fileIdentity;try{let lstat8=await fsp5.lstat(filePath,{bigint:!0});if(lstat8.isSymbolicLink()||!lstat8.isFile()||lstat8.size>BigInt(MAX_QUEUE_BYTES))throw Error(`BLOCKED: PR feedback monitor queue for session "${sessionID}" must be a bounded regular file`);fileIdentity=lstat8,await _internals151.beforeQueueFileOpen?.(),handle=await fsp5.open(filePath,"r")}catch(error93){if(error93.code==="ENOENT")return null;throw error93}let raw;try{let stat17=await handle.stat({bigint:!0});if(!stat17.isFile()||stat17.size>BigInt(MAX_QUEUE_BYTES)||!sameFileIdentity3(fileIdentity,stat17))throw Error(`BLOCKED: PR feedback monitor queue for session "${sessionID}" changed during its bounded read`);let[postQueueDirectory,postPathStat,postRealPath]=await Promise.all([ensureQueueDirectory(directory,!1),fsp5.lstat(filePath,{bigint:!0}),fsp5.realpath(filePath)]);if(!postQueueDirectory||normalizeComparablePath(postQueueDirectory)!==normalizeComparablePath(verifiedQueueDirectory)||postPathStat.isSymbolicLink()||!postPathStat.isFile()||!sameFileIdentity3(fileIdentity,postPathStat)||!sameFileIdentity3(stat17,postPathStat)||normalizeComparablePath(path198.dirname(postRealPath))!==normalizeComparablePath(verifiedQueueDirectory))throw Error(`BLOCKED: PR feedback monitor queue for session "${sessionID}" changed or escaped during its bounded read`);let buffer=Buffer.allocUnsafe(MAX_QUEUE_BYTES+1),{bytesRead}=await handle.read(buffer,0,buffer.length,0);if(bytesRead>MAX_QUEUE_BYTES)throw Error(`BLOCKED: PR feedback monitor queue for session "${sessionID}" exceeds its size limit`);raw=buffer.subarray(0,bytesRead).toString("utf8")}finally{await handle.close()}let parsedJson;try{parsedJson=JSON.parse(raw)}catch{throw Error(`BLOCKED: PR feedback monitor queue for session "${sessionID}" is not valid JSON`)}let parsed=QueueRecordSchema.safeParse(parsedJson);if(!parsed.success)throw Error(`BLOCKED: PR feedback monitor queue for session "${sessionID}" is invalid`);return parsed.data}function sameFileIdentity3(left,right){return left.dev===right.dev&&left.ino===right.ino}async function ensureQueueDirectory(directory,create){let swarmRoot=path198.resolve(directory,".swarm"),queueDirectory=path198.join(swarmRoot,PR_FEEDBACK_EVENT_QUEUE_DIR);if(create)await ensurePrWorkflowSafeParentDirectory(directory,path198.join(queueDirectory,".containment-probe"));else try{await rejectUnsafeDirectory(swarmRoot,".swarm"),await rejectUnsafeDirectory(queueDirectory,`.swarm/${PR_FEEDBACK_EVENT_QUEUE_DIR}`)}catch(error93){if(error93.code==="ENOENT")return null;throw error93}await rejectUnsafeDirectory(queueDirectory,`.swarm/${PR_FEEDBACK_EVENT_QUEUE_DIR}`);let[realRoot,realQueue]=await Promise.all([fsp5.realpath(swarmRoot),fsp5.realpath(queueDirectory)]),expectedParent=normalizeComparablePath(realRoot);if(normalizeComparablePath(path198.dirname(realQueue))!==expectedParent)throw Error("BLOCKED: PR feedback monitor queue directory escapes the project .swarm root");return realQueue}async function rejectUnsafeDirectory(directoryPath,label){let stat17=await fsp5.lstat(directoryPath);if(stat17.isSymbolicLink()||!stat17.isDirectory())throw Error(`BLOCKED: PR feedback monitor queue ${label} path must be a real directory`)}function normalizeComparablePath(value){let normalized=path198.normalize(path198.resolve(value));return process.platform==="win32"?normalized.toLowerCase():normalized}function rememberQueue(directory,sessionID,record3){let cacheKey=queueCacheKey(directory,sessionID);trackedQueuesByProjectSession.delete(cacheKey),trackedQueuesByProjectSession.set(cacheKey,record3);while(trackedQueuesByProjectSession.size>MAX_TRACKED_SESSIONS2){let oldestKey=trackedQueuesByProjectSession.keys().next().value;if(!oldestKey)break;trackedQueuesByProjectSession.delete(oldestKey)}}function queueCacheKey(directory,sessionID){let resolved=path198.normalize(path198.resolve(directory));return`${process.platform==="win32"?resolved.toLowerCase():resolved}\x00${sessionID}`}function normalizeSessionID2(sessionID){let normalized=sessionID.trim();if(!normalized||normalized.length>512)throw Error("BLOCKED: PR feedback monitor queue requires a non-empty sessionID");return normalized}function canonicalGitHubPrUrl2(value){try{let url3=new URL(value),matched=url3.pathname.match(/^\/([^/]+)\/([^/]+)\/pull\/(\d+)\/?$/);if(url3.protocol!=="https:"||url3.hostname.toLowerCase()!=="github.com"||!matched)return null;let prNumber=Number(matched[3]);if(!Number.isSafeInteger(prNumber)||prNumber<=0)return null;return`github.com/${matched[1].toLowerCase()}/${matched[2].toLowerCase()}/pull/${prNumber}`}catch{return null}}function queueRelativePath(sessionID){return path198.join(PR_FEEDBACK_EVENT_QUEUE_DIR,`${prWorkflowSessionFileStem(sessionID)}.json`)}function queueLockRelativePath(sessionID){return path198.join(PR_FEEDBACK_EVENT_QUEUE_DIR,`${prWorkflowSessionFileStem(sessionID)}.lock`)}function delay2(ms){return new Promise((resolve79)=>setTimeout(resolve79,ms))}var PR_FEEDBACK_EVENT_QUEUE_DIR="pr-feedback-events",MAX_PR_FEEDBACK_MONITOR_EVENTS=20,MAX_QUEUE_BYTES=524288,MAX_TRACKED_SESSIONS2=200,LOCK_MAX_ATTEMPTS=50,LOCK_RETRY_DELAY_MS=10,LOCK_UNINITIALIZED_STALE_MS=30000,PrFeedbackMonitorEventSchema,QueueRecordSchema,trackedQueuesByProjectSession,pendingQueueMutationsByProjectSession,_internals151;var init_pr_feedback_event_queue=__esm(()=>{init_zod();init_pr_workflow_gate();init_utils2();PrFeedbackMonitorEventSchema=exports_external.object({type:exports_external.string().min(1).max(128),repoFullName:exports_external.string().min(1).max(512),prNumber:exports_external.number().int().positive(),prUrl:exports_external.string().url().max(2000),message:exports_external.string().min(1).max(20000),dedupToken:exports_external.string().min(1).max(512),authorized:exports_external.boolean(),queuedAt:exports_external.string().min(1),claimedWorkflowInstanceId:exports_external.string().min(1).max(128).optional(),claimedAt:exports_external.string().min(1).optional()}).strict(),QueueRecordSchema=exports_external.object({schemaVersion:exports_external.literal(1),revision:exports_external.number().int().nonnegative(),sessionID:exports_external.string().min(1),events:exports_external.array(PrFeedbackMonitorEventSchema).max(MAX_PR_FEEDBACK_MONITOR_EVENTS)}).strict(),trackedQueuesByProjectSession=new Map,pendingQueueMutationsByProjectSession=new Map;_internals151={queueRelativePath,queueLockRelativePath,resetQueueCache:()=>{trackedQueuesByProjectSession.clear(),pendingQueueMutationsByProjectSession.clear(),_internals151.beforeQueueFileOpen=void 0,_internals151.beforeQueueLockWrite=void 0},rename:fsp5.rename,nowMs:()=>Date.now(),isProcessAlive:isProcessAlive4,beforeQueueFileOpen:void 0,beforeQueueLockWrite:void 0}});var exports_pr_event_delivery={};__export(exports_pr_event_delivery,{unregisterPrEventDelivery:()=>unregisterPrEventDelivery,registerPrEventDelivery:()=>registerPrEventDelivery,noteSessionIdle:()=>noteSessionIdle,isPrEventDeliveryRegistered:()=>isPrEventDeliveryRegistered,deliverPrActivity:()=>deliverPrActivity,buildWakeMessage:()=>buildWakeMessage,_internals:()=>_internals152,_getTrackedSessionCount:()=>_getTrackedSessionCount,_getSessionQueueStats:()=>_getSessionQueueStats,WAKE_PROMPT_TIMEOUT_MS:()=>WAKE_PROMPT_TIMEOUT_MS,MAX_TRACKED_SESSIONS:()=>MAX_TRACKED_SESSIONS3,MAX_QUEUED_EVENTS_PER_SESSION:()=>MAX_QUEUED_EVENTS_PER_SESSION});function registerPrEventDelivery(options){registration=options,_internals152.log("[pr-monitor] Wake delivery registered",{directory:options.directory})}function unregisterPrEventDelivery(){registration=null,sessionStates2.clear()}function isPrEventDeliveryRegistered(){return registration!==null}function getSessionState2(sessionID){let state=sessionStates2.get(sessionID);if(!state){state={busy:!1,queue:[],droppedCount:0},sessionStates2.set(sessionID,state);while(sessionStates2.size>MAX_TRACKED_SESSIONS3){let oldest=sessionStates2.keys().next().value;if(oldest===void 0)break;sessionStates2.delete(oldest)}}return state}function enqueueBounded(state,events){for(let event of events){state.queue.push(event);while(state.queue.length>MAX_QUEUED_EVENTS_PER_SESSION)state.queue.shift(),state.droppedCount+=1}}async function deliverPrActivity(sessionID,events){try{if(!registration||!sessionID||events.length===0)return!1;let state=getSessionState2(sessionID),fresh=events.filter((event)=>!state.queue.some((queued)=>queued.dedupToken===event.dedupToken));if(fresh.length===0)return!0;if(state.busy||isPrWorkflowAutoWakeSuppressed(registration.directory,sessionID))return enqueueBounded(state,fresh),_internals152.log("[pr-monitor] Session busy — queued PR events",{sessionID,queued:state.queue.length,dropped:state.droppedCount}),!0;let previouslyQueued=state.queue.splice(0,state.queue.length),toSend=[...previouslyQueued,...fresh];if(state.busy=!0,!await sendWakePromptWithMarker(sessionID,toSend)){let current=sessionStates2.get(sessionID);if(current){if(current.busy=!1,previouslyQueued.length>0)enqueueBounded(current,previouslyQueued)}return!1}return!0}catch(err){return _internals152.log("[pr-monitor] deliverPrActivity failed",{error:err instanceof Error?err.message:String(err)}),!1}}function noteSessionIdle(sessionID){if(!registration||!sessionID)return;handleSessionIdle(sessionID).catch((err)=>{_internals152.log("[pr-monitor] noteSessionIdle failed",{error:err instanceof Error?err.message:String(err)})})}async function handleSessionIdle(sessionID){let active=registration;if(!active)return;let state=getSessionState2(sessionID);if(state.busy=!1,isPrWorkflowAutoWakeSuppressed(active.directory,sessionID))return;if(!active.config.auto_pr_feedback){if(state.queue.length===0)return;let queued=state.queue.splice(0,state.queue.length);if(state.busy=!0,!await sendWakePromptWithMarker(sessionID,queued))state.busy=!1,enqueueBounded(state,queued);return}let unclaimed=(await _internals152.readPrFeedbackMonitorQueue(active.directory,sessionID))?.events.filter((event)=>!event.claimedWorkflowInstanceId)??[],workflow=await _internals152.readPrWorkflowGateState(active.directory,sessionID),activatedFromQueue=!1;if(!workflow){let authorized=unclaimed.find((event)=>event.authorized);if(authorized)try{workflow=await _internals152.activatePrWorkflow(active.directory,sessionID,"PR_FEEDBACK",{requireCheckoutPreflight:!0,prUrl:authorized.prUrl}),activatedFromQueue=!0}catch(error93){_internals152.log("[pr-monitor] Deferred PR_FEEDBACK activation remains blocked",{sessionID,error:error93 instanceof Error?error93.message:String(error93)})}}let durableToSend=[],durablePrUrl;if(activatedFromQueue&&workflow?.mode==="PR_FEEDBACK"&&!workflow.prFeedbackInventory&&workflow.workflowInstanceId){let target=workflow.prFeedbackTargetUrl??workflow.prFeedbackReviewHandoff?.prUrl;if(target)durablePrUrl=target,durableToSend=unclaimed.filter((event)=>sameGitHubPr(event.prUrl,target)).map((event)=>({type:event.type,repoFullName:event.repoFullName,prNumber:event.prNumber,prUrl:event.prUrl,message:event.message,dedupToken:event.dedupToken}))}let inMemory=state.queue.splice(0,state.queue.length),toSend=dedupeFormattedEvents([...inMemory,...durableToSend]);if(toSend.length===0)return;if(state.busy=!0,!await sendWakePromptWithMarker(sessionID,toSend)){state.busy=!1,enqueueBounded(state,inMemory);return}if(durableToSend.length>0&&durablePrUrl&&workflow?.workflowInstanceId){let postWakeWorkflow=await _internals152.readPrWorkflowGateState(active.directory,sessionID),postWakeTarget=postWakeWorkflow?.prFeedbackTargetUrl??postWakeWorkflow?.prFeedbackReviewHandoff?.prUrl;if(postWakeWorkflow?.mode==="PR_FEEDBACK"&&postWakeWorkflow.workflowInstanceId===workflow.workflowInstanceId&&!postWakeWorkflow.prFeedbackInventory&&postWakeTarget&&sameGitHubPr(postWakeTarget,durablePrUrl))await _internals152.claimPrFeedbackMonitorEvents(active.directory,sessionID,workflow.workflowInstanceId,durablePrUrl,durableToSend.map((event)=>event.dedupToken))}}function dedupeFormattedEvents(events){let latestByToken=new Map;for(let event of events)latestByToken.delete(event.dedupToken),latestByToken.set(event.dedupToken,event);return[...latestByToken.values()].slice(-MAX_QUEUED_EVENTS_PER_SESSION)}function canonicalGitHubPrUrl3(value){try{let url3=new URL(value),match=url3.pathname.match(/^\/([^/]+)\/([^/]+)\/pull\/(\d+)\/?$/);if(url3.protocol!=="https:"||url3.hostname.toLowerCase()!=="github.com"||!match)return null;let number7=Number(match[3]);if(!Number.isSafeInteger(number7)||number7<=0)return null;return`github.com/${match[1].toLowerCase()}/${match[2].toLowerCase()}/pull/${number7}`}catch{return null}}function sameGitHubPr(left,right){let leftCanonical=canonicalGitHubPrUrl3(left);return leftCanonical!==null&&leftCanonical===canonicalGitHubPrUrl3(right)}async function sendWakePromptWithMarker(sessionID,events){let active=registration;if(!active)return!1;let messageID=markPrWorkflowPluginWake(active.directory,sessionID);return _internals152.sendWakePrompt(sessionID,events,messageID)}function sanitizeAttribute(value){return value.replace(/["<>\r\n]/g,"")}function sanitizeWakeBody(value){return value.replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\[(MODE|SYSTEM|DEVELOPER|USER|ASSISTANT)\s*:/gi,"($1:")}function buildWakeMessage(events){let groups=new Map;for(let event of events){let key=`${event.repoFullName}#${event.prNumber}`,group=groups.get(key);if(group)group.push(event);else groups.set(key,[event])}let blocks=[];for(let[prKey,groupEvents]of groups){let types2=[...new Set(groupEvents.map((e)=>e.type))].join(","),url3=sanitizeAttribute(groupEvents[0]?.prUrl??""),disposition=groupEvents.some((event)=>event.disposition==="queued-for-later")?"queued-for-later":"active",lines=groupEvents.map((e)=>sanitizeWakeBody(e.message)).join(`
5818
5825
  `);blocks.push([`<pr-activity pr="${sanitizeAttribute(prKey)}" url="${url3}" events="${sanitizeAttribute(types2)}" disposition="${disposition}">`,lines,"</pr-activity>"].join(`
5819
5826
  `))}let instruction=events.some((event)=>event.disposition==="queued-for-later")?`${QUEUED_WAKE_INSTRUCTION}
5820
5827
 
@@ -5834,10 +5841,10 @@ ${instruction}`}async function sendWakePrompt(sessionID,events,messageID){let ac
5834
5841
  `);case"pr.review.approved":return[`${dedupToken} (advisory) PR #${payload.prNumber} — Review: approved`,` Repository: ${payload.repoFullName}`,` URL: ${payload.prUrl||""}`,` Review state: ${payload.reviewDecision||"APPROVED"}`].join(`
5835
5842
  `);case"pr.merged":return[`${dedupToken} (advisory) PR #${payload.prNumber} — PR merged (TERMINAL)`,` Repository: ${payload.repoFullName}`,` URL: ${payload.prUrl||""}`," Monitoring ends: report final status and stop — the subscription is complete."].join(`
5836
5843
  `);case"pr.closed":return[`${dedupToken} (advisory) PR #${payload.prNumber} — PR closed without merge (TERMINAL)`,` Repository: ${payload.repoFullName}`,` URL: ${payload.prUrl||""}`," Monitoring ends: report final status and stop — the subscription is complete."].join(`
5837
- `);default:return null}}var CLEAR_UNADDRESSED_DELAY_MS=2000,MAX_PENDING_CLEARS=200,pendingClears,_internals153,AUTO_PR_FEEDBACK_EVENTS,EVENT_CONFIG_MAP,CONTENT_EVENT_TYPES;var init_pr_event_subscribers=__esm(()=>{init_pr_workflow_gate();init_state2();init_utils();init_event_bus();init_pr_event_delivery();init_pr_feedback_event_queue();init_pr_subscriptions();pendingClears=new Map,_internals153={handlePrEvent,getGlobalEventBus,listActive,updateSnapshot,getAgentSession,readPrWorkflowGateState,activatePrWorkflow,enqueuePrFeedbackMonitorEvent,deliverPrActivity,isPrEventDeliveryRegistered,scheduleClearUnaddressed,clearUnaddressedDelayMs:CLEAR_UNADDRESSED_DELAY_MS,log,formatAdvisory},AUTO_PR_FEEDBACK_EVENTS=new Set(["pr.ci.failed","pr.merge.conflict"]),EVENT_CONFIG_MAP={"pr.ci.failed":"notify_ci_failure","pr.ci.passed":"notify_ci_success","pr.new.comment":"notify_new_comments","pr.merge.conflict":"notify_merge_conflict","pr.merge.conflict_resolved":"notify_merge_conflict","pr.review.changes_requested":"notify_review_activity","pr.review.approved":"notify_review_activity","pr.merged":"notify_merged","pr.closed":"notify_closed"};CONTENT_EVENT_TYPES=new Set(["pr.new.comment","pr.review.changes_requested","pr.review.approved","pr.review.comment"])});var exports_status_artifact={};__export(exports_status_artifact,{AutomationStatusArtifact:()=>AutomationStatusArtifact});import*as fs105 from"node:fs";import*as path199 from"node:path";function createEmptySnapshot(mode,capabilities){return{timestamp:Date.now(),mode,enabled:mode!=="manual",currentPhase:0,lastTrigger:null,pendingActions:0,lastOutcome:null,capabilities}}function validateFilename(filename){if(filename.includes("\x00"))throw Error("Invalid filename: contains null byte");let pathSeparators=["/","\\",".."];for(let sep37 of pathSeparators)if(filename.includes(sep37))throw Error(`Invalid filename: contains path separator '${sep37}'`);if(filename.startsWith("/")||filename.startsWith("\\")||/^[a-zA-Z]:/.test(filename))throw Error("Invalid filename: absolute paths not allowed");if(filename.length>MAX_FILENAME_LENGTH)throw Error(`Invalid filename: exceeds maximum length of ${MAX_FILENAME_LENGTH} characters`);if(!SAFE_FILENAME_PATTERN.test(filename))throw Error("Invalid filename: contains unsafe characters");if(filename.includes("/")||filename.includes("\\"))throw Error("Invalid filename: path separators not allowed");if(!filename.trim()||filename.trim()!==filename)throw Error("Invalid filename: cannot be empty or contain leading/trailing whitespace");return filename}class AutomationStatusArtifact{swarmDir;filename;currentSnapshot;constructor(swarmDir,filename="automation-status.json"){let sanitizedFilename=validateFilename(filename);this.swarmDir=swarmDir,this.filename=sanitizedFilename,this.currentSnapshot=this.load()??createEmptySnapshot("manual",{plan_sync:!1,phase_preflight:!1,config_doctor_on_startup:!1,config_doctor_autofix:!1,evidence_auto_summaries:!1,decision_drift_detection:!1})}getFilePath(){return path199.join(this.swarmDir,this.filename)}load(){let filePath=this.getFilePath();try{if(fs105.existsSync(filePath)){let content=fs105.readFileSync(filePath,"utf-8");return JSON.parse(content)}}catch{}return null}write(){let filePath=this.getFilePath();if(!fs105.existsSync(this.swarmDir))fs105.mkdirSync(this.swarmDir,{recursive:!0});fs105.writeFileSync(filePath,JSON.stringify(this.currentSnapshot,null,2),"utf-8")}getSnapshot(){return{...this.currentSnapshot}}read(){let loaded=this.load();if(loaded)this.currentSnapshot=loaded;return this.getSnapshot()}updateConfig(mode,capabilities){this.currentSnapshot={...this.currentSnapshot,mode,enabled:mode!=="manual",timestamp:Date.now(),capabilities},this.write()}updatePhase(phase){this.currentSnapshot={...this.currentSnapshot,currentPhase:phase,timestamp:Date.now()},this.write()}recordTrigger(triggeredAt,triggeredPhase,source,reason){this.currentSnapshot={...this.currentSnapshot,lastTrigger:{triggeredAt,triggeredPhase,source,reason},timestamp:Date.now()},this.write()}updatePendingActions(count){this.currentSnapshot={...this.currentSnapshot,pendingActions:count,timestamp:Date.now()},this.write()}recordOutcome(state,phase,message){this.currentSnapshot={...this.currentSnapshot,lastOutcome:{state,phase,outcomeAt:Date.now(),message:message??null},timestamp:Date.now()},this.write()}clearOutcome(){this.currentSnapshot={...this.currentSnapshot,lastOutcome:{state:"none",phase:null,outcomeAt:null,message:null},timestamp:Date.now()},this.write()}isEnabled(){return this.currentSnapshot.enabled}hasCapability(capability){return this.currentSnapshot.capabilities[capability]===!0}getGuiSummary(){let{currentSnapshot}=this,status="Disabled";if(currentSnapshot.enabled)status=currentSnapshot.mode.charAt(0).toUpperCase()+currentSnapshot.mode.slice(1);let lastTrigger=null;if(currentSnapshot.lastTrigger?.triggeredAt)lastTrigger=new Date(currentSnapshot.lastTrigger.triggeredAt).toLocaleTimeString();let outcome=null;if(currentSnapshot.lastOutcome?.state&&currentSnapshot.lastOutcome.state!=="none")outcome=currentSnapshot.lastOutcome.state;return{status,phase:currentSnapshot.currentPhase,lastTrigger,pending:currentSnapshot.pendingActions,outcome}}}var MAX_FILENAME_LENGTH=255,SAFE_FILENAME_PATTERN;var init_status_artifact=__esm(()=>{SAFE_FILENAME_PATTERN=/^[a-zA-Z0-9._-]+$/});var exports_trigger={};__export(exports_trigger,{PreflightTriggerManager:()=>PreflightTriggerManager,PhaseBoundaryTrigger:()=>PhaseBoundaryTrigger});class PhaseBoundaryTrigger{eventBus;config;lastKnownPhase=0;lastTriggeredPhase=0;constructor(eventBus,config3){this.eventBus=eventBus??getGlobalEventBus(),this.config={minCompletedTasksThreshold:config3?.minCompletedTasksThreshold??1,allowZeroTaskTrigger:config3?.allowZeroTaskTrigger??!1}}setCurrentPhase(phase){this.lastKnownPhase=phase}getCurrentPhase(){return this.lastKnownPhase}get lastTriggeredPhaseValue(){return this.lastTriggeredPhase}detectBoundary(newPhase,completedTasks,totalTasks){if(newPhase===this.lastKnownPhase)return{detected:!1,previousPhase:this.lastKnownPhase,currentPhase:newPhase,reason:"Phase unchanged",completedTaskCount:completedTasks,totalTaskCount:totalTasks};let boundaryResult={detected:!0,previousPhase:this.lastKnownPhase,currentPhase:newPhase,reason:`Phase transition from ${this.lastKnownPhase} to ${newPhase}`,completedTaskCount:completedTasks,totalTaskCount:totalTasks};return this.lastKnownPhase=newPhase,this.eventBus.publish("phase.boundary.detected",boundaryResult),boundaryResult}shouldTriggerPreflight(boundaryResult){if(this.lastTriggeredPhase===boundaryResult.currentPhase)return log("[Trigger] Preflight already triggered for phase",{phase:boundaryResult.currentPhase}),!1;let threshold=this.config.minCompletedTasksThreshold??1;if(!(this.config.allowZeroTaskTrigger||boundaryResult.completedTaskCount>=threshold))return log("[Trigger] Preflight skipped - insufficient task completion",{completed:boundaryResult.completedTaskCount,required:threshold}),!1;return!0}markTriggered(phase){this.lastTriggeredPhase=phase}reset(){this.lastKnownPhase=0,this.lastTriggeredPhase=0}}class PreflightTriggerManager{automationConfig;eventBus;trigger;requestQueue;requestCounter=0;preflightHandler=null;unsubscribe=null;unsubscribeSkipped=null;constructor(automationConfig,eventBus,triggerConfig){this.automationConfig=automationConfig,this.eventBus=eventBus??getGlobalEventBus(),this.trigger=new PhaseBoundaryTrigger(this.eventBus,triggerConfig),this.requestQueue=new AutomationQueue({maxSize:100,defaultMaxRetries:3,overflowStrategy:"evict-oldest"}),this.unsubscribeSkipped=this.eventBus.subscribe("preflight.skipped",(event)=>{let payload=event.payload;if(payload.reason==="queue_overflow"||payload.reason==="queue_enqueue_error")criticalWarn("[PreflightTrigger] preflight skipped",{reason:payload.reason,phase:payload.phase,requestId:payload.requestId,queueDepth:this.requestQueue.size()})})}isEnabled(){if(!this.automationConfig)return!1;if(!this.automationConfig.capabilities)return!1;if(this.automationConfig.mode==="manual")return!1;return this.automationConfig.capabilities.phase_preflight===!0}getMode(){if(!this.automationConfig)return"unknown";return this.automationConfig.mode??"unknown"}updatePhase(phase){this.trigger.setCurrentPhase(phase)}async checkAndTrigger(currentPhase,completedTasks,totalTasks){let phasePreflight=this.automationConfig?.capabilities?.phase_preflight,mode=this.automationConfig?.mode;if(!this.isEnabled())return log("[PreflightTrigger] Disabled via feature flags",{mode:mode??"unknown",phase_preflight:phasePreflight}),await this.eventBus.publish("preflight.skipped",{reason:"feature_disabled",mode:mode??"unknown",phase_preflight:phasePreflight}),!1;let boundaryResult=this.trigger.detectBoundary(currentPhase,completedTasks,totalTasks);if(!boundaryResult.detected)return!1;if(!this.trigger.shouldTriggerPreflight(boundaryResult))return await this.eventBus.publish("preflight.skipped",{reason:"threshold_not_met",boundary:boundaryResult}),!1;return this.triggerPreflight(boundaryResult)}async triggerPreflight(boundaryResult){let requestId=`preflight-${Date.now()}-${++this.requestCounter}`,request={id:requestId,triggeredAt:Date.now(),currentPhase:boundaryResult.currentPhase,source:"phase_boundary",reason:boundaryResult.reason,metadata:{completedTaskCount:boundaryResult.completedTaskCount,totalTaskCount:boundaryResult.totalTaskCount}};try{this.requestQueue.enqueue(request,"high")}catch(error93){log("[PreflightTrigger] Queue enqueue failed (continuing)",{requestId,phase:boundaryResult.currentPhase,error:error93 instanceof Error?error93.message:String(error93)}),await this.eventBus.publish("preflight.skipped",{reason:"queue_enqueue_error",requestId,phase:boundaryResult.currentPhase})}return this.trigger.markTriggered(boundaryResult.currentPhase),await this.eventBus.publish("preflight.requested",request),await this.eventBus.publish("preflight.triggered",{requestId,phase:boundaryResult.currentPhase,timestamp:request.triggeredAt}),log("[PreflightTrigger] Preflight triggered",{requestId,phase:boundaryResult.currentPhase,completed:boundaryResult.completedTaskCount,total:boundaryResult.totalTaskCount}),!0}getPendingRequests(){return this.requestQueue.getAll().map((item)=>item.payload)}getQueueSize(){return this.requestQueue.size()}getStats(){let mode="unknown";try{mode=this.getMode()}catch{mode="unknown"}return{enabled:this.isEnabled(),mode,currentPhase:this.trigger.getCurrentPhase(),lastTriggeredPhase:this.trigger.lastTriggeredPhaseValue,pendingRequests:this.getQueueSize()}}reset(){if(this.trigger.reset(),this.requestQueue.clear(),this.unsubscribe)this.unsubscribe(),this.unsubscribe=null;if(this.unsubscribeSkipped)this.unsubscribeSkipped(),this.unsubscribeSkipped=null}registerHandler(handler){if(this.unsubscribe)this.unsubscribe();this.preflightHandler=handler;let HANDLER_TIMEOUT_MS=120000;this.unsubscribe=this.eventBus.subscribe("preflight.requested",async(event)=>{let request=event.payload,timeoutHandle;try{if(this.preflightHandler)await Promise.race([this.preflightHandler(request),new Promise((_,reject)=>{timeoutHandle=setTimeout(()=>{reject(Error(`Preflight handler timed out after ${HANDLER_TIMEOUT_MS}ms`))},HANDLER_TIMEOUT_MS)})])}catch(error93){log("[PreflightTrigger] Handler error",{requestId:request.id,phase:request.currentPhase,errorType:error93 instanceof Error?error93.name:"unknown"})}finally{clearTimeout(timeoutHandle);let match=this.requestQueue.getAll().find((it)=>it.payload.id===request.id);if(match)this.requestQueue.complete(match.id)}}),log("[PreflightTrigger] Handler registered")}unregisterHandler(){if(this.unsubscribe)this.unsubscribe(),this.unsubscribe=null;this.preflightHandler=null,log("[PreflightTrigger] Handler unregistered")}hasHandler(){return this.preflightHandler!==null}}var init_trigger=__esm(()=>{init_utils();init_event_bus();init_queue()});function truncateWords(text,maxWords){let trimmed=text.trim();if(trimmed.length===0)return{text:trimmed,truncated:!1};let words=trimmed.split(/\s+/);if(words.length<=maxWords)return{text:trimmed,truncated:!1};return{text:`${words.slice(0,maxWords).join(" ")}…`,truncated:!0}}function capArray(items,maxItems){if(items.length<=maxItems)return{items,truncated:!1};return{items:items.slice(0,maxItems),truncated:!0}}function normalizeAgentWorkSummary(input,maxSummaryWords=MAX_AGENT_SUMMARY_WORDS){let truncated=!1,sum=truncateWords(input.summary,maxSummaryWords);truncated||=sum.truncated;let cap=(items)=>{let r=capArray(items??[],MAX_LIST_ITEMS);return truncated||=r.truncated,r.items},candidate2={schema_version:SUMMARY_SCHEMA_VERSION,phase:input.phase,task_id:input.task_id,session_id:input.session_id,agent:input.agent,parent_agent:input.parent_agent,summary:sum.text,key_decisions:cap(input.key_decisions),constraints_observed:cap(input.constraints_observed),constraints_violated:cap(input.constraints_violated),assumptions:cap(input.assumptions),risks:cap(input.risks),files_touched:input.files_touched?capArray(input.files_touched,50).items:void 0,evidence_refs:capArray(input.evidence_refs??[],20).items,created_at:input.created_at??new Date().toISOString(),truncated:truncated||void 0};return AgentWorkSummarySchema.parse(candidate2)}var SUMMARY_SCHEMA_VERSION="1.0.0",MAX_AGENT_SUMMARY_WORDS=100,MAX_PHASE_SUMMARY_WORDS=250,MAX_LIST_ITEMS=5,SupervisorVerdictSchema,AgentWorkSummarySchema,PhaseArchitectureSummarySchema,SupervisorFindingSchema,KnowledgeRecommendationSchema,EvidenceProvenanceSchema,ArchitectureSupervisorReportSchema;var init_schema3=__esm(()=>{init_zod();SupervisorVerdictSchema=exports_external.enum(["APPROVE","CONCERNS","REJECT"]);AgentWorkSummarySchema=exports_external.object({schema_version:exports_external.literal(SUMMARY_SCHEMA_VERSION),phase:exports_external.number().int().min(0).max(999),task_id:exports_external.string().min(1).optional(),session_id:exports_external.string().min(1),agent:exports_external.string().min(1),parent_agent:exports_external.string().min(1).optional(),summary:exports_external.string().min(1),key_decisions:exports_external.array(exports_external.string().min(1)).max(MAX_LIST_ITEMS).default([]),constraints_observed:exports_external.array(exports_external.string().min(1)).max(MAX_LIST_ITEMS).default([]),constraints_violated:exports_external.array(exports_external.string().min(1)).max(MAX_LIST_ITEMS).default([]),assumptions:exports_external.array(exports_external.string().min(1)).max(MAX_LIST_ITEMS).default([]),risks:exports_external.array(exports_external.string().min(1)).max(MAX_LIST_ITEMS).default([]),files_touched:exports_external.array(exports_external.string().min(1)).max(50).optional(),evidence_refs:exports_external.array(exports_external.string().min(1)).max(20).default([]),created_at:exports_external.string().datetime(),truncated:exports_external.boolean().optional()});PhaseArchitectureSummarySchema=exports_external.object({schema_version:exports_external.literal(SUMMARY_SCHEMA_VERSION),phase:exports_external.number().int().min(0).max(999),summary:exports_external.string().default(""),agents_seen:exports_external.array(exports_external.string().min(1)).default([]),tasks_seen:exports_external.array(exports_external.string().min(1)).default([]),key_decisions:exports_external.array(exports_external.string().min(1)).default([]),conflicts:exports_external.array(exports_external.string().min(1)).default([]),unresolved_risks:exports_external.array(exports_external.string().min(1)).default([]),constraint_violations:exports_external.array(exports_external.string().min(1)).default([]),evidence_refs:exports_external.array(exports_external.string().min(1)).default([]),created_at:exports_external.string().datetime()}),SupervisorFindingSchema=exports_external.object({severity:exports_external.enum(["low","medium","high","critical"]),category:exports_external.string().min(1),agents:exports_external.array(exports_external.string().min(1)).default([]),tasks:exports_external.array(exports_external.string().min(1)).default([]),evidence_refs:exports_external.array(exports_external.string().min(1)).default([]),description:exports_external.string().min(1),recommendation:exports_external.string().default("")}),KnowledgeRecommendationSchema=exports_external.object({lesson:exports_external.string().min(1),target_agents:exports_external.array(exports_external.string().min(1)).default([]),confidence:exports_external.number().min(0).max(1).default(0.5),evidence_refs:exports_external.array(exports_external.string().min(1)).default([])}),EvidenceProvenanceSchema=exports_external.object({agent_name:exports_external.string().min(1).optional(),session_id:exports_external.string().min(1).optional(),captured_at:exports_external.string().datetime().optional()}),ArchitectureSupervisorReportSchema=exports_external.object({schema_version:exports_external.literal(SUMMARY_SCHEMA_VERSION),phase:exports_external.number().int().min(0).max(999),verdict:SupervisorVerdictSchema,findings:exports_external.array(SupervisorFindingSchema).default([]),knowledge_recommendations:exports_external.array(KnowledgeRecommendationSchema).default([]),created_at:exports_external.string().datetime(),provenance:EvidenceProvenanceSchema.optional()})});import{existsSync as existsSync108,mkdirSync as mkdirSync60,readFileSync as readFileSync84,renameSync as renameSync35,unlinkSync as unlinkSync34,writeFileSync as writeFileSync41}from"node:fs";import*as path211 from"node:path";function writeRawSidecar(absPath,bundle){mkdirSync60(path211.dirname(absPath),{recursive:!0});let tempFile=`${absPath}.tmp-${Date.now()}-${process.pid}`;try{writeFileSync41(tempFile,JSON.stringify(bundle,null,2),"utf-8"),renameSync35(tempFile,absPath),invalidateCachedArtifact(absPath)}finally{if(existsSync108(tempFile))try{unlinkSync34(tempFile)}catch{}}}async function writeAgentSummary(directory,summary){let taskId=summary.task_id??`phase-${summary.phase}-summaries`;return await saveEvidence(directory,taskId,{task_id:taskId,type:"note",timestamp:summary.created_at,agent:summary.agent,verdict:"info",summary:summary.summary,metadata:{kind:AGENT_SUMMARY_METADATA_KIND,phase:summary.phase,session_id:summary.session_id,payload:summary}}),taskId}async function listAgentSummaries(directory,filter={}){let taskIds=await listEvidenceTaskIds(directory),results=[];for(let taskId of taskIds){let loaded=await loadEvidence(directory,taskId);if(loaded.status!=="found")continue;for(let entry of loaded.bundle.entries){if(entry.type!=="note")continue;let meta3=entry.metadata;if(!meta3||meta3.kind!==AGENT_SUMMARY_METADATA_KIND)continue;if(filter.phase!==void 0&&meta3.phase!==filter.phase)continue;if(filter.session!==void 0&&meta3.session_id!==filter.session)continue;let parsed=AgentWorkSummarySchema.safeParse(meta3.payload);if(!parsed.success){warn(`Skipping malformed agent summary in task ${taskId}: ${parsed.error.issues.map((i)=>i.message).join(", ")}`);continue}results.push(parsed.data)}}return results}function writePhaseArchitectureSummary(directory,summary){let rel=path211.join("evidence",String(summary.phase),PHASE_SUMMARY_FILE),abs=validateSwarmPath(directory,rel);return writeRawSidecar(abs,summary),abs}function writeSupervisorReport(directory,report){let rel=path211.join("evidence",String(report.phase),SUPERVISOR_REPORT_FILE),abs=validateSwarmPath(directory,rel),bundle={entries:[{type:SUPERVISOR_ENTRY_TYPE,phase_number:report.phase,scope:"phase",timestamp:report.created_at,verdict:report.verdict,findings:report.findings,knowledge_recommendations:report.knowledge_recommendations,...report.provenance?{provenance:report.provenance}:{}}]};return writeRawSidecar(abs,bundle),abs}function readSupervisorReportRaw(directory,phase){let rel=path211.join("evidence",String(phase),SUPERVISOR_REPORT_FILE),abs;try{abs=validateSwarmPath(directory,rel)}catch{return null}if(!existsSync108(abs))return null;try{return JSON.parse(readFileSync84(abs,"utf-8")).entries?.find((e)=>e.type===SUPERVISOR_ENTRY_TYPE)??null}catch{return null}}var AGENT_SUMMARY_METADATA_KIND="agent_summary",PHASE_SUMMARY_FILE="phase-architecture-summary.json",SUPERVISOR_REPORT_FILE="architecture-supervisor.json",SUPERVISOR_ENTRY_TYPE="architecture-supervisor";var init_store4=__esm(()=>{init_manager2();init_utils2();init_utils();init_swarm_artifact_cache();init_schema3()});var exports_aggregate={};__export(exports_aggregate,{aggregatePhaseSummary:()=>aggregatePhaseSummary});function dedupe2(values){return Array.from(new Set(values)).filter((v)=>v.trim().length>0)}function detectConflicts(summaries){let observedBy=new Map,violatedBy=new Map;for(let s of summaries){for(let c of s.constraints_observed){if(!observedBy.has(c))observedBy.set(c,new Set);observedBy.get(c)?.add(s.agent)}for(let c of s.constraints_violated){if(!violatedBy.has(c))violatedBy.set(c,new Set);violatedBy.get(c)?.add(s.agent)}}let conflicts=[];for(let[constraint,violators]of violatedBy){let observers=observedBy.get(constraint);if(observers&&observers.size>0){let obs=Array.from(observers).sort().join(", "),vio=Array.from(violators).sort().join(", ");conflicts.push(`Constraint "${constraint}" observed by [${obs}] but violated by [${vio}]`)}}return conflicts.sort()}async function aggregatePhaseSummary(directory,phase,options={}){let summaries=await listAgentSummaries(directory,{phase});if(summaries.length===0)return null;let agentsSeen=dedupe2(summaries.map((s)=>s.agent)).sort(),tasksSeen=dedupe2(summaries.map((s)=>s.task_id).filter((t)=>Boolean(t))).sort(),keyDecisions=dedupe2(summaries.flatMap((s)=>s.key_decisions)),unresolvedRisks=dedupe2(summaries.flatMap((s)=>s.risks)),constraintViolations=dedupe2(summaries.flatMap((s)=>s.constraints_violated)),evidenceRefs=dedupe2(summaries.flatMap((s)=>s.evidence_refs)),conflicts=detectConflicts(summaries),headline=`Phase ${phase}: ${summaries.length} agent summary(ies) across ${tasksSeen.length} task(s); ${constraintViolations.length} constraint violation(s), ${conflicts.length} cross-agent conflict(s).`,cap=options.maxPhaseSummaryWords??MAX_PHASE_SUMMARY_WORDS,summaryText=truncateWords(headline,cap).text,phaseSummary={schema_version:SUMMARY_SCHEMA_VERSION,phase,summary:summaryText,agents_seen:agentsSeen,tasks_seen:tasksSeen,key_decisions:keyDecisions,conflicts,unresolved_risks:unresolvedRisks,constraint_violations:constraintViolations,evidence_refs:evidenceRefs,created_at:options.now?.()??new Date().toISOString()};return writePhaseArchitectureSummary(directory,phaseSummary),phaseSummary}var init_aggregate=__esm(()=>{init_schema3();init_store4()});var exports_preflight_integration={};__export(exports_preflight_integration,{runManualPreflight:()=>runManualPreflight,createPreflightIntegration:()=>createPreflightIntegration});function createPreflightIntegration(config3){let{automationConfig,directory,swarmDir,preflightConfig,updateStatusArtifact=!0}=config3;if(automationConfig?.capabilities?.phase_preflight!==!0)throw Error("Preflight is not enabled in automation capabilities. Set automation.capabilities.phase_preflight to true.");let manager=new PreflightTriggerManager(automationConfig,void 0,{directory}),statusArtifact=null;if(updateStatusArtifact&&swarmDir)statusArtifact=new AutomationStatusArtifact(swarmDir);let preflightHandler=async(request)=>{log("[PreflightIntegration] Handling preflight request",{requestId:request.id,phase:request.currentPhase,source:request.source});let report=await runPreflight(directory,request.currentPhase,preflightConfig);if(statusArtifact){let state=report.overall==="pass"?"success":"failure";statusArtifact.recordOutcome(state,request.currentPhase,report.message),log("[PreflightIntegration] Status artifact updated",{state,phase:request.currentPhase,message:report.message})}log("[PreflightIntegration] Preflight complete",{requestId:request.id,overall:report.overall,message:report.message,durationMs:report.totalDurationMs})};return manager.registerHandler(preflightHandler),{manager,cleanup:()=>{manager.unregisterHandler()}}}async function runManualPreflight(directory,phase,config3){return runPreflight(directory,phase,config3)}var init_preflight_integration=__esm(()=>{init_status_artifact();init_trigger();init_preflight_service();init_logger()});var exports_doc_scan={};__export(exports_doc_scan,{scanDocIndex:()=>scanDocIndex,extractDocConstraints:()=>extractDocConstraints,doc_scan:()=>doc_scan,doc_extract:()=>doc_extract});import*as crypto16 from"node:crypto";import*as fs125 from"node:fs";import{mkdir as mkdir46,readdir as readdir14,readFile as readFile48,realpath as realpath11,stat as stat20,writeFile as writeFile28}from"node:fs/promises";import*as path227 from"node:path";function normalizeSeparators(filePath){return filePath.replace(/\\/g,"/")}function matchesDocPattern(filePath,patterns){let normalizedPath2=normalizeSeparators(filePath),basename33=path227.basename(filePath);for(let pattern of patterns){if(!pattern.includes("/")&&!pattern.includes("\\")){if(basename33===pattern)return!0;continue}if(pattern.startsWith("**/")){let filenamePattern=pattern.slice(3);if(basename33===filenamePattern)return!0;continue}let dirPrefix=normalizeSeparators(pattern).replace(/\/\*\*.*$/,"").replace(/\/\*.*$/,"");if(normalizedPath2.startsWith(`${dirPrefix}/`)||normalizedPath2===dirPrefix)return!0}return!1}function extractTitleAndSummary(content,filename){let lines=content.split(`
5844
+ `);default:return null}}var CLEAR_UNADDRESSED_DELAY_MS=2000,MAX_PENDING_CLEARS=200,pendingClears,_internals153,AUTO_PR_FEEDBACK_EVENTS,EVENT_CONFIG_MAP,CONTENT_EVENT_TYPES;var init_pr_event_subscribers=__esm(()=>{init_pr_workflow_gate();init_state2();init_utils();init_event_bus();init_pr_event_delivery();init_pr_feedback_event_queue();init_pr_subscriptions();pendingClears=new Map,_internals153={handlePrEvent,getGlobalEventBus,listActive,updateSnapshot,getAgentSession,readPrWorkflowGateState,activatePrWorkflow,enqueuePrFeedbackMonitorEvent,deliverPrActivity,isPrEventDeliveryRegistered,scheduleClearUnaddressed,clearUnaddressedDelayMs:CLEAR_UNADDRESSED_DELAY_MS,log,formatAdvisory},AUTO_PR_FEEDBACK_EVENTS=new Set(["pr.ci.failed","pr.merge.conflict"]),EVENT_CONFIG_MAP={"pr.ci.failed":"notify_ci_failure","pr.ci.passed":"notify_ci_success","pr.new.comment":"notify_new_comments","pr.merge.conflict":"notify_merge_conflict","pr.merge.conflict_resolved":"notify_merge_conflict","pr.review.changes_requested":"notify_review_activity","pr.review.approved":"notify_review_activity","pr.merged":"notify_merged","pr.closed":"notify_closed"};CONTENT_EVENT_TYPES=new Set(["pr.new.comment","pr.review.changes_requested","pr.review.approved","pr.review.comment"])});var exports_status_artifact={};__export(exports_status_artifact,{AutomationStatusArtifact:()=>AutomationStatusArtifact});import*as fs105 from"node:fs";import*as path199 from"node:path";function createEmptySnapshot(mode,capabilities){return{timestamp:Date.now(),mode,enabled:mode!=="manual",currentPhase:0,lastTrigger:null,pendingActions:0,lastOutcome:null,capabilities}}function validateFilename(filename){if(filename.includes("\x00"))throw Error("Invalid filename: contains null byte");let pathSeparators=["/","\\",".."];for(let sep37 of pathSeparators)if(filename.includes(sep37))throw Error(`Invalid filename: contains path separator '${sep37}'`);if(filename.startsWith("/")||filename.startsWith("\\")||/^[a-zA-Z]:/.test(filename))throw Error("Invalid filename: absolute paths not allowed");if(filename.length>MAX_FILENAME_LENGTH)throw Error(`Invalid filename: exceeds maximum length of ${MAX_FILENAME_LENGTH} characters`);if(!SAFE_FILENAME_PATTERN.test(filename))throw Error("Invalid filename: contains unsafe characters");if(filename.includes("/")||filename.includes("\\"))throw Error("Invalid filename: path separators not allowed");if(!filename.trim()||filename.trim()!==filename)throw Error("Invalid filename: cannot be empty or contain leading/trailing whitespace");return filename}class AutomationStatusArtifact{swarmDir;filename;currentSnapshot;constructor(swarmDir,filename="automation-status.json"){let sanitizedFilename=validateFilename(filename);this.swarmDir=swarmDir,this.filename=sanitizedFilename,this.currentSnapshot=this.load()??createEmptySnapshot("manual",{plan_sync:!1,phase_preflight:!1,config_doctor_on_startup:!1,config_doctor_autofix:!1,evidence_auto_summaries:!1,decision_drift_detection:!1})}getFilePath(){return path199.join(this.swarmDir,this.filename)}load(){let filePath=this.getFilePath();try{if(fs105.existsSync(filePath)){let content=fs105.readFileSync(filePath,"utf-8");return JSON.parse(content)}}catch{}return null}write(){let filePath=this.getFilePath();if(!fs105.existsSync(this.swarmDir))fs105.mkdirSync(this.swarmDir,{recursive:!0});fs105.writeFileSync(filePath,JSON.stringify(this.currentSnapshot,null,2),"utf-8")}getSnapshot(){return{...this.currentSnapshot}}read(){let loaded=this.load();if(loaded)this.currentSnapshot=loaded;return this.getSnapshot()}updateConfig(mode,capabilities){this.currentSnapshot={...this.currentSnapshot,mode,enabled:mode!=="manual",timestamp:Date.now(),capabilities},this.write()}updatePhase(phase){this.currentSnapshot={...this.currentSnapshot,currentPhase:phase,timestamp:Date.now()},this.write()}recordTrigger(triggeredAt,triggeredPhase,source,reason){this.currentSnapshot={...this.currentSnapshot,lastTrigger:{triggeredAt,triggeredPhase,source,reason},timestamp:Date.now()},this.write()}updatePendingActions(count){this.currentSnapshot={...this.currentSnapshot,pendingActions:count,timestamp:Date.now()},this.write()}recordOutcome(state,phase,message){this.currentSnapshot={...this.currentSnapshot,lastOutcome:{state,phase,outcomeAt:Date.now(),message:message??null},timestamp:Date.now()},this.write()}clearOutcome(){this.currentSnapshot={...this.currentSnapshot,lastOutcome:{state:"none",phase:null,outcomeAt:null,message:null},timestamp:Date.now()},this.write()}isEnabled(){return this.currentSnapshot.enabled}hasCapability(capability){return this.currentSnapshot.capabilities[capability]===!0}getGuiSummary(){let{currentSnapshot}=this,status="Disabled";if(currentSnapshot.enabled)status=currentSnapshot.mode.charAt(0).toUpperCase()+currentSnapshot.mode.slice(1);let lastTrigger=null;if(currentSnapshot.lastTrigger?.triggeredAt)lastTrigger=new Date(currentSnapshot.lastTrigger.triggeredAt).toLocaleTimeString();let outcome=null;if(currentSnapshot.lastOutcome?.state&&currentSnapshot.lastOutcome.state!=="none")outcome=currentSnapshot.lastOutcome.state;return{status,phase:currentSnapshot.currentPhase,lastTrigger,pending:currentSnapshot.pendingActions,outcome}}}var MAX_FILENAME_LENGTH=255,SAFE_FILENAME_PATTERN;var init_status_artifact=__esm(()=>{SAFE_FILENAME_PATTERN=/^[a-zA-Z0-9._-]+$/});var exports_trigger={};__export(exports_trigger,{PreflightTriggerManager:()=>PreflightTriggerManager,PhaseBoundaryTrigger:()=>PhaseBoundaryTrigger});class PhaseBoundaryTrigger{eventBus;config;lastKnownPhase=0;lastTriggeredPhase=0;constructor(eventBus,config3){this.eventBus=eventBus??getGlobalEventBus(),this.config={minCompletedTasksThreshold:config3?.minCompletedTasksThreshold??1,allowZeroTaskTrigger:config3?.allowZeroTaskTrigger??!1}}setCurrentPhase(phase){this.lastKnownPhase=phase}getCurrentPhase(){return this.lastKnownPhase}get lastTriggeredPhaseValue(){return this.lastTriggeredPhase}detectBoundary(newPhase,completedTasks,totalTasks){if(newPhase===this.lastKnownPhase)return{detected:!1,previousPhase:this.lastKnownPhase,currentPhase:newPhase,reason:"Phase unchanged",completedTaskCount:completedTasks,totalTaskCount:totalTasks};let boundaryResult={detected:!0,previousPhase:this.lastKnownPhase,currentPhase:newPhase,reason:`Phase transition from ${this.lastKnownPhase} to ${newPhase}`,completedTaskCount:completedTasks,totalTaskCount:totalTasks};return this.lastKnownPhase=newPhase,this.eventBus.publish("phase.boundary.detected",boundaryResult),boundaryResult}shouldTriggerPreflight(boundaryResult){if(this.lastTriggeredPhase===boundaryResult.currentPhase)return log("[Trigger] Preflight already triggered for phase",{phase:boundaryResult.currentPhase}),!1;let threshold=this.config.minCompletedTasksThreshold??1;if(!(this.config.allowZeroTaskTrigger||boundaryResult.completedTaskCount>=threshold))return log("[Trigger] Preflight skipped - insufficient task completion",{completed:boundaryResult.completedTaskCount,required:threshold}),!1;return!0}markTriggered(phase){this.lastTriggeredPhase=phase}reset(){this.lastKnownPhase=0,this.lastTriggeredPhase=0}}class PreflightTriggerManager{automationConfig;eventBus;trigger;requestQueue;requestCounter=0;preflightHandler=null;unsubscribe=null;unsubscribeSkipped=null;constructor(automationConfig,eventBus,triggerConfig){this.automationConfig=automationConfig,this.eventBus=eventBus??getGlobalEventBus(),this.trigger=new PhaseBoundaryTrigger(this.eventBus,triggerConfig),this.requestQueue=new AutomationQueue({maxSize:100,defaultMaxRetries:3,overflowStrategy:"evict-oldest"}),this.unsubscribeSkipped=this.eventBus.subscribe("preflight.skipped",(event)=>{let payload=event.payload;if(payload.reason==="queue_overflow"||payload.reason==="queue_enqueue_error")criticalWarn("[PreflightTrigger] preflight skipped",{reason:payload.reason,phase:payload.phase,requestId:payload.requestId,queueDepth:this.requestQueue.size()})})}isEnabled(){if(!this.automationConfig)return!1;if(!this.automationConfig.capabilities)return!1;if(this.automationConfig.mode==="manual")return!1;return this.automationConfig.capabilities.phase_preflight===!0}getMode(){if(!this.automationConfig)return"unknown";return this.automationConfig.mode??"unknown"}updatePhase(phase){this.trigger.setCurrentPhase(phase)}async checkAndTrigger(currentPhase,completedTasks,totalTasks){let phasePreflight=this.automationConfig?.capabilities?.phase_preflight,mode=this.automationConfig?.mode;if(!this.isEnabled())return log("[PreflightTrigger] Disabled via feature flags",{mode:mode??"unknown",phase_preflight:phasePreflight}),await this.eventBus.publish("preflight.skipped",{reason:"feature_disabled",mode:mode??"unknown",phase_preflight:phasePreflight}),!1;let boundaryResult=this.trigger.detectBoundary(currentPhase,completedTasks,totalTasks);if(!boundaryResult.detected)return!1;if(!this.trigger.shouldTriggerPreflight(boundaryResult))return await this.eventBus.publish("preflight.skipped",{reason:"threshold_not_met",boundary:boundaryResult}),!1;return this.triggerPreflight(boundaryResult)}async triggerPreflight(boundaryResult){let requestId=`preflight-${Date.now()}-${++this.requestCounter}`,request={id:requestId,triggeredAt:Date.now(),currentPhase:boundaryResult.currentPhase,source:"phase_boundary",reason:boundaryResult.reason,metadata:{completedTaskCount:boundaryResult.completedTaskCount,totalTaskCount:boundaryResult.totalTaskCount}};try{this.requestQueue.enqueue(request,"high")}catch(error93){log("[PreflightTrigger] Queue enqueue failed (continuing)",{requestId,phase:boundaryResult.currentPhase,error:error93 instanceof Error?error93.message:String(error93)}),await this.eventBus.publish("preflight.skipped",{reason:"queue_enqueue_error",requestId,phase:boundaryResult.currentPhase})}return this.trigger.markTriggered(boundaryResult.currentPhase),await this.eventBus.publish("preflight.requested",request),await this.eventBus.publish("preflight.triggered",{requestId,phase:boundaryResult.currentPhase,timestamp:request.triggeredAt}),log("[PreflightTrigger] Preflight triggered",{requestId,phase:boundaryResult.currentPhase,completed:boundaryResult.completedTaskCount,total:boundaryResult.totalTaskCount}),!0}getPendingRequests(){return this.requestQueue.getAll().map((item)=>item.payload)}getQueueSize(){return this.requestQueue.size()}getStats(){let mode="unknown";try{mode=this.getMode()}catch{mode="unknown"}return{enabled:this.isEnabled(),mode,currentPhase:this.trigger.getCurrentPhase(),lastTriggeredPhase:this.trigger.lastTriggeredPhaseValue,pendingRequests:this.getQueueSize()}}reset(){if(this.trigger.reset(),this.requestQueue.clear(),this.unsubscribe)this.unsubscribe(),this.unsubscribe=null;if(this.unsubscribeSkipped)this.unsubscribeSkipped(),this.unsubscribeSkipped=null}registerHandler(handler){if(this.unsubscribe)this.unsubscribe();this.preflightHandler=handler;let HANDLER_TIMEOUT_MS=120000;this.unsubscribe=this.eventBus.subscribe("preflight.requested",async(event)=>{let request=event.payload,timeoutHandle;try{if(this.preflightHandler)await Promise.race([this.preflightHandler(request),new Promise((_,reject)=>{timeoutHandle=setTimeout(()=>{reject(Error(`Preflight handler timed out after ${HANDLER_TIMEOUT_MS}ms`))},HANDLER_TIMEOUT_MS)})])}catch(error93){log("[PreflightTrigger] Handler error",{requestId:request.id,phase:request.currentPhase,errorType:error93 instanceof Error?error93.name:"unknown"})}finally{clearTimeout(timeoutHandle);let match=this.requestQueue.getAll().find((it)=>it.payload.id===request.id);if(match)this.requestQueue.complete(match.id)}}),log("[PreflightTrigger] Handler registered")}unregisterHandler(){if(this.unsubscribe)this.unsubscribe(),this.unsubscribe=null;this.preflightHandler=null,log("[PreflightTrigger] Handler unregistered")}hasHandler(){return this.preflightHandler!==null}}var init_trigger=__esm(()=>{init_utils();init_event_bus();init_queue()});function truncateWords(text,maxWords){let trimmed=text.trim();if(trimmed.length===0)return{text:trimmed,truncated:!1};let words=trimmed.split(/\s+/);if(words.length<=maxWords)return{text:trimmed,truncated:!1};return{text:`${words.slice(0,maxWords).join(" ")}…`,truncated:!0}}function capArray(items,maxItems){if(items.length<=maxItems)return{items,truncated:!1};return{items:items.slice(0,maxItems),truncated:!0}}function normalizeAgentWorkSummary(input,maxSummaryWords=MAX_AGENT_SUMMARY_WORDS){let truncated=!1,sum=truncateWords(input.summary,maxSummaryWords);truncated||=sum.truncated;let cap=(items)=>{let r=capArray(items??[],MAX_LIST_ITEMS);return truncated||=r.truncated,r.items},candidate2={schema_version:SUMMARY_SCHEMA_VERSION,phase:input.phase,task_id:input.task_id,session_id:input.session_id,agent:input.agent,parent_agent:input.parent_agent,summary:sum.text,key_decisions:cap(input.key_decisions),constraints_observed:cap(input.constraints_observed),constraints_violated:cap(input.constraints_violated),assumptions:cap(input.assumptions),risks:cap(input.risks),files_touched:input.files_touched?capArray(input.files_touched,50).items:void 0,evidence_refs:capArray(input.evidence_refs??[],20).items,created_at:input.created_at??new Date().toISOString(),truncated:truncated||void 0};return AgentWorkSummarySchema.parse(candidate2)}var SUMMARY_SCHEMA_VERSION="1.0.0",MAX_AGENT_SUMMARY_WORDS=100,MAX_PHASE_SUMMARY_WORDS=250,MAX_LIST_ITEMS=5,SupervisorVerdictSchema,AgentWorkSummarySchema,PhaseArchitectureSummarySchema,SupervisorFindingSchema,KnowledgeRecommendationSchema,EvidenceProvenanceSchema,ArchitectureSupervisorReportSchema;var init_schema3=__esm(()=>{init_zod();SupervisorVerdictSchema=exports_external.enum(["APPROVE","CONCERNS","REJECT"]);AgentWorkSummarySchema=exports_external.object({schema_version:exports_external.literal(SUMMARY_SCHEMA_VERSION),phase:exports_external.number().int().min(0).max(999),task_id:exports_external.string().min(1).optional(),session_id:exports_external.string().min(1),agent:exports_external.string().min(1),parent_agent:exports_external.string().min(1).optional(),summary:exports_external.string().min(1),key_decisions:exports_external.array(exports_external.string().min(1)).max(MAX_LIST_ITEMS).default([]),constraints_observed:exports_external.array(exports_external.string().min(1)).max(MAX_LIST_ITEMS).default([]),constraints_violated:exports_external.array(exports_external.string().min(1)).max(MAX_LIST_ITEMS).default([]),assumptions:exports_external.array(exports_external.string().min(1)).max(MAX_LIST_ITEMS).default([]),risks:exports_external.array(exports_external.string().min(1)).max(MAX_LIST_ITEMS).default([]),files_touched:exports_external.array(exports_external.string().min(1)).max(50).optional(),evidence_refs:exports_external.array(exports_external.string().min(1)).max(20).default([]),created_at:exports_external.string().datetime(),truncated:exports_external.boolean().optional()});PhaseArchitectureSummarySchema=exports_external.object({schema_version:exports_external.literal(SUMMARY_SCHEMA_VERSION),phase:exports_external.number().int().min(0).max(999),summary:exports_external.string().default(""),agents_seen:exports_external.array(exports_external.string().min(1)).default([]),tasks_seen:exports_external.array(exports_external.string().min(1)).default([]),key_decisions:exports_external.array(exports_external.string().min(1)).default([]),conflicts:exports_external.array(exports_external.string().min(1)).default([]),unresolved_risks:exports_external.array(exports_external.string().min(1)).default([]),constraint_violations:exports_external.array(exports_external.string().min(1)).default([]),evidence_refs:exports_external.array(exports_external.string().min(1)).default([]),created_at:exports_external.string().datetime()}),SupervisorFindingSchema=exports_external.object({severity:exports_external.enum(["low","medium","high","critical"]),category:exports_external.string().min(1),agents:exports_external.array(exports_external.string().min(1)).default([]),tasks:exports_external.array(exports_external.string().min(1)).default([]),evidence_refs:exports_external.array(exports_external.string().min(1)).default([]),description:exports_external.string().min(1),recommendation:exports_external.string().default("")}),KnowledgeRecommendationSchema=exports_external.object({lesson:exports_external.string().min(1),target_agents:exports_external.array(exports_external.string().min(1)).default([]),confidence:exports_external.number().min(0).max(1).default(0.5),evidence_refs:exports_external.array(exports_external.string().min(1)).default([])}),EvidenceProvenanceSchema=exports_external.object({agent_name:exports_external.string().min(1).optional(),session_id:exports_external.string().min(1).optional(),captured_at:exports_external.string().datetime().optional()}),ArchitectureSupervisorReportSchema=exports_external.object({schema_version:exports_external.literal(SUMMARY_SCHEMA_VERSION),phase:exports_external.number().int().min(0).max(999),verdict:SupervisorVerdictSchema,findings:exports_external.array(SupervisorFindingSchema).default([]),knowledge_recommendations:exports_external.array(KnowledgeRecommendationSchema).default([]),created_at:exports_external.string().datetime(),provenance:EvidenceProvenanceSchema.optional()})});import{existsSync as existsSync109,mkdirSync as mkdirSync60,readFileSync as readFileSync84,renameSync as renameSync34,unlinkSync as unlinkSync35,writeFileSync as writeFileSync41}from"node:fs";import*as path211 from"node:path";function writeRawSidecar(absPath,bundle){mkdirSync60(path211.dirname(absPath),{recursive:!0});let tempFile=`${absPath}.tmp-${Date.now()}-${process.pid}`;try{writeFileSync41(tempFile,JSON.stringify(bundle,null,2),"utf-8"),renameSync34(tempFile,absPath),invalidateCachedArtifact(absPath)}finally{if(existsSync109(tempFile))try{unlinkSync35(tempFile)}catch{}}}async function writeAgentSummary(directory,summary){let taskId=summary.task_id??`phase-${summary.phase}-summaries`;return await saveEvidence(directory,taskId,{task_id:taskId,type:"note",timestamp:summary.created_at,agent:summary.agent,verdict:"info",summary:summary.summary,metadata:{kind:AGENT_SUMMARY_METADATA_KIND,phase:summary.phase,session_id:summary.session_id,payload:summary}}),taskId}async function listAgentSummaries(directory,filter={}){let taskIds=await listEvidenceTaskIds(directory),results=[];for(let taskId of taskIds){let loaded=await loadEvidence(directory,taskId);if(loaded.status!=="found")continue;for(let entry of loaded.bundle.entries){if(entry.type!=="note")continue;let meta3=entry.metadata;if(!meta3||meta3.kind!==AGENT_SUMMARY_METADATA_KIND)continue;if(filter.phase!==void 0&&meta3.phase!==filter.phase)continue;if(filter.session!==void 0&&meta3.session_id!==filter.session)continue;let parsed=AgentWorkSummarySchema.safeParse(meta3.payload);if(!parsed.success){warn(`Skipping malformed agent summary in task ${taskId}: ${parsed.error.issues.map((i)=>i.message).join(", ")}`);continue}results.push(parsed.data)}}return results}function writePhaseArchitectureSummary(directory,summary){let rel=path211.join("evidence",String(summary.phase),PHASE_SUMMARY_FILE),abs=validateSwarmPath(directory,rel);return writeRawSidecar(abs,summary),abs}function writeSupervisorReport(directory,report){let rel=path211.join("evidence",String(report.phase),SUPERVISOR_REPORT_FILE),abs=validateSwarmPath(directory,rel),bundle={entries:[{type:SUPERVISOR_ENTRY_TYPE,phase_number:report.phase,scope:"phase",timestamp:report.created_at,verdict:report.verdict,findings:report.findings,knowledge_recommendations:report.knowledge_recommendations,...report.provenance?{provenance:report.provenance}:{}}]};return writeRawSidecar(abs,bundle),abs}function readSupervisorReportRaw(directory,phase){let rel=path211.join("evidence",String(phase),SUPERVISOR_REPORT_FILE),abs;try{abs=validateSwarmPath(directory,rel)}catch{return null}if(!existsSync109(abs))return null;try{return JSON.parse(readFileSync84(abs,"utf-8")).entries?.find((e)=>e.type===SUPERVISOR_ENTRY_TYPE)??null}catch{return null}}var AGENT_SUMMARY_METADATA_KIND="agent_summary",PHASE_SUMMARY_FILE="phase-architecture-summary.json",SUPERVISOR_REPORT_FILE="architecture-supervisor.json",SUPERVISOR_ENTRY_TYPE="architecture-supervisor";var init_store4=__esm(()=>{init_manager2();init_utils2();init_utils();init_swarm_artifact_cache();init_schema3()});var exports_aggregate={};__export(exports_aggregate,{aggregatePhaseSummary:()=>aggregatePhaseSummary});function dedupe2(values){return Array.from(new Set(values)).filter((v)=>v.trim().length>0)}function detectConflicts(summaries){let observedBy=new Map,violatedBy=new Map;for(let s of summaries){for(let c of s.constraints_observed){if(!observedBy.has(c))observedBy.set(c,new Set);observedBy.get(c)?.add(s.agent)}for(let c of s.constraints_violated){if(!violatedBy.has(c))violatedBy.set(c,new Set);violatedBy.get(c)?.add(s.agent)}}let conflicts=[];for(let[constraint,violators]of violatedBy){let observers=observedBy.get(constraint);if(observers&&observers.size>0){let obs=Array.from(observers).sort().join(", "),vio=Array.from(violators).sort().join(", ");conflicts.push(`Constraint "${constraint}" observed by [${obs}] but violated by [${vio}]`)}}return conflicts.sort()}async function aggregatePhaseSummary(directory,phase,options={}){let summaries=await listAgentSummaries(directory,{phase});if(summaries.length===0)return null;let agentsSeen=dedupe2(summaries.map((s)=>s.agent)).sort(),tasksSeen=dedupe2(summaries.map((s)=>s.task_id).filter((t)=>Boolean(t))).sort(),keyDecisions=dedupe2(summaries.flatMap((s)=>s.key_decisions)),unresolvedRisks=dedupe2(summaries.flatMap((s)=>s.risks)),constraintViolations=dedupe2(summaries.flatMap((s)=>s.constraints_violated)),evidenceRefs=dedupe2(summaries.flatMap((s)=>s.evidence_refs)),conflicts=detectConflicts(summaries),headline=`Phase ${phase}: ${summaries.length} agent summary(ies) across ${tasksSeen.length} task(s); ${constraintViolations.length} constraint violation(s), ${conflicts.length} cross-agent conflict(s).`,cap=options.maxPhaseSummaryWords??MAX_PHASE_SUMMARY_WORDS,summaryText=truncateWords(headline,cap).text,phaseSummary={schema_version:SUMMARY_SCHEMA_VERSION,phase,summary:summaryText,agents_seen:agentsSeen,tasks_seen:tasksSeen,key_decisions:keyDecisions,conflicts,unresolved_risks:unresolvedRisks,constraint_violations:constraintViolations,evidence_refs:evidenceRefs,created_at:options.now?.()??new Date().toISOString()};return writePhaseArchitectureSummary(directory,phaseSummary),phaseSummary}var init_aggregate=__esm(()=>{init_schema3();init_store4()});var exports_preflight_integration={};__export(exports_preflight_integration,{runManualPreflight:()=>runManualPreflight,createPreflightIntegration:()=>createPreflightIntegration});function createPreflightIntegration(config3){let{automationConfig,directory,swarmDir,preflightConfig,updateStatusArtifact=!0}=config3;if(automationConfig?.capabilities?.phase_preflight!==!0)throw Error("Preflight is not enabled in automation capabilities. Set automation.capabilities.phase_preflight to true.");let manager=new PreflightTriggerManager(automationConfig,void 0,{directory}),statusArtifact=null;if(updateStatusArtifact&&swarmDir)statusArtifact=new AutomationStatusArtifact(swarmDir);let preflightHandler=async(request)=>{log("[PreflightIntegration] Handling preflight request",{requestId:request.id,phase:request.currentPhase,source:request.source});let report=await runPreflight(directory,request.currentPhase,preflightConfig);if(statusArtifact){let state=report.overall==="pass"?"success":"failure";statusArtifact.recordOutcome(state,request.currentPhase,report.message),log("[PreflightIntegration] Status artifact updated",{state,phase:request.currentPhase,message:report.message})}log("[PreflightIntegration] Preflight complete",{requestId:request.id,overall:report.overall,message:report.message,durationMs:report.totalDurationMs})};return manager.registerHandler(preflightHandler),{manager,cleanup:()=>{manager.unregisterHandler()}}}async function runManualPreflight(directory,phase,config3){return runPreflight(directory,phase,config3)}var init_preflight_integration=__esm(()=>{init_status_artifact();init_trigger();init_preflight_service();init_logger()});var exports_doc_scan={};__export(exports_doc_scan,{scanDocIndex:()=>scanDocIndex,extractDocConstraints:()=>extractDocConstraints,doc_scan:()=>doc_scan,doc_extract:()=>doc_extract});import*as crypto16 from"node:crypto";import*as fs125 from"node:fs";import{mkdir as mkdir46,readdir as readdir14,readFile as readFile48,realpath as realpath11,stat as stat20,writeFile as writeFile28}from"node:fs/promises";import*as path227 from"node:path";function normalizeSeparators(filePath){return filePath.replace(/\\/g,"/")}function matchesDocPattern(filePath,patterns){let normalizedPath2=normalizeSeparators(filePath),basename33=path227.basename(filePath);for(let pattern of patterns){if(!pattern.includes("/")&&!pattern.includes("\\")){if(basename33===pattern)return!0;continue}if(pattern.startsWith("**/")){let filenamePattern=pattern.slice(3);if(basename33===filenamePattern)return!0;continue}let dirPrefix=normalizeSeparators(pattern).replace(/\/\*\*.*$/,"").replace(/\/\*.*$/,"");if(normalizedPath2.startsWith(`${dirPrefix}/`)||normalizedPath2===dirPrefix)return!0}return!1}function extractTitleAndSummary(content,filename){let lines=content.split(`
5838
5845
  `),title=filename,summary="",foundTitle=!1,potentialSummaryLines=[];for(let i=0;i<lines.length&&i<READ_LINES_LIMIT;i++){let line=lines[i].trim();if(!foundTitle&&line.startsWith("# ")){title=line.slice(2).trim(),foundTitle=!0;continue}if(line&&!line.startsWith("#"))potentialSummaryLines.push(line)}for(let line of potentialSummaryLines)if(summary+=(summary?" ":"")+line,summary.length>=MAX_SUMMARY_LENGTH)break;if(summary.length>MAX_SUMMARY_LENGTH)summary=`${summary.slice(0,MAX_SUMMARY_LENGTH-3)}...`;return{title,summary}}function stripMarkdown(text){return text.replace(/\[([^\]]+)\]\([^)]+\)/g,"$1").replace(/\*\*([^*]+)\*\*/g,"$1").replace(/`([^`]+)`/g,"$1").replace(/^\s*[-*•]\s+/gm,"").replace(/^\s*\d+\.\s+/gm,"").trim()}async function scanDocIndex(directory){let manifestPath=path227.join(directory,".swarm","doc-manifest.json"),defaultPatterns=DocsConfigSchema.parse({}).doc_patterns,extraPatterns=["ARCHITECTURE.md","CLAUDE.md","AGENTS.md",".github/*.md","doc/**/*.md"],allPatterns=[...defaultPatterns,...extraPatterns];try{let manifestContent=await readFile48(manifestPath,"utf-8"),existingManifest=JSON.parse(manifestContent);if(existingManifest.schema_version===1&&existingManifest.files){let cacheValid=!0;for(let file3 of existingManifest.files)try{let fullPath=path227.join(directory,file3.path);if(fs125.statSync(fullPath).mtimeMs>file3.mtime){cacheValid=!1;break}}catch{cacheValid=!1;break}if(cacheValid)return{manifest:existingManifest,cached:!0}}}catch{}let resolvedDirectory=await realpath11(directory).catch(()=>directory),discoveredFiles=[],rootReadable=!1,truncated=!1,walkDir2=async(dir)=>{let entries;try{if(entries=await readdir14(dir,{withFileTypes:!0}),dir===directory)rootReadable=!0}catch{return}for(let entry of entries){let isDir=entry.isDirectory(),isFile=entry.isFile();if(entry.isSymbolicLink())try{let symlinkPath=path227.join(dir,entry.name),resolved=await realpath11(symlinkPath),rel=path227.relative(resolvedDirectory,resolved);if(rel.startsWith("..")||path227.isAbsolute(rel))continue;isFile=(await stat20(symlinkPath)).isFile()}catch{continue}if(isDir){if(!SKIP_DIRECTORIES3.has(entry.name))await walkDir2(path227.join(dir,entry.name));continue}if(!isFile)continue;let fullPath=path227.join(dir,entry.name),relPath=normalizeSeparators(path227.relative(directory,fullPath)),skipThisFile=!1;for(let pattern of SKIP_PATTERNS)if(pattern.test(relPath)){skipThisFile=!0;break}if(skipThisFile)continue;if(!matchesDocPattern(relPath,allPatterns))continue;if(discoveredFiles.length>=MAX_INDEXED_FILES){truncated=!0;return}let fileStat;try{fileStat=await stat20(fullPath)}catch{continue}let content;try{content=await readFile48(fullPath,"utf-8")}catch{continue}let{title,summary}=extractTitleAndSummary(content,path227.basename(relPath));discoveredFiles.push({path:relPath,title,summary,lines:content.split(`
5839
5846
  `).length,mtime:fileStat.mtimeMs})}};if(await walkDir2(directory),!rootReadable)return{manifest:{schema_version:1,scanned_at:new Date().toISOString(),files:[]},cached:!1};if(discoveredFiles.sort((a,b)=>a.path.toLowerCase().localeCompare(b.path.toLowerCase())),discoveredFiles.length>MAX_INDEXED_FILES)discoveredFiles.splice(MAX_INDEXED_FILES),truncated=!0;if(truncated&&discoveredFiles.length>0)discoveredFiles[0].summary=`[Warning: ${MAX_INDEXED_FILES}+ docs found, listing first ${MAX_INDEXED_FILES}] `+discoveredFiles[0].summary;let manifest={schema_version:1,scanned_at:new Date().toISOString(),files:discoveredFiles};try{await mkdir46(path227.dirname(manifestPath),{recursive:!0}),await writeFile28(manifestPath,JSON.stringify(manifest,null,2),"utf-8")}catch{}return{manifest,cached:!1}}function isConstraintLine(line){let upperLine=line.toUpperCase();for(let pattern of CONSTRAINT_PATTERNS)if(pattern.test(upperLine))return!0;if(/^\s*[-*•]/.test(line)&&ACTION_WORDS.test(line))return!0;return!1}function extractConstraintsFromContent(content){let lines=content.split(`
5840
- `),constraints=[];for(let line of lines){if(constraints.length>=MAX_CONSTRAINTS_PER_DOC)break;let trimmed=line.trim();if(!trimmed)continue;if(isConstraintLine(trimmed)){let cleaned=stripMarkdown(trimmed),len=cleaned.length;if(len>=MIN_LESSON_LENGTH&&len<=MAX_CONSTRAINT_LENGTH)constraints.push(cleaned)}}return constraints}async function extractDocConstraints(directory,taskFiles,taskDescription){let manifestPath=path227.join(directory,".swarm","doc-manifest.json"),manifest;try{let content=await readFile48(manifestPath,"utf-8");manifest=JSON.parse(content)}catch{manifest=(await scanDocIndex(directory)).manifest}let knowledgePath=resolveSwarmKnowledgePath(directory),existingEntries=await readKnowledge(knowledgePath),taskContext=[...taskFiles,taskDescription].join(" "),taskBigrams=wordBigrams(normalize5(taskContext)),extractedCount=0,skippedCount=0,details=[];for(let docFile of manifest.files){let docContext=`${docFile.path} ${docFile.title} ${docFile.summary}`,docBigrams=wordBigrams(normalize5(docContext)),score=jaccardBigram(taskBigrams,docBigrams);if(score<=RELEVANCE_THRESHOLD){skippedCount++;continue}let fullContent;try{fullContent=await readFile48(path227.join(directory,docFile.path),"utf-8")}catch{skippedCount++;continue}let constraints=extractConstraintsFromContent(fullContent);if(constraints.length===0){skippedCount++;continue}let docDetails={path:docFile.path,score,constraints:[]};for(let constraint of constraints)if(!findNearDuplicate(constraint,existingEntries,DEDUP_THRESHOLD2)){let entry={id:crypto16.randomUUID(),tier:"swarm",lesson:constraint,category:"architecture",tags:["doc-scan",path227.basename(docFile.path)],scope:"global",confidence:0.5,status:"candidate",confirmed_by:[],project_name:"",retrieval_outcomes:{applied_count:0,succeeded_after_count:0,failed_after_count:0},schema_version:1,created_at:new Date().toISOString(),updated_at:new Date().toISOString(),auto_generated:!0,hive_eligible:!1};await appendKnowledge(knowledgePath,entry),existingEntries.push(entry),extractedCount++,docDetails.constraints.push(constraint)}if(docDetails.constraints.length>0)details.push(docDetails);else skippedCount++}return{extracted:extractedCount,skipped:skippedCount,details}}var SKIP_DIRECTORIES3,SKIP_PATTERNS,MAX_SUMMARY_LENGTH=200,MAX_INDEXED_FILES=100,READ_LINES_LIMIT=30,MIN_LESSON_LENGTH=15,MAX_CONSTRAINTS_PER_DOC=5,MAX_CONSTRAINT_LENGTH=200,RELEVANCE_THRESHOLD=0.1,DEDUP_THRESHOLD2=0.6,CONSTRAINT_PATTERNS,ACTION_WORDS,doc_scan,doc_extract;var init_doc_scan=__esm(()=>{init_zod();init_schema();init_knowledge_store();init_create_tool();SKIP_DIRECTORIES3=new Set(["node_modules",".git",".swarm","dist","build",".next","vendor","bazel-out","bazel-bin","bazel-genfiles","bazel-testlogs",".gradle","target"]),SKIP_PATTERNS=[/\.test\./,/\.spec\./,/\.d\.ts$/];CONSTRAINT_PATTERNS=[/\bMUST\b/,/\bMUST NOT\b/,/\bSHOULD\b/,/\bSHOULD NOT\b/,/\bDO NOT\b/,/\bALWAYS\b/,/\bNEVER\b/,/\bREQUIRED\b/],ACTION_WORDS=/\b(must|should|don't|avoid|ensure|use|follow)\b/i;doc_scan=createSwarmTool({description:"Scan project documentation files and build an index manifest. Caches results in .swarm/doc-manifest.json for fast subsequent scans.",args:{force:exports_external.boolean().optional().describe("Force re-scan even if cache is valid")},execute:async(args2,directory)=>{let force=!1;try{if(args2&&typeof args2==="object"){if(args2.force===!0)force=!0}}catch{}if(force){let manifestPath=path227.join(directory,".swarm","doc-manifest.json");try{fs125.unlinkSync(manifestPath)}catch{}}let{manifest,cached:cached3}=await scanDocIndex(directory);return JSON.stringify({success:!0,files_count:manifest.files.length,cached:cached3,manifest},null,2)}}),doc_extract=createSwarmTool({description:"Extract actionable constraints from project documentation relevant to the current task. Scans docs via doc-manifest, scores relevance via Jaccard bigram similarity, and stores non-duplicate constraints in .swarm/knowledge.jsonl.",args:{task_files:exports_external.array(exports_external.string()).describe("List of file paths involved in the current task"),task_description:exports_external.string().describe("Description of the current task")},execute:async(args2,directory)=>{let taskFiles=[],taskDescription="";try{if(args2&&typeof args2==="object"){let obj=args2;if(Array.isArray(obj.task_files))taskFiles=obj.task_files.filter((f)=>typeof f==="string");if(typeof obj.task_description==="string")taskDescription=obj.task_description}}catch{}if(taskFiles.length===0&&!taskDescription)return JSON.stringify({success:!1,error:"task_files or task_description is required"});let result=await extractDocConstraints(directory,taskFiles,taskDescription);return JSON.stringify({success:!0,...result},null,2)}})});import{existsSync as existsSync113}from"node:fs";import{readFile as readFile49}from"node:fs/promises";import*as path228 from"node:path";function inferCategoriesFromPhase(phaseDescription){let lower=phaseDescription.toLowerCase(),patterns=[{pattern:/\b(?:test|qa|quality|verification|validation)\b/,categories:["testing","debugging"]},{pattern:/\b(?:implement|build|develop|coding|code)\b/,categories:["tooling","architecture","debugging"]},{pattern:/\b(?:integrat|deploy|ci|cd|release|publish)\b/,categories:["integration","tooling","performance"]},{pattern:/\b(?:plan|design|architect|spec|requirement)\b/,categories:["architecture","process"]},{pattern:/\b(?:review|refactor|cleanup|polish|optimi)\b/,categories:["performance","architecture","process"]},{pattern:/\b(?:secur|audit|harden|compliance)\b/,categories:["security","testing"]},{pattern:/\b(?:setup|config|scaffold|init|bootstrap)\b/,categories:["tooling","other"]},{pattern:/\b(?:doc|readme|changelog)\b/,categories:["process","tooling"]}];for(let{pattern,categories}of patterns)if(pattern.test(lower))return categories;return["process","tooling"]}async function transactShownFile(shownFile,mutate){return transactFile(shownFile,async(filePath)=>{if(!existsSync113(filePath))return{};try{let content=await readFile49(filePath,"utf-8");return JSON.parse(content)}catch{return{}}},async(filePath,data)=>{await atomicWriteFile(filePath,JSON.stringify(data,null,2))},mutate)}async function recordLessonsShown(directory,lessonIds,currentPhase){if(lessonIds.length===0)return;let shownFile=path228.join(directory,".swarm",".knowledge-shown.json");try{let phaseMatch=/^Phase\s+(\d+)/i.exec(currentPhase),canonicalKey=phaseMatch?`Phase ${phaseMatch[1]}`:currentPhase;if(!await transactShownFile(shownFile,(shownData)=>{let existing=new Set(shownData[canonicalKey]??[]);for(let id of lessonIds)existing.add(id);return shownData[canonicalKey]=[...existing],shownData}))warn("[swarm] Knowledge: failed to record shown lessons")}catch{warn("[swarm] Knowledge: failed to record shown lessons")}}async function readMergedKnowledge(directory,config3,context,opts){let swarmPath3=resolveSwarmKnowledgePath(directory),swarmEntries=await readKnowledge(swarmPath3),hiveEntries=[];if(config3.hive_enabled!==!1){let hivePath=resolveHiveKnowledgePath2();hiveEntries=await readKnowledge(hivePath)}let seenLessons=new Set,merged=[];for(let entry of hiveEntries){let normalized=normalize5(entry.lesson);seenLessons.add(normalized),merged.push({...entry,relevanceScore:{category:0,confidence:0,keywords:0},finalScore:0})}for(let entry of swarmEntries){let normalized=normalize5(entry.lesson);if(seenLessons.has(normalized))continue;let swarmBigrams=wordBigrams(normalized);if(hiveEntries.some((hiveEntry)=>jaccardBigram(swarmBigrams,wordBigrams(normalize5(hiveEntry.lesson)))>=JACCARD_THRESHOLD2))continue;if(merged.some((m)=>m.tier==="swarm"&&jaccardBigram(swarmBigrams,wordBigrams(normalize5(m.lesson)))>=JACCARD_THRESHOLD2))continue;seenLessons.add(normalized),merged.push({...entry,relevanceScore:{category:0,confidence:0,keywords:0},finalScore:0})}let retractionRecords=await readRetractionRecords(directory),suppressedLessons=new Set(retractionRecords.map((record3)=>record3.normalized_lesson).filter((value)=>typeof value==="string"&&value.length>0)),scopeFilter=config3.scope_filter??["global"],ranked=merged.filter((entry)=>(opts?.skipScopeFilter||scopeFilter.some((pattern)=>(entry.scope??"global")===pattern))&&isActiveStatus(entry.status)&&!suppressedLessons.has(normalize5(entry.lesson))).map((entry)=>{let categoryScore=0;if(context?.currentPhase){if(inferCategoriesFromPhase(context.currentPhase).includes(entry.category))categoryScore=1;else if(entry.category==="process")categoryScore=0.5}else categoryScore=0.5;let confidenceScore=entry.confidence,keywordsScore=0;if(context?.techStack&&entry.tags.length>0){let matchingTags=entry.tags.filter((t)=>context.techStack.some((s)=>t.toLowerCase().includes(s.toLowerCase())||s.toLowerCase().includes(t.toLowerCase()))).length;keywordsScore=Math.min(matchingTags/Math.max(entry.tags.length,1),1)}else if(entry.tags.length===0)keywordsScore=0.5;let tierBoost=0,isSameProject=!1;if(entry.tier==="hive"&&"source_project"in entry){let sourceProject=entry.source_project;isSameProject=!!(context?.projectName&&sourceProject===context.projectName),tierBoost=HIVE_TIER_BOOST}let sameProjectPenalty=isSameProject?DEFAULT_SAME_PROJECT_PENALTY:0,finalScore=categoryScore*0.4+confidenceScore*0.35+keywordsScore*0.25+tierBoost+sameProjectPenalty;return{...entry,relevanceScore:{category:categoryScore,confidence:confidenceScore,keywords:keywordsScore},finalScore:Math.min(Math.max(finalScore,0),1)}});ranked.sort((a,b)=>{let scoreDiff=b.finalScore-a.finalScore;if(Math.abs(scoreDiff)>0.001)return scoreDiff;let dateA=new Date(a.created_at).getTime();return new Date(b.created_at).getTime()-dateA});let maxInject=config3.max_inject_count??5;return ranked.slice(0,maxInject)}async function updateRetrievalOutcome(directory,phaseInfo,phaseSucceeded){let shownFile=path228.join(directory,".swarm",".knowledge-shown.json");try{if(!existsSync113(shownFile))return;let shownIds;try{let content=await readFile49(shownFile,"utf-8");shownIds=JSON.parse(content)[phaseInfo]}catch{return}if(!shownIds||shownIds.length===0)return;let outcome=phaseSucceeded?"success":"failure",evidenceSummary=`${phaseInfo} ${phaseSucceeded?"succeeded":"failed"} after entry was shown`;await transactShownFile(shownFile,(data)=>{return delete data[phaseInfo],data});for(let id of shownIds)await _internals169.recordKnowledgeEvent(directory,{type:"outcome",knowledge_id:id,phase:phaseInfo,outcome,evidence_summary:evidenceSummary})}catch{warn("[swarm] Knowledge: failed to update retrieval outcomes")}}function lc(s){return(s??"").toLowerCase()}function anyMatch(haystack,needles){if(needles.length===0)return!1;let hay=haystack.map(lc);return needles.some((n)=>hay.some((h)=>h.includes(lc(n))))}function tokenizeContext(ctx){let parts=[];if(ctx.taskTitle)parts.push(ctx.taskTitle);if(ctx.taskDescription)parts.push(ctx.taskDescription);if(ctx.lastUserMessage)parts.push(ctx.lastUserMessage);if(ctx.currentAction)parts.push(ctx.currentAction);if(ctx.currentTool)parts.push(ctx.currentTool);if(ctx.targetAgent)parts.push(ctx.targetAgent);if(ctx.declaredScope)parts.push(ctx.declaredScope);if(ctx.recentReviewerFailures)parts.push(...ctx.recentReviewerFailures);if(ctx.recentTestFailures)parts.push(...ctx.recentTestFailures);if(ctx.recentToolErrors)parts.push(...ctx.recentToolErrors);if(ctx.planConstraints)parts.push(...ctx.planConstraints);if(ctx.filePaths)parts.push(...ctx.filePaths);return parts.map(lc)}function scoreDirectiveAgainstContext(entry,ctx){let haystack=tokenizeContext(ctx),triggerHit=entry.triggers&&entry.triggers.length>0?anyMatch(haystack,entry.triggers):!1,actionHit=entry.applies_to_tools&&entry.applies_to_tools.length>0?entry.applies_to_tools.map(lc).some((t)=>t===lc(ctx.currentTool)||t===lc(ctx.currentAction)):!1,agentHit=entry.applies_to_agents&&entry.applies_to_agents.length>0?entry.applies_to_agents.map(lc).some((a)=>a===lc(ctx.targetAgent)):!1,score=0;if(triggerHit)score+=0.5;if(actionHit)score+=0.35;if(agentHit)score+=0.25;if(entry.directive_priority==="critical")score+=0.4;else if(entry.directive_priority==="high")score+=0.2;else if(entry.directive_priority==="medium")score+=0.1;return{triggerHit,actionHit,agentHit,score:Math.min(1,score)}}var JACCARD_THRESHOLD2=0.6,HIVE_TIER_BOOST=0.05,DEFAULT_SAME_PROJECT_PENALTY=-0.05,_internals169;var init_knowledge_reader=__esm(()=>{init_task_file();init_logger();init_knowledge_events();init_knowledge_store();init_knowledge_types();_internals169={readMergedKnowledge,updateRetrievalOutcome,scoreDirectiveAgainstContext,transactShownFile,recordKnowledgeEvent,recordLessonsShown}});function entryText(e){return`${e.lesson} ${e.tags.join(" ")} ${e.category}`}function entryAgePhases(e){let cb=e.confirmed_by;if(!Array.isArray(cb)||cb.length===0)return 0;let phases=new Set;for(let c of cb)if(typeof c?.phase_number==="number")phases.add(c.phase_number);return phases.size>0?phases.size:cb.length}function clampLambda(v){if(typeof v!=="number"||Number.isNaN(v))return 0.5;return Math.min(1,Math.max(0,v))}function mmrRerank(pool,pinned,max,lambda){if(pool.length===0)return[];let bigrams=new Map,bg=(e)=>{let s=bigrams.get(e.id);if(!s)s=wordBigrams(normalize5(e.lesson??"")),bigrams.set(e.id,s);return s},selected=[...pinned],candidates=[...pool],out=[];while(selected.length<max&&candidates.length>0){let bestIdx=-1,bestScore=Number.NEGATIVE_INFINITY,best=null;for(let i=0;i<candidates.length;i++){let c=candidates[i],maxSim=0;for(let s of selected){let sim=jaccardBigram(bg(c),bg(s));if(sim>maxSim)maxSim=sim}let score=lambda*c.finalScore-(1-lambda)*maxSim;if(score>bestScore+0.000000001||Math.abs(score-bestScore)<=0.000000001&&best!==null&&tieBreak(c,best)<0)bestScore=score,bestIdx=i,best=c}if(bestIdx<0||best===null)break;out.push(best),selected.push(best),candidates.splice(bestIdx,1)}return out}function tieBreak(a,b){if(Math.abs(a.finalScore-b.finalScore)>0.000000001)return b.finalScore-a.finalScore;let at=new Date(a.created_at).getTime(),bt=new Date(b.created_at).getTime();if(at!==bt)return bt-at;return a.id<b.id?-1:a.id>b.id?1:0}function statusBoost(status){if(status==="promoted")return 0.15;if(status==="established")return 0.1;return 0}async function searchKnowledge(params){let{directory,config:config3,query,context,mode,agent="unknown",sessionId="unknown",tier="all",emitEvent=!1,applyScopeFilter=!0,forceReadHive=!1,applyRoleScope=!0}=params,traceId=newTraceId2(),max=params.maxResults??config3.max_inject_count??5,results=[],synonymTokens=[],synonymTrace={};try{let mergeConfig={...config3,hive_enabled:tier==="swarm"?!1:forceReadHive?!0:config3.hive_enabled,max_inject_count:Math.max(20,max)},projected={projectName:context?.projectName??"unknown",currentPhase:context?.currentPhase??"",techStack:context?.techStack,recentErrors:[...context?.recentReviewerFailures??[],...context?.recentTestFailures??[],...context?.recentToolErrors??[]]},candidates=await readMergedKnowledge(directory,mergeConfig,projected,{skipScopeFilter:!applyScopeFilter}),counterRollups=await readAuthoritativeKnowledgeCounterRollups(directory);candidates=candidates.filter((e)=>{if(!isActiveStatus(e.status))return!1;if(tier==="hive"&&e.tier!=="hive")return!1;return!0});let role=stripKnownSwarmPrefix(agent).toLowerCase();if(applyRoleScope&&role&&role!=="unknown")candidates=candidates.filter((e)=>{if(!e.applies_to_agents||e.applies_to_agents.length===0)return!0;if(role==="architect")return!0;return e.applies_to_agents.map((a)=>stripKnownSwarmPrefix(a).toLowerCase()).includes(role)});let queryText=(query??"").trim(),queryBigrams=queryText?wordBigrams(normalize5(queryText)):null,hasQuery=queryBigrams!==null,textWeight=hasQuery?TEXT_WEIGHT:0,metaWeight=hasQuery?META_WEIGHT:1,compositeRaw=[queryText,context?.taskTitle,context?.taskDescription,context?.lastUserMessage,context?.currentAction,...context?.recentReviewerFailures??[],...context?.recentTestFailures??[],...context?.recentToolErrors??[]].filter((s)=>typeof s==="string"&&s.length>0).join(" "),compositeNorm=normalize5(compositeRaw),hasComposite=compositeNorm.length>0;try{if(hasComposite){let synMap=await readSynonymMap(directory,config3.retrieval?.synonym_map_max_pairs),synIndex=buildSynonymIndex(synMap,config3.retrieval?.synonym_min_cooccurrence),baseTokens=compositeNorm.split(" ").filter(Boolean);synonymTokens=expandTokens(synIndex,baseTokens)}}catch{synonymTokens=[]}let minConf=typeof config3.directive_min_confidence==="number"?config3.directive_min_confidence:DIRECTIVE_BOOST_MIN_CONFIDENCE,scored=candidates.map((entry)=>{let retrievalOutcomes=effectiveRetrievalOutcomes(entry.retrieval_outcomes,counterRollups.get(entry.id)),textScore=queryBigrams?jaccardBigram(queryBigrams,wordBigrams(normalize5(entryText(entry)))):0,metaScore=entry.finalScore,ds=context?scoreDirectiveAgainstContext(entry,context):{triggerHit:!1,actionHit:!1,agentHit:!1,score:0},confBoost=context&&entry.confidence>=minConf&&(ds.actionHit||ds.agentHit)?0.25:0,generatedSkillBoost=entry.generated_skill_path&&entry.status!=="archived"?0.05:0,outcomeBoost=computeOutcomeSignal(retrievalOutcomes)*OUTCOME_RANK_WEIGHT,coldStartBonus=(retrievalOutcomes.applied_explicit_count??0)===0&&entryAgePhases(entry)<(config3.retrieval?.cold_start_max_age_phases??DEFAULT_COLD_START_MAX_AGE_PHASES)?config3.retrieval?.cold_start_bonus??DEFAULT_COLD_START_BONUS:0,synonymBoost=0;if(synonymTokens.length>0){let entryHay=normalize5(entryText(entry)),matched=[];for(let t of synonymTokens)if(t.length>0&&entryHay.includes(t))matched.push(t);if(matched.length>0)synonymBoost=SYNONYM_TEXT_BOOST,synonymTrace[entry.id]=matched}let triggerRecallBoost=!ds.triggerHit&&hasComposite&&Array.isArray(entry.triggers)&&entry.triggers.some((tr)=>{let n=normalize5(tr);return n.length>=TRIGGER_RECALL_MIN_LEN&&compositeNorm.includes(n)})?TRIGGER_RECALL_BOOST:0,finalScore=Math.min(1,Math.max(0,textWeight*textScore+metaWeight*metaScore+ds.score+confBoost+generatedSkillBoost+outcomeBoost+coldStartBonus+synonymBoost+triggerRecallBoost+(hasQuery&&!entry.confidence_floor_demoted?statusBoost(entry.status):0))),statusScoreBoost=hasQuery&&!entry.confidence_floor_demoted?statusBoost(entry.status):0,isCritical=entry.directive_priority==="critical"&&(ds.triggerHit||ds.actionHit||ds.agentHit),isForceHive=forceReadHive&&entry.tier==="hive";return{...entry,retrieval_outcomes:retrievalOutcomes,finalScore,coldStartBoost:coldStartBonus,score_breakdown:{text_score:textScore,metadata_score:metaScore,directive_score:ds.score,confidence_boost:confBoost,generated_skill_boost:generatedSkillBoost,outcome_boost:outcomeBoost,cold_start_boost:coldStartBonus,synonym_boost:synonymBoost,trigger_recall_boost:triggerRecallBoost,status_boost:statusScoreBoost,final_score:finalScore,...synonymTrace[entry.id]?{synonym_matches:synonymTrace[entry.id]}:{}},__critical:isCritical,__forceHive:isForceHive}});scored.sort((a,b)=>{let diff=b.finalScore-a.finalScore;if(Math.abs(diff)>0.001)return diff;return new Date(b.created_at).getTime()-new Date(a.created_at).getTime()});let top=[],seen=new Set;for(let e of scored){if(top.length>=max)break;if(e.__critical&&!seen.has(e.id))top.push(e),seen.add(e.id)}for(let e of scored){if(top.length>=max)break;if(e.__forceHive&&!seen.has(e.id))top.push(e),seen.add(e.id)}let lambda=clampLambda(config3.retrieval?.mmr_lambda),remaining=scored.filter((e)=>!seen.has(e.id)),selected=mmrRerank(remaining,top,max,lambda);for(let e of selected){if(top.length>=max)break;if(!seen.has(e.id))top.push(e),seen.add(e.id)}results=top.map(({__critical:_c,__forceHive:_f,...rest})=>rest)}catch(err){warn(`[search-knowledge] retrieval failed: ${err instanceof Error?err.message:String(err)}`),results=[]}if(emitEvent){let ranks={},scores={};results.forEach((e,idx)=>{ranks[e.id]=idx+1,scores[e.id]=e.finalScore});let synonymBreakdown={};for(let e of results)if(synonymTrace[e.id])synonymBreakdown[e.id]=synonymTrace[e.id];let scoreBreakdown=synonymTokens.length>0?{synonyms_expanded:synonymTokens,synonym_matches:synonymBreakdown}:void 0;await recordKnowledgeEvent(directory,{type:"retrieved",trace_id:traceId,session_id:sessionId,phase:context?.currentPhase,task_id:context?.taskId,agent,query:query??context?.lastUserMessage??context?.currentPhase??"",retrieval_mode:mode,result_ids:results.map((e)=>e.id),ranks,scores,...scoreBreakdown?{score_breakdown:scoreBreakdown}:{}})}return{trace_id:traceId,results}}var TEXT_WEIGHT=0.6,META_WEIGHT=0.4,DIRECTIVE_BOOST_MIN_CONFIDENCE=0.75,SYNONYM_TEXT_BOOST=0.15,TRIGGER_RECALL_BOOST=0.3,TRIGGER_RECALL_MIN_LEN=3,DEFAULT_COLD_START_BONUS=0.08,DEFAULT_COLD_START_MAX_AGE_PHASES=3,OUTCOME_RANK_WEIGHT=0.1;var init_search_knowledge=__esm(()=>{init_schema();init_synonym_map();init_logger();init_knowledge_events();init_knowledge_reader();init_knowledge_store();init_knowledge_types()});var exports_knowledge_recall={};__export(exports_knowledge_recall,{knowledge_recall:()=>knowledge_recall,_internals:()=>_internals170});var knowledge_recall,_internals170;var init_knowledge_recall=__esm(()=>{init_zod();init_config();init_schema();init_knowledge_events();init_knowledge_receipt_ledger();init_knowledge_types();init_search_knowledge();init_knowledge_diagnostics();init_logger();init_create_tool();knowledge_recall=createSwarmTool({allowWorkingDirectoryOverride:!0,description:"Performs semantic natural-language search across the knowledge base for relevant past decisions, patterns, and lessons learned. Returns ranked results via the unified hybrid retrieval service and a trace_id for knowledge_receipt. This is the tool to use when the user has a QUESTION about what the knowledge base contains. For structured filter-based retrieval (by category, status, or score), use `knowledge_query` instead.",args:{query:exports_external.string().min(3).describe("Natural language search query"),top_n:exports_external.number().int().min(1).max(20).optional().describe("Maximum results to return (default: 5)"),tier:exports_external.enum(["all","swarm","hive"]).optional().describe("Knowledge tier to search (default: 'all')"),debug:exports_external.boolean().optional().describe("Include path/version/health debug metadata in the response")},execute:async(args2,directory,ctx)=>{let queryInput,topNInput,tierInput,debugInput;try{if(args2&&typeof args2==="object"){let obj=args2;queryInput=obj.query,topNInput=obj.top_n,tierInput=obj.tier,debugInput=obj.debug}}catch{}let wantDebug=debugInput===!0;if(typeof queryInput!=="string"||queryInput.length<3)return JSON.stringify({results:[],total:0,error:"query must be a string with at least 3 characters"});let topN=5;if(typeof topNInput==="number"&&Number.isInteger(topNInput))topN=Math.max(1,Math.min(20,topNInput));let tier="all";if(tierInput==="swarm"||tierInput==="hive")tier=tierInput;let knowledgeConfig=KnowledgeConfigSchema.parse({});try{let{config:config3}=loadPluginConfigWithMeta(directory);knowledgeConfig=KnowledgeConfigSchema.parse(config3.knowledge??{})}catch{}let{trace_id,results}=await searchKnowledge({directory,config:knowledgeConfig,query:queryInput,mode:"manual",agent:ctx?.agent??"unknown",sessionId:ctx?.sessionID??"unknown",tier,maxResults:topN,applyScopeFilter:!1,forceReadHive:!0,applyRoleScope:!1,emitEvent:!1}),sessionId=ctx?.sessionID??"unknown";if(results.length>0){let membership=await commitDisplayedMembership(directory,{trace_id,session_id:sessionId,exposure_kind:"manual_recall",agent:ctx?.agent??"unknown",grace_days:knowledgeConfig.receipt_close_grace_days,entries:results.map((entry,index)=>({entry_id:entry.id,critical:entry.directive_priority==="critical"&&isActiveStatus(entry.status),rank:index+1,score:entry.finalScore}))});if(!membership.ok||membership.memberships.some((item)=>item.terminal))return JSON.stringify({results:[],total:0,unverifiable:!0,code:membership.ok?"terminal_trace_reuse":membership.code,error:membership.ok?"retrieval trace was already terminalized":membership.detail})}else{let empty=await commitEmptyRetrieval(directory,{trace_id,session_id:sessionId,agent:ctx?.agent??"unknown",grace_days:knowledgeConfig.receipt_close_grace_days});if(!empty.ok)return JSON.stringify({results:[],total:0,unverifiable:!0,code:empty.code,error:empty.detail});if(!empty.terminal_event_id)return JSON.stringify({results:[],total:0,unverifiable:!0,code:"store_unavailable",error:"empty retrieval terminal did not commit"})}let ranks=Object.fromEntries(results.map((entry,index)=>[entry.id,index+1])),scores=Object.fromEntries(results.map((entry)=>[entry.id,entry.finalScore]));await recordKnowledgeEvent(directory,{type:"retrieved",trace_id,session_id:sessionId,agent:ctx?.agent??"unknown",query:queryInput,retrieval_mode:"manual",result_ids:results.map((entry)=>entry.id),ranks,scores});let scored=results.map((e)=>({id:e.id,confidence:e.confidence,category:e.category,lesson:e.lesson,score:e.finalScore,score_breakdown:e.score_breakdown}));log("[knowledge_recall] completed",{agent:ctx?.agent??"unknown",session_id:ctx?.sessionID??"unknown",query:queryInput,tier,result_count:scored.length,trace_id});let result={results:scored,total:scored.length,trace_id};if(wantDebug)result.debug=await computeKnowledgeDebug(directory);return JSON.stringify(result)}}),_internals170={knowledge_recall}});var exports_prompt_renderer={};__export(exports_prompt_renderer,{renderEnvironmentPrompt:()=>renderEnvironmentPrompt});function renderEnvironmentPrompt(profile,audience){let policy=deriveCommandPolicy(profile),header=["RUNTIME ENVIRONMENT",`- Host OS: ${profile.hostOS}`,`- Shell family: ${profile.shellFamily}`,`- Execution mode: ${profile.executionMode}`,`- Path style: ${profile.pathStyle}`].join(`
5847
+ `),constraints=[];for(let line of lines){if(constraints.length>=MAX_CONSTRAINTS_PER_DOC)break;let trimmed=line.trim();if(!trimmed)continue;if(isConstraintLine(trimmed)){let cleaned=stripMarkdown(trimmed),len=cleaned.length;if(len>=MIN_LESSON_LENGTH&&len<=MAX_CONSTRAINT_LENGTH)constraints.push(cleaned)}}return constraints}async function extractDocConstraints(directory,taskFiles,taskDescription){let manifestPath=path227.join(directory,".swarm","doc-manifest.json"),manifest;try{let content=await readFile48(manifestPath,"utf-8");manifest=JSON.parse(content)}catch{manifest=(await scanDocIndex(directory)).manifest}let knowledgePath=resolveSwarmKnowledgePath(directory),existingEntries=await readKnowledge(knowledgePath),taskContext=[...taskFiles,taskDescription].join(" "),taskBigrams=wordBigrams(normalize5(taskContext)),extractedCount=0,skippedCount=0,details=[];for(let docFile of manifest.files){let docContext=`${docFile.path} ${docFile.title} ${docFile.summary}`,docBigrams=wordBigrams(normalize5(docContext)),score=jaccardBigram(taskBigrams,docBigrams);if(score<=RELEVANCE_THRESHOLD){skippedCount++;continue}let fullContent;try{fullContent=await readFile48(path227.join(directory,docFile.path),"utf-8")}catch{skippedCount++;continue}let constraints=extractConstraintsFromContent(fullContent);if(constraints.length===0){skippedCount++;continue}let docDetails={path:docFile.path,score,constraints:[]};for(let constraint of constraints)if(!findNearDuplicate(constraint,existingEntries,DEDUP_THRESHOLD2)){let entry={id:crypto16.randomUUID(),tier:"swarm",lesson:constraint,category:"architecture",tags:["doc-scan",path227.basename(docFile.path)],scope:"global",confidence:0.5,status:"candidate",confirmed_by:[],project_name:"",retrieval_outcomes:{applied_count:0,succeeded_after_count:0,failed_after_count:0},schema_version:1,created_at:new Date().toISOString(),updated_at:new Date().toISOString(),auto_generated:!0,hive_eligible:!1};await appendKnowledge(knowledgePath,entry),existingEntries.push(entry),extractedCount++,docDetails.constraints.push(constraint)}if(docDetails.constraints.length>0)details.push(docDetails);else skippedCount++}return{extracted:extractedCount,skipped:skippedCount,details}}var SKIP_DIRECTORIES3,SKIP_PATTERNS,MAX_SUMMARY_LENGTH=200,MAX_INDEXED_FILES=100,READ_LINES_LIMIT=30,MIN_LESSON_LENGTH=15,MAX_CONSTRAINTS_PER_DOC=5,MAX_CONSTRAINT_LENGTH=200,RELEVANCE_THRESHOLD=0.1,DEDUP_THRESHOLD2=0.6,CONSTRAINT_PATTERNS,ACTION_WORDS,doc_scan,doc_extract;var init_doc_scan=__esm(()=>{init_zod();init_schema();init_knowledge_store();init_create_tool();SKIP_DIRECTORIES3=new Set(["node_modules",".git",".swarm","dist","build",".next","vendor","bazel-out","bazel-bin","bazel-genfiles","bazel-testlogs",".gradle","target"]),SKIP_PATTERNS=[/\.test\./,/\.spec\./,/\.d\.ts$/];CONSTRAINT_PATTERNS=[/\bMUST\b/,/\bMUST NOT\b/,/\bSHOULD\b/,/\bSHOULD NOT\b/,/\bDO NOT\b/,/\bALWAYS\b/,/\bNEVER\b/,/\bREQUIRED\b/],ACTION_WORDS=/\b(must|should|don't|avoid|ensure|use|follow)\b/i;doc_scan=createSwarmTool({description:"Scan project documentation files and build an index manifest. Caches results in .swarm/doc-manifest.json for fast subsequent scans.",args:{force:exports_external.boolean().optional().describe("Force re-scan even if cache is valid")},execute:async(args2,directory)=>{let force=!1;try{if(args2&&typeof args2==="object"){if(args2.force===!0)force=!0}}catch{}if(force){let manifestPath=path227.join(directory,".swarm","doc-manifest.json");try{fs125.unlinkSync(manifestPath)}catch{}}let{manifest,cached:cached3}=await scanDocIndex(directory);return JSON.stringify({success:!0,files_count:manifest.files.length,cached:cached3,manifest},null,2)}}),doc_extract=createSwarmTool({description:"Extract actionable constraints from project documentation relevant to the current task. Scans docs via doc-manifest, scores relevance via Jaccard bigram similarity, and stores non-duplicate constraints in .swarm/knowledge.jsonl.",args:{task_files:exports_external.array(exports_external.string()).describe("List of file paths involved in the current task"),task_description:exports_external.string().describe("Description of the current task")},execute:async(args2,directory)=>{let taskFiles=[],taskDescription="";try{if(args2&&typeof args2==="object"){let obj=args2;if(Array.isArray(obj.task_files))taskFiles=obj.task_files.filter((f)=>typeof f==="string");if(typeof obj.task_description==="string")taskDescription=obj.task_description}}catch{}if(taskFiles.length===0&&!taskDescription)return JSON.stringify({success:!1,error:"task_files or task_description is required"});let result=await extractDocConstraints(directory,taskFiles,taskDescription);return JSON.stringify({success:!0,...result},null,2)}})});import{existsSync as existsSync114}from"node:fs";import{readFile as readFile49}from"node:fs/promises";import*as path228 from"node:path";function inferCategoriesFromPhase(phaseDescription){let lower=phaseDescription.toLowerCase(),patterns=[{pattern:/\b(?:test|qa|quality|verification|validation)\b/,categories:["testing","debugging"]},{pattern:/\b(?:implement|build|develop|coding|code)\b/,categories:["tooling","architecture","debugging"]},{pattern:/\b(?:integrat|deploy|ci|cd|release|publish)\b/,categories:["integration","tooling","performance"]},{pattern:/\b(?:plan|design|architect|spec|requirement)\b/,categories:["architecture","process"]},{pattern:/\b(?:review|refactor|cleanup|polish|optimi)\b/,categories:["performance","architecture","process"]},{pattern:/\b(?:secur|audit|harden|compliance)\b/,categories:["security","testing"]},{pattern:/\b(?:setup|config|scaffold|init|bootstrap)\b/,categories:["tooling","other"]},{pattern:/\b(?:doc|readme|changelog)\b/,categories:["process","tooling"]}];for(let{pattern,categories}of patterns)if(pattern.test(lower))return categories;return["process","tooling"]}async function transactShownFile(shownFile,mutate){return transactFile(shownFile,async(filePath)=>{if(!existsSync114(filePath))return{};try{let content=await readFile49(filePath,"utf-8");return JSON.parse(content)}catch{return{}}},async(filePath,data)=>{await atomicWriteFile(filePath,JSON.stringify(data,null,2))},mutate)}async function recordLessonsShown(directory,lessonIds,currentPhase){if(lessonIds.length===0)return;let shownFile=path228.join(directory,".swarm",".knowledge-shown.json");try{let phaseMatch=/^Phase\s+(\d+)/i.exec(currentPhase),canonicalKey=phaseMatch?`Phase ${phaseMatch[1]}`:currentPhase;if(!await transactShownFile(shownFile,(shownData)=>{let existing=new Set(shownData[canonicalKey]??[]);for(let id of lessonIds)existing.add(id);return shownData[canonicalKey]=[...existing],shownData}))warn("[swarm] Knowledge: failed to record shown lessons")}catch{warn("[swarm] Knowledge: failed to record shown lessons")}}async function readMergedKnowledge(directory,config3,context,opts){let swarmPath3=resolveSwarmKnowledgePath(directory),swarmEntries=await readKnowledge(swarmPath3),hiveEntries=[];if(config3.hive_enabled!==!1){let hivePath=resolveHiveKnowledgePath2();hiveEntries=await readKnowledge(hivePath)}let seenLessons=new Set,merged=[];for(let entry of hiveEntries){let normalized=normalize5(entry.lesson);seenLessons.add(normalized),merged.push({...entry,relevanceScore:{category:0,confidence:0,keywords:0},finalScore:0})}for(let entry of swarmEntries){let normalized=normalize5(entry.lesson);if(seenLessons.has(normalized))continue;let swarmBigrams=wordBigrams(normalized);if(hiveEntries.some((hiveEntry)=>jaccardBigram(swarmBigrams,wordBigrams(normalize5(hiveEntry.lesson)))>=JACCARD_THRESHOLD2))continue;if(merged.some((m)=>m.tier==="swarm"&&jaccardBigram(swarmBigrams,wordBigrams(normalize5(m.lesson)))>=JACCARD_THRESHOLD2))continue;seenLessons.add(normalized),merged.push({...entry,relevanceScore:{category:0,confidence:0,keywords:0},finalScore:0})}let retractionRecords=await readRetractionRecords(directory),suppressedLessons=new Set(retractionRecords.map((record3)=>record3.normalized_lesson).filter((value)=>typeof value==="string"&&value.length>0)),scopeFilter=config3.scope_filter??["global"],ranked=merged.filter((entry)=>(opts?.skipScopeFilter||scopeFilter.some((pattern)=>(entry.scope??"global")===pattern))&&isActiveStatus(entry.status)&&!suppressedLessons.has(normalize5(entry.lesson))).map((entry)=>{let categoryScore=0;if(context?.currentPhase){if(inferCategoriesFromPhase(context.currentPhase).includes(entry.category))categoryScore=1;else if(entry.category==="process")categoryScore=0.5}else categoryScore=0.5;let confidenceScore=entry.confidence,keywordsScore=0;if(context?.techStack&&entry.tags.length>0){let matchingTags=entry.tags.filter((t)=>context.techStack.some((s)=>t.toLowerCase().includes(s.toLowerCase())||s.toLowerCase().includes(t.toLowerCase()))).length;keywordsScore=Math.min(matchingTags/Math.max(entry.tags.length,1),1)}else if(entry.tags.length===0)keywordsScore=0.5;let tierBoost=0,isSameProject=!1;if(entry.tier==="hive"&&"source_project"in entry){let sourceProject=entry.source_project;isSameProject=!!(context?.projectName&&sourceProject===context.projectName),tierBoost=HIVE_TIER_BOOST}let sameProjectPenalty=isSameProject?DEFAULT_SAME_PROJECT_PENALTY:0,finalScore=categoryScore*0.4+confidenceScore*0.35+keywordsScore*0.25+tierBoost+sameProjectPenalty;return{...entry,relevanceScore:{category:categoryScore,confidence:confidenceScore,keywords:keywordsScore},finalScore:Math.min(Math.max(finalScore,0),1)}});ranked.sort((a,b)=>{let scoreDiff=b.finalScore-a.finalScore;if(Math.abs(scoreDiff)>0.001)return scoreDiff;let dateA=new Date(a.created_at).getTime();return new Date(b.created_at).getTime()-dateA});let maxInject=config3.max_inject_count??5;return ranked.slice(0,maxInject)}async function updateRetrievalOutcome(directory,phaseInfo,phaseSucceeded){let shownFile=path228.join(directory,".swarm",".knowledge-shown.json");try{if(!existsSync114(shownFile))return;let shownIds;try{let content=await readFile49(shownFile,"utf-8");shownIds=JSON.parse(content)[phaseInfo]}catch{return}if(!shownIds||shownIds.length===0)return;let outcome=phaseSucceeded?"success":"failure",evidenceSummary=`${phaseInfo} ${phaseSucceeded?"succeeded":"failed"} after entry was shown`;await transactShownFile(shownFile,(data)=>{return delete data[phaseInfo],data});for(let id of shownIds)await _internals169.recordKnowledgeEvent(directory,{type:"outcome",knowledge_id:id,phase:phaseInfo,outcome,evidence_summary:evidenceSummary})}catch{warn("[swarm] Knowledge: failed to update retrieval outcomes")}}function lc(s){return(s??"").toLowerCase()}function anyMatch(haystack,needles){if(needles.length===0)return!1;let hay=haystack.map(lc);return needles.some((n)=>hay.some((h)=>h.includes(lc(n))))}function tokenizeContext(ctx){let parts=[];if(ctx.taskTitle)parts.push(ctx.taskTitle);if(ctx.taskDescription)parts.push(ctx.taskDescription);if(ctx.lastUserMessage)parts.push(ctx.lastUserMessage);if(ctx.currentAction)parts.push(ctx.currentAction);if(ctx.currentTool)parts.push(ctx.currentTool);if(ctx.targetAgent)parts.push(ctx.targetAgent);if(ctx.declaredScope)parts.push(ctx.declaredScope);if(ctx.recentReviewerFailures)parts.push(...ctx.recentReviewerFailures);if(ctx.recentTestFailures)parts.push(...ctx.recentTestFailures);if(ctx.recentToolErrors)parts.push(...ctx.recentToolErrors);if(ctx.planConstraints)parts.push(...ctx.planConstraints);if(ctx.filePaths)parts.push(...ctx.filePaths);return parts.map(lc)}function scoreDirectiveAgainstContext(entry,ctx){let haystack=tokenizeContext(ctx),triggerHit=entry.triggers&&entry.triggers.length>0?anyMatch(haystack,entry.triggers):!1,actionHit=entry.applies_to_tools&&entry.applies_to_tools.length>0?entry.applies_to_tools.map(lc).some((t)=>t===lc(ctx.currentTool)||t===lc(ctx.currentAction)):!1,agentHit=entry.applies_to_agents&&entry.applies_to_agents.length>0?entry.applies_to_agents.map(lc).some((a)=>a===lc(ctx.targetAgent)):!1,score=0;if(triggerHit)score+=0.5;if(actionHit)score+=0.35;if(agentHit)score+=0.25;if(entry.directive_priority==="critical")score+=0.4;else if(entry.directive_priority==="high")score+=0.2;else if(entry.directive_priority==="medium")score+=0.1;return{triggerHit,actionHit,agentHit,score:Math.min(1,score)}}var JACCARD_THRESHOLD2=0.6,HIVE_TIER_BOOST=0.05,DEFAULT_SAME_PROJECT_PENALTY=-0.05,_internals169;var init_knowledge_reader=__esm(()=>{init_task_file();init_logger();init_knowledge_events();init_knowledge_store();init_knowledge_types();_internals169={readMergedKnowledge,updateRetrievalOutcome,scoreDirectiveAgainstContext,transactShownFile,recordKnowledgeEvent,recordLessonsShown}});function entryText(e){return`${e.lesson} ${e.tags.join(" ")} ${e.category}`}function entryAgePhases(e){let cb=e.confirmed_by;if(!Array.isArray(cb)||cb.length===0)return 0;let phases=new Set;for(let c of cb)if(typeof c?.phase_number==="number")phases.add(c.phase_number);return phases.size>0?phases.size:cb.length}function clampLambda(v){if(typeof v!=="number"||Number.isNaN(v))return 0.5;return Math.min(1,Math.max(0,v))}function mmrRerank(pool,pinned,max,lambda){if(pool.length===0)return[];let bigrams=new Map,bg=(e)=>{let s=bigrams.get(e.id);if(!s)s=wordBigrams(normalize5(e.lesson??"")),bigrams.set(e.id,s);return s},selected=[...pinned],candidates=[...pool],out=[];while(selected.length<max&&candidates.length>0){let bestIdx=-1,bestScore=Number.NEGATIVE_INFINITY,best=null;for(let i=0;i<candidates.length;i++){let c=candidates[i],maxSim=0;for(let s of selected){let sim=jaccardBigram(bg(c),bg(s));if(sim>maxSim)maxSim=sim}let score=lambda*c.finalScore-(1-lambda)*maxSim;if(score>bestScore+0.000000001||Math.abs(score-bestScore)<=0.000000001&&best!==null&&tieBreak(c,best)<0)bestScore=score,bestIdx=i,best=c}if(bestIdx<0||best===null)break;out.push(best),selected.push(best),candidates.splice(bestIdx,1)}return out}function tieBreak(a,b){if(Math.abs(a.finalScore-b.finalScore)>0.000000001)return b.finalScore-a.finalScore;let at=new Date(a.created_at).getTime(),bt=new Date(b.created_at).getTime();if(at!==bt)return bt-at;return a.id<b.id?-1:a.id>b.id?1:0}function statusBoost(status){if(status==="promoted")return 0.15;if(status==="established")return 0.1;return 0}async function searchKnowledge(params){let{directory,config:config3,query,context,mode,agent="unknown",sessionId="unknown",tier="all",emitEvent=!1,applyScopeFilter=!0,forceReadHive=!1,applyRoleScope=!0}=params,traceId=newTraceId2(),max=params.maxResults??config3.max_inject_count??5,results=[],synonymTokens=[],synonymTrace={};try{let mergeConfig={...config3,hive_enabled:tier==="swarm"?!1:forceReadHive?!0:config3.hive_enabled,max_inject_count:Math.max(20,max)},projected={projectName:context?.projectName??"unknown",currentPhase:context?.currentPhase??"",techStack:context?.techStack,recentErrors:[...context?.recentReviewerFailures??[],...context?.recentTestFailures??[],...context?.recentToolErrors??[]]},candidates=await readMergedKnowledge(directory,mergeConfig,projected,{skipScopeFilter:!applyScopeFilter}),counterRollups=await readAuthoritativeKnowledgeCounterRollups(directory);candidates=candidates.filter((e)=>{if(!isActiveStatus(e.status))return!1;if(tier==="hive"&&e.tier!=="hive")return!1;return!0});let role=stripKnownSwarmPrefix(agent).toLowerCase();if(applyRoleScope&&role&&role!=="unknown")candidates=candidates.filter((e)=>{if(!e.applies_to_agents||e.applies_to_agents.length===0)return!0;if(role==="architect")return!0;return e.applies_to_agents.map((a)=>stripKnownSwarmPrefix(a).toLowerCase()).includes(role)});let queryText=(query??"").trim(),queryBigrams=queryText?wordBigrams(normalize5(queryText)):null,hasQuery=queryBigrams!==null,textWeight=hasQuery?TEXT_WEIGHT:0,metaWeight=hasQuery?META_WEIGHT:1,compositeRaw=[queryText,context?.taskTitle,context?.taskDescription,context?.lastUserMessage,context?.currentAction,...context?.recentReviewerFailures??[],...context?.recentTestFailures??[],...context?.recentToolErrors??[]].filter((s)=>typeof s==="string"&&s.length>0).join(" "),compositeNorm=normalize5(compositeRaw),hasComposite=compositeNorm.length>0;try{if(hasComposite){let synMap=await readSynonymMap(directory,config3.retrieval?.synonym_map_max_pairs),synIndex=buildSynonymIndex(synMap,config3.retrieval?.synonym_min_cooccurrence),baseTokens=compositeNorm.split(" ").filter(Boolean);synonymTokens=expandTokens(synIndex,baseTokens)}}catch{synonymTokens=[]}let minConf=typeof config3.directive_min_confidence==="number"?config3.directive_min_confidence:DIRECTIVE_BOOST_MIN_CONFIDENCE,scored=candidates.map((entry)=>{let retrievalOutcomes=effectiveRetrievalOutcomes(entry.retrieval_outcomes,counterRollups.get(entry.id)),textScore=queryBigrams?jaccardBigram(queryBigrams,wordBigrams(normalize5(entryText(entry)))):0,metaScore=entry.finalScore,ds=context?scoreDirectiveAgainstContext(entry,context):{triggerHit:!1,actionHit:!1,agentHit:!1,score:0},confBoost=context&&entry.confidence>=minConf&&(ds.actionHit||ds.agentHit)?0.25:0,generatedSkillBoost=entry.generated_skill_path&&entry.status!=="archived"?0.05:0,outcomeBoost=computeOutcomeSignal(retrievalOutcomes)*OUTCOME_RANK_WEIGHT,coldStartBonus=(retrievalOutcomes.applied_explicit_count??0)===0&&entryAgePhases(entry)<(config3.retrieval?.cold_start_max_age_phases??DEFAULT_COLD_START_MAX_AGE_PHASES)?config3.retrieval?.cold_start_bonus??DEFAULT_COLD_START_BONUS:0,synonymBoost=0;if(synonymTokens.length>0){let entryHay=normalize5(entryText(entry)),matched=[];for(let t of synonymTokens)if(t.length>0&&entryHay.includes(t))matched.push(t);if(matched.length>0)synonymBoost=SYNONYM_TEXT_BOOST,synonymTrace[entry.id]=matched}let triggerRecallBoost=!ds.triggerHit&&hasComposite&&Array.isArray(entry.triggers)&&entry.triggers.some((tr)=>{let n=normalize5(tr);return n.length>=TRIGGER_RECALL_MIN_LEN&&compositeNorm.includes(n)})?TRIGGER_RECALL_BOOST:0,finalScore=Math.min(1,Math.max(0,textWeight*textScore+metaWeight*metaScore+ds.score+confBoost+generatedSkillBoost+outcomeBoost+coldStartBonus+synonymBoost+triggerRecallBoost+(hasQuery&&!entry.confidence_floor_demoted?statusBoost(entry.status):0))),statusScoreBoost=hasQuery&&!entry.confidence_floor_demoted?statusBoost(entry.status):0,isCritical=entry.directive_priority==="critical"&&(ds.triggerHit||ds.actionHit||ds.agentHit),isForceHive=forceReadHive&&entry.tier==="hive";return{...entry,retrieval_outcomes:retrievalOutcomes,finalScore,coldStartBoost:coldStartBonus,score_breakdown:{text_score:textScore,metadata_score:metaScore,directive_score:ds.score,confidence_boost:confBoost,generated_skill_boost:generatedSkillBoost,outcome_boost:outcomeBoost,cold_start_boost:coldStartBonus,synonym_boost:synonymBoost,trigger_recall_boost:triggerRecallBoost,status_boost:statusScoreBoost,final_score:finalScore,...synonymTrace[entry.id]?{synonym_matches:synonymTrace[entry.id]}:{}},__critical:isCritical,__forceHive:isForceHive}});scored.sort((a,b)=>{let diff=b.finalScore-a.finalScore;if(Math.abs(diff)>0.001)return diff;return new Date(b.created_at).getTime()-new Date(a.created_at).getTime()});let top=[],seen=new Set;for(let e of scored){if(top.length>=max)break;if(e.__critical&&!seen.has(e.id))top.push(e),seen.add(e.id)}for(let e of scored){if(top.length>=max)break;if(e.__forceHive&&!seen.has(e.id))top.push(e),seen.add(e.id)}let lambda=clampLambda(config3.retrieval?.mmr_lambda),remaining=scored.filter((e)=>!seen.has(e.id)),selected=mmrRerank(remaining,top,max,lambda);for(let e of selected){if(top.length>=max)break;if(!seen.has(e.id))top.push(e),seen.add(e.id)}results=top.map(({__critical:_c,__forceHive:_f,...rest})=>rest)}catch(err){warn(`[search-knowledge] retrieval failed: ${err instanceof Error?err.message:String(err)}`),results=[]}if(emitEvent){let ranks={},scores={};results.forEach((e,idx)=>{ranks[e.id]=idx+1,scores[e.id]=e.finalScore});let synonymBreakdown={};for(let e of results)if(synonymTrace[e.id])synonymBreakdown[e.id]=synonymTrace[e.id];let scoreBreakdown=synonymTokens.length>0?{synonyms_expanded:synonymTokens,synonym_matches:synonymBreakdown}:void 0;await recordKnowledgeEvent(directory,{type:"retrieved",trace_id:traceId,session_id:sessionId,phase:context?.currentPhase,task_id:context?.taskId,agent,query:query??context?.lastUserMessage??context?.currentPhase??"",retrieval_mode:mode,result_ids:results.map((e)=>e.id),ranks,scores,...scoreBreakdown?{score_breakdown:scoreBreakdown}:{}})}return{trace_id:traceId,results}}var TEXT_WEIGHT=0.6,META_WEIGHT=0.4,DIRECTIVE_BOOST_MIN_CONFIDENCE=0.75,SYNONYM_TEXT_BOOST=0.15,TRIGGER_RECALL_BOOST=0.3,TRIGGER_RECALL_MIN_LEN=3,DEFAULT_COLD_START_BONUS=0.08,DEFAULT_COLD_START_MAX_AGE_PHASES=3,OUTCOME_RANK_WEIGHT=0.1;var init_search_knowledge=__esm(()=>{init_schema();init_synonym_map();init_logger();init_knowledge_events();init_knowledge_reader();init_knowledge_store();init_knowledge_types()});var exports_knowledge_recall={};__export(exports_knowledge_recall,{knowledge_recall:()=>knowledge_recall,_internals:()=>_internals170});var knowledge_recall,_internals170;var init_knowledge_recall=__esm(()=>{init_zod();init_config();init_schema();init_knowledge_events();init_knowledge_receipt_ledger();init_knowledge_types();init_search_knowledge();init_knowledge_diagnostics();init_logger();init_create_tool();knowledge_recall=createSwarmTool({allowWorkingDirectoryOverride:!0,description:"Performs semantic natural-language search across the knowledge base for relevant past decisions, patterns, and lessons learned. Returns ranked results via the unified hybrid retrieval service and a trace_id for knowledge_receipt. This is the tool to use when the user has a QUESTION about what the knowledge base contains. For structured filter-based retrieval (by category, status, or score), use `knowledge_query` instead.",args:{query:exports_external.string().min(3).describe("Natural language search query"),top_n:exports_external.number().int().min(1).max(20).optional().describe("Maximum results to return (default: 5)"),tier:exports_external.enum(["all","swarm","hive"]).optional().describe("Knowledge tier to search (default: 'all')"),debug:exports_external.boolean().optional().describe("Include path/version/health debug metadata in the response")},execute:async(args2,directory,ctx)=>{let queryInput,topNInput,tierInput,debugInput;try{if(args2&&typeof args2==="object"){let obj=args2;queryInput=obj.query,topNInput=obj.top_n,tierInput=obj.tier,debugInput=obj.debug}}catch{}let wantDebug=debugInput===!0;if(typeof queryInput!=="string"||queryInput.length<3)return JSON.stringify({results:[],total:0,error:"query must be a string with at least 3 characters"});let topN=5;if(typeof topNInput==="number"&&Number.isInteger(topNInput))topN=Math.max(1,Math.min(20,topNInput));let tier="all";if(tierInput==="swarm"||tierInput==="hive")tier=tierInput;let knowledgeConfig=KnowledgeConfigSchema.parse({});try{let{config:config3}=loadPluginConfigWithMeta(directory);knowledgeConfig=KnowledgeConfigSchema.parse(config3.knowledge??{})}catch{}let{trace_id,results}=await searchKnowledge({directory,config:knowledgeConfig,query:queryInput,mode:"manual",agent:ctx?.agent??"unknown",sessionId:ctx?.sessionID??"unknown",tier,maxResults:topN,applyScopeFilter:!1,forceReadHive:!0,applyRoleScope:!1,emitEvent:!1}),sessionId=ctx?.sessionID??"unknown";if(results.length>0){let membership=await commitDisplayedMembership(directory,{trace_id,session_id:sessionId,exposure_kind:"manual_recall",agent:ctx?.agent??"unknown",grace_days:knowledgeConfig.receipt_close_grace_days,entries:results.map((entry,index)=>({entry_id:entry.id,critical:entry.directive_priority==="critical"&&isActiveStatus(entry.status),rank:index+1,score:entry.finalScore}))});if(!membership.ok||membership.memberships.some((item)=>item.terminal))return JSON.stringify({results:[],total:0,unverifiable:!0,code:membership.ok?"terminal_trace_reuse":membership.code,error:membership.ok?"retrieval trace was already terminalized":membership.detail})}else{let empty=await commitEmptyRetrieval(directory,{trace_id,session_id:sessionId,agent:ctx?.agent??"unknown",grace_days:knowledgeConfig.receipt_close_grace_days});if(!empty.ok)return JSON.stringify({results:[],total:0,unverifiable:!0,code:empty.code,error:empty.detail});if(!empty.terminal_event_id)return JSON.stringify({results:[],total:0,unverifiable:!0,code:"store_unavailable",error:"empty retrieval terminal did not commit"})}let ranks=Object.fromEntries(results.map((entry,index)=>[entry.id,index+1])),scores=Object.fromEntries(results.map((entry)=>[entry.id,entry.finalScore]));await recordKnowledgeEvent(directory,{type:"retrieved",trace_id,session_id:sessionId,agent:ctx?.agent??"unknown",query:queryInput,retrieval_mode:"manual",result_ids:results.map((entry)=>entry.id),ranks,scores});let scored=results.map((e)=>({id:e.id,confidence:e.confidence,category:e.category,lesson:e.lesson,score:e.finalScore,score_breakdown:e.score_breakdown}));log("[knowledge_recall] completed",{agent:ctx?.agent??"unknown",session_id:ctx?.sessionID??"unknown",query:queryInput,tier,result_count:scored.length,trace_id});let result={results:scored,total:scored.length,trace_id};if(wantDebug)result.debug=await computeKnowledgeDebug(directory);return JSON.stringify(result)}}),_internals170={knowledge_recall}});var exports_prompt_renderer={};__export(exports_prompt_renderer,{renderEnvironmentPrompt:()=>renderEnvironmentPrompt});function renderEnvironmentPrompt(profile,audience){let policy=deriveCommandPolicy(profile),header=["RUNTIME ENVIRONMENT",`- Host OS: ${profile.hostOS}`,`- Shell family: ${profile.shellFamily}`,`- Execution mode: ${profile.executionMode}`,`- Path style: ${profile.pathStyle}`].join(`
5841
5848
  `);if(audience==="coder")return[header,policy.avoidPosixExamples?"- Command policy: Prefer PowerShell-native commands and Node.js APIs. Do not start with POSIX commands (ls, grep, rm, cat, export, pwd) unless the environment profile indicates Docker, WSL, or a POSIX shell.":"- Command policy: Use POSIX-native commands and Node.js APIs.","","EXECUTION ENVIRONMENT AWARENESS","- This session includes a runtime environment profile. Follow it exactly.","- Decision ladder when shell commands are necessary:"," 1. Prefer swarm tools and Node.js fs/path APIs."," 2. Use shell only when the task truly requires it."," 3. When shell commands are needed, match the active shell family above."].join(`
5842
5849
  `);return[header,"- Test execution policy: Always execute tests via the swarm test runner tool.",policy.avoidPosixExamples?" Do not describe POSIX shell setup commands unless the profile indicates Docker, WSL, or POSIX shell.":" Use POSIX semantics for test commands.","","ENVIRONMENT-SPECIFIC TEST EXECUTION RULES",profile.isWindowsNative?"- Native Windows + PowerShell: Assume PowerShell semantics for paths and env vars. Prefer Pester for PowerShell modules where appropriate.":profile.isWindowsDocker?"- Windows + Docker: Host paths are Windows-style; in-container operations use POSIX semantics.":"- Linux/macOS: Use POSIX semantics for all shell-related reasoning.","- In all modes: prefer the swarm test runner over ad hoc shell commands.","- When tests are skipped due to environment issues, explicitly mention the environment profile assumptions in your verdict."].join(`
5843
5850
  `)}var init_prompt_renderer=()=>{};var exports_design_doc_drift={};__export(exports_design_doc_drift,{runDesignDocDriftCheck:()=>runDesignDocDriftCheck,_internals:()=>_internals214});import*as fs167 from"node:fs";import*as path280 from"node:path";function mtimeMsOrNull(absPath){try{return fs167.statSync(absPath).mtimeMs}catch{return null}}function resolveAnchorWithin(directory,anchor){if(!anchor||typeof anchor!=="string")return null;let root=path280.resolve(directory),resolved=path280.resolve(root,anchor),rel=path280.relative(root,resolved);if(rel.startsWith("..")||path280.isAbsolute(rel))return null;return resolved}async function runDesignDocDriftCheck(directory,phase,outDir){try{let root=path280.resolve(directory),outAbs=path280.resolve(root,outDir),outRel=path280.relative(root,outAbs);if(outRel.startsWith("..")||path280.isAbsolute(outRel))return null;let docMtimes=new Map,checkedDocs=[],missingDocs=[];for(let[docName,relFile]of Object.entries(DESIGN_DOC_FILES)){let abs=path280.join(outAbs,relFile),mtime=mtimeMsOrNull(abs);if(docMtimes.set(docName,mtime),mtime===null)missingDocs.push(path280.join(outDir,relFile));else checkedDocs.push(path280.join(outDir,relFile))}let traceabilityAbs=path280.join(outAbs,TRACEABILITY_REL),registry3=null;try{if((await fs167.promises.stat(traceabilityAbs)).size<=MAX_TRACEABILITY_BYTES){let raw=await fs167.promises.readFile(traceabilityAbs,"utf-8"),parsed=JSON.parse(raw);registry3=parsed&&typeof parsed==="object"&&!Array.isArray(parsed)?parsed:null}}catch{registry3=null}let noDocs=checkedDocs.length===0||registry3===null,effectiveSpec=readEffectiveSpecSync(root),specMtime=effectiveSpec?.mtime?Date.parse(effectiveSpec.mtime):null,staleSections=[];if(!noDocs&&Array.isArray(registry3?.sections))for(let section of registry3.sections){if(!section||typeof section.section_id!=="string")continue;if(typeof section.doc!=="string"||!docMtimes.has(section.doc))continue;let docMtime=docMtimes.get(section.doc)??null;if(docMtime===null){staleSections.push({section_id:section.section_id,doc:section.doc,reason:"owning design doc is missing"});continue}let flagged=!1;for(let anchor of section.code_anchors??[]){let anchorAbs=resolveAnchorWithin(directory,anchor);if(anchorAbs===null)continue;let anchorMtime=mtimeMsOrNull(anchorAbs);if(anchorMtime!==null&&anchorMtime>docMtime){staleSections.push({section_id:section.section_id,doc:section.doc,reason:`code anchor ${anchor} changed after the doc`}),flagged=!0;break}}if(!flagged&&specMtime!==null&&specMtime>docMtime&&(section.spec_frs?.length??0)>0)staleSections.push({section_id:section.section_id,doc:section.doc,reason:"effective spec changed after the doc"})}let verdict=noDocs?"NO_DOCS":staleSections.length>0?"DOC_STALE":"DOC_FRESH",report={schema_version:1,phase,timestamp:new Date().toISOString(),out_dir:outDir,verdict,stale_sections:staleSections,missing_docs:missingDocs,checked_docs:checkedDocs},filename=`${DOC_DRIFT_REPORT_PREFIX}${phase}.json`,filePath=validateSwarmPath(directory,filename);return await fs167.promises.mkdir(path280.dirname(filePath),{recursive:!0}),await fs167.promises.writeFile(filePath,JSON.stringify(report,null,2),"utf-8"),getGlobalEventBus().publish("curator.docdrift.completed",{phase,verdict,stale_count:staleSections.length,report_path:filePath}),report}catch(err){try{getGlobalEventBus().publish("curator.error",{operation:"docdrift",phase,error:String(err)})}catch{}return warn(`[design-doc-drift] check failed for phase ${phase}: ${String(err)}`),null}}var DOC_DRIFT_REPORT_PREFIX="doc-drift-phase-",MAX_TRACEABILITY_BYTES=1048576,DESIGN_DOC_FILES,TRACEABILITY_REL,_internals214;var init_design_doc_drift=__esm(()=>{init_event_bus();init_effective_spec();init_logger();init_utils2();DESIGN_DOC_FILES={domain:"domain.md","technical-spec":"technical-spec.md","behavior-spec":"behavior-spec.md","reference-impl":path280.join("reference","reference-impl.md"),"idiom-notes":path280.join("reference","idiom-notes.md")},TRACEABILITY_REL=path280.join("reference","traceability.json");_internals214={mtimeMsOrNull,resolveAnchorWithin,DESIGN_DOC_FILES}});var exports_project_context={};__export(exports_project_context,{buildProjectContext:()=>buildProjectContext,_internals:()=>_internals238,LANG_BACKEND_DETECTION_TIMEOUT_MS:()=>LANG_BACKEND_DETECTION_TIMEOUT_MS});import*as fs197 from"node:fs";import*as path317 from"node:path";function detectFileExists2(directory,pattern){if(pattern.includes("*")||pattern.includes("?"))try{let files=fs197.readdirSync(directory),regex=new RegExp(`^${pattern.replace(/\./g,"\\.").replace(/\*/g,".*").replace(/\?/g,".")}$`);return files.some((f)=>regex.test(f))}catch{return!1}try{return fs197.accessSync(path317.join(directory,pattern)),!0}catch{return!1}}function selectTestCommandFromScriptsTest(backend,directory){let pkgRaw;try{pkgRaw=fs197.readFileSync(path317.join(directory,"package.json"),"utf-8")}catch{return null}let pkg;try{pkg=JSON.parse(pkgRaw)}catch{return null}let script=pkg.scripts?.test;if(!script)return null;let fwName=null;if(script.includes("vitest"))fwName="vitest";else if(script.includes("jest"))fwName="jest";else if(script.includes("mocha"))fwName="mocha";else if(script.includes("bun test"))fwName="bun:test";if(!fwName)return null;let fw=backend.test.frameworks.find((f)=>f.name===fwName);return fw?fw.cmd:null}function selectTestCommandFast(backend,directory){let fromScripts=selectTestCommandFromScriptsTest(backend,directory);if(fromScripts!==null)return fromScripts;let sorted=[...backend.test.frameworks].sort((a,b)=>b.priority-a.priority);for(let fw of sorted){if(!detectFileExists2(directory,fw.detect))continue;return fw.cmd}return null}function selectBuildCommandFast(backend,directory){let sorted=[...backend.build.commands].sort((a,b)=>b.priority-a.priority);for(let cmd of sorted){if(cmd.detectFile&&!detectFileExists2(directory,cmd.detectFile))continue;return cmd.cmd}return null}function selectLintCommand(backend,directory){let sorted=[...backend.lint.linters].sort((a,b)=>b.priority-a.priority);for(let lint2 of sorted){if(!detectFileExists2(directory,lint2.detect))continue;return lint2.cmd}return null}async function buildProjectContext(directory){let backend=await _internals238.pickBackend(directory);if(!backend)return null;let ctx=emptyProjectContext();ctx.PROJECT_LANGUAGE=backend.displayName;let buildCmd=selectBuildCommandFast(backend,directory);if(buildCmd)ctx.BUILD_CMD=buildCmd;let testCmd=selectTestCommandFast(backend,directory);if(testCmd)ctx.TEST_CMD=testCmd;let lintCmd=selectLintCommand(backend,directory);if(lintCmd)ctx.LINT_CMD=lintCmd;if(backend.id==="php"){let overlay=getLaravelCommandOverlay(directory);if(overlay){if(ctx.TEST_CMD=overlay.testCommand,overlay.lintCommand)ctx.LINT_CMD=overlay.lintCommand}}let[frameworkSel,entryPoints]=await Promise.all([backend.selectFramework?backend.selectFramework(directory).catch(()=>null):Promise.resolve(null),backend.selectEntryPoints?backend.selectEntryPoints(directory).catch(()=>[]):Promise.resolve([])]);if(frameworkSel)ctx.PROJECT_FRAMEWORK=frameworkSel.name;if(entryPoints.length>0)ctx.ENTRY_POINTS=entryPoints.join(", ");if(backend.prompts.coderConstraints.length>0)ctx.CODER_CONSTRAINTS=bulletList(backend.prompts.coderConstraints);if(backend.prompts.testConstraints&&backend.prompts.testConstraints.length>0)ctx.TEST_CONSTRAINTS=bulletList(backend.prompts.testConstraints);if(backend.prompts.reviewerChecklist.length>0)ctx.REVIEWER_CHECKLIST=bulletList(backend.prompts.reviewerChecklist);let profiles=_internals238.pickedProfiles(directory);if(profiles.length>1)ctx.PROJECT_CONTEXT_SECONDARY_LANGUAGES=profiles.slice(1).map((p)=>p.id).join(", ");return ctx}var LANG_BACKEND_DETECTION_TIMEOUT_MS=300,_internals238;var init_project_context=__esm(()=>{init_dispatch();init_framework_detector();_internals238={pickBackend,pickedProfiles}});init_package();init_agents2();init_critic();import*as path318 from"node:path";import{performance as performance2}from"node:perf_hooks";import{fileURLToPath as fileURLToPath7}from"node:url";init_event_bus();init_evidence_summary_integration();init_manager3();init_manager();init_utils();import*as fs104 from"node:fs";import*as path196 from"node:path";class PlanSyncWorker{directory;debounceMs;pollIntervalMs;syncTimeoutMs;onSyncComplete;status="stopped";watcher=null;pollTimer=null;debounceTimer=null;syncing=!1;pendingSync=!1;lastStat=null;disposed=!1;constructor(options={}){this.directory=options.directory??"",this.debounceMs=options.debounceMs??500,this.pollIntervalMs=options.pollIntervalMs??2000,this.syncTimeoutMs=options.syncTimeoutMs??30000,this.onSyncComplete=options.onSyncComplete}getSwarmDir(){return path196.resolve(this.directory,".swarm")}getPlanJsonPath(){return path196.join(this.getSwarmDir(),"plan.json")}start(){if(this.disposed){log("[PlanSyncWorker] Cannot start - worker has been disposed");return}if(!this.directory){log("[PlanSyncWorker] Cannot start - no directory provided");return}if(this.status==="running"||this.status==="starting"){log("[PlanSyncWorker] Already running or starting");return}this.status="starting",log("[PlanSyncWorker] Starting..."),this.initializeStat(),this.setupPolling(),this.setupNativeWatcher(),this.status="running",log("[PlanSyncWorker] Started watching for plan.json changes")}stop(){if(this.status==="stopped"||this.status==="stopping")return;if(this.status="stopping",log("[PlanSyncWorker] Stopping..."),this.clearDebounce(),this.watcher)this.watcher.close(),this.watcher=null;if(this.pollTimer)clearInterval(this.pollTimer),this.pollTimer=null;this.status="stopped",log("[PlanSyncWorker] Stopped")}dispose(){this.stop(),this.disposed=!0,this.lastStat=null,log("[PlanSyncWorker] Disposed")}getStatus(){return this.status}isRunning(){return this.status==="running"}initializeStat(){try{let stats2=fs104.statSync(this.getPlanJsonPath());this.lastStat={mtimeMs:stats2.mtimeMs,size:stats2.size}}catch{this.lastStat=null}}setupNativeWatcher(){let swarmDir=this.getSwarmDir();try{if(!fs104.existsSync(swarmDir))return log("[PlanSyncWorker] Swarm directory does not exist yet"),!1;return this.watcher=fs104.watch(swarmDir,{persistent:!1},(_eventType,filename)=>{if(this.disposed||this.status!=="running")return;if(filename&&(filename.includes(".tmp.")||filename.endsWith(".rebuild")))return;if(filename==="plan.json"||filename===void 0)this.debouncedSync()}),this.watcher.on("error",(error93)=>{if(this.disposed||this.status!=="running")return;if(log("[PlanSyncWorker] Watcher error, falling back to polling",{error:error93.message}),this.watcher)this.watcher.close(),this.watcher=null;this.setupPolling()}),log("[PlanSyncWorker] Native fs.watch established"),!0}catch(error93){return log("[PlanSyncWorker] Failed to setup native watcher",{error:error93 instanceof Error?error93.message:String(error93)}),!1}}setupPolling(){if(this.pollTimer)clearInterval(this.pollTimer);if(this.pollTimer=setInterval(()=>{if(this.disposed||this.status!=="running")return;this.pollCheck()},this.pollIntervalMs),typeof this.pollTimer.unref==="function")this.pollTimer.unref();log("[PlanSyncWorker] Polling fallback established",{intervalMs:this.pollIntervalMs})}pollCheck(){try{let planPath=this.getPlanJsonPath();if(!fs104.existsSync(planPath)){if(this.lastStat!==null)this.lastStat=null,log("[PlanSyncWorker] plan.json deleted");return}let stats2=fs104.statSync(planPath),currentStat={mtimeMs:stats2.mtimeMs,size:stats2.size};if(this.lastStat===null||currentStat.mtimeMs!==this.lastStat.mtimeMs||currentStat.size!==this.lastStat.size)this.lastStat=currentStat,this.debouncedSync()}catch(error93){log("[PlanSyncWorker] Poll check error",{error:error93 instanceof Error?error93.message:String(error93)})}}debouncedSync(){if(this.disposed||this.status!=="running")return;if(this.debounceTimer)clearTimeout(this.debounceTimer);this.debounceTimer=setTimeout(()=>{if(this.disposed||this.status!=="running")return;this.debounceTimer=null,this.triggerSync()},this.debounceMs)}clearDebounce(){if(this.debounceTimer)clearTimeout(this.debounceTimer),this.debounceTimer=null}triggerSync(){if(this.syncing){this.pendingSync=!0,log("[PlanSyncWorker] Sync pending (in-flight)");return}this.executeSync()}async executeSync(){this.syncing=!0;try{log("[PlanSyncWorker] Syncing plan..."),this.checkForUnauthorizedWrite();let plan=await this.withTimeout(_internals24.loadPlanJsonOnly(this.directory),this.syncTimeoutMs,"Sync operation timed out");if(plan&&plan.phases.length>0)await _internals24.regeneratePlanMarkdown(this.directory,plan),log("[PlanSyncWorker] Sync complete",{title:plan.title,phase:plan.current_phase}),this.safeCallback(!0);else if(plan)log("[PlanSyncWorker] Plan has no phases, skipping markdown regeneration"),this.safeCallback(!0);else log("[PlanSyncWorker] No plan found to sync"),this.safeCallback(!0)}catch(error93){if(error93 instanceof Error&&error93.message.includes("timed out"))log("[PlanSyncWorker] Sync timed out after "+this.syncTimeoutMs+"ms, worker remains active");else log("[PlanSyncWorker] Sync failed",{error:error93 instanceof Error?error93.message:String(error93)});this.safeCallback(!1,error93 instanceof Error?error93:Error(String(error93)))}finally{if(this.syncing=!1,this.pendingSync&&!this.disposed&&this.status==="running")this.pendingSync=!1,log("[PlanSyncWorker] Executing pending sync"),this.executeSync()}}safeCallback(success3,error93){if(this.onSyncComplete)try{this.onSyncComplete(success3,error93)}catch(callbackError){log("[PlanSyncWorker] onSyncComplete callback threw error (ignored)",{callbackError:callbackError instanceof Error?callbackError.message:String(callbackError)})}}checkForUnauthorizedWrite(){try{let swarmDir=this.getSwarmDir(),planJsonPath=path196.join(swarmDir,"plan.json"),markerPath=path196.join(swarmDir,".plan-write-marker"),planStats=fs104.statSync(planJsonPath),planMtimeMs=Math.floor(planStats.mtimeMs),markerContent=fs104.readFileSync(markerPath,"utf8"),marker=JSON.parse(markerContent);if(marker.in_progress===!0){log("[PlanSyncWorker] Skipping unauthorized-write check - plan write in progress");return}let markerTimestampMs=new Date(marker.timestamp).getTime();if(planMtimeMs>markerTimestampMs+5000)log("[PlanSyncWorker] WARNING: plan.json may have been written outside save_plan/savePlan - unauthorized direct write suspected",{planMtimeMs,markerTimestampMs})}catch{}}withTimeout(promise3,ms,timeoutMessage2){return new Promise((resolve77,reject)=>{let timer=setTimeout(()=>{reject(Error(`${timeoutMessage2} (${ms}ms)`))},ms);promise3.then((result)=>{clearTimeout(timer),resolve77(result)}).catch((error93)=>{clearTimeout(timer),reject(error93)})})}}init_pr_event_subscribers();import*as child_process10 from"node:child_process";init_zod();init_bun_compat();init_logger();function sanitizeLabel(label){return label.replace(/[<>]/g," ").replace(/[\p{Cc}]/gu," ").replace(/\s+/g," ").trim().slice(0,120)}function neutralizeUntrustedMarkdown(content,sourceLabel="GitHub content"){let normalized=content.replaceAll(String.fromCharCode(0),"").replace(/\r\n/g,`
@@ -5980,7 +5987,7 @@ ${phaseNumber!==null&&phaseNumber>=4?`
5980
5987
 
5981
5988
  ---
5982
5989
 
5983
- ${originalText}`})}}init_constants();import*as path222 from"node:path";init_profiles();import*as fsSync12 from"node:fs";import{existsSync as existsSync109,realpathSync as realpathSync35}from"node:fs";import*as fsPromises6 from"node:fs/promises";import*as os25 from"node:os";import*as path216 from"node:path";var PUBLIC_INFO={exported:!0,visibility:"public",exportedReason:"top_level_public",apiSurfaceKind:"public"},PRIVATE_INFO={exported:!1,visibility:"private",exportedReason:"unknown",apiSurfaceKind:"private"};function collectCommonJsExports(source){let sanitized=maskCommentsAndStrings(source),exportsByLocal=new Map,add2=(localName,exportedName,sourceIndex)=>{if(!isIdentifier(localName)||!isIdentifier(exportedName))return;let existing=exportsByLocal.get(localName);if(existing&&existing.sourceIndex<=sourceIndex)return;exportsByLocal.set(localName,{localName,exportedName,exportedReason:"explicit_export",sourceIndex})};for(let match of sanitized.matchAll(/\bmodule\s*\.\s*exports\s*=\s*([A-Za-z_$][\w$]*)\b/g))add2(match[1],match[1],match.index??0);for(let match of sanitized.matchAll(/\bmodule\s*\.\s*exports\s*=\s*\{([^}]*)\}/g)){let body=match[1],baseIndex=match.index??0;for(let part of body.split(",")){let entry=part.trim();if(!entry)continue;let alias=entry.match(/^([A-Za-z_$][\w$]*)\s*:\s*([A-Za-z_$][\w$]*)$/);if(alias){add2(alias[2],alias[1],baseIndex+match[0].indexOf(part));continue}let shorthand=entry.match(/^([A-Za-z_$][\w$]*)$/);if(shorthand)add2(shorthand[1],shorthand[1],baseIndex+match[0].indexOf(part))}}for(let match of sanitized.matchAll(/\b(?:module\s*\.\s*exports|exports)\s*\.\s*([A-Za-z_$][\w$]*)\s*=\s*([A-Za-z_$][\w$]*)\b/g))add2(match[2],match[1],match.index??0);return exportsByLocal}function collectPythonAllNames(source){let match=source.match(/__all__\s*=\s*([[({])([\s\S]*?)[\])}]/);if(!match)return null;let body=match[2].trim();if(!body)return new Set;let names=new Set;for(let part of body.split(",")){let trimmed=part.trim();if(!trimmed)continue;let stringMatch=trimmed.match(/^['"]([^'"]+)['"]$/);if(!stringMatch)return null;names.add(stringMatch[1])}return names}function getSymbolVisibilityInfo(ctx){if(hasPrivateContainer(ctx.defNode))return{...PRIVATE_INFO};if(ctx.explicitExported||ctx.commonJsExport)return{exported:!0,visibility:"public",exportedReason:"explicit_export",apiSurfaceKind:"export"};let ownVisibility=visibilityFromText(ctx.grammarId,ctx.defNode.text);if(ctx.kind==="method"){if(ctx.grammarId==="go")return isUppercasePublic(ctx.localName)?{...PUBLIC_INFO,exportedReason:"naming_convention"}:{...PRIVATE_INFO};if(ctx.grammarId==="python"&&ctx.pythonParentClassExported){let isPrivate=ctx.localName.startsWith("_"),isInit=ctx.localName==="__init__";if(isPrivate||isInit)return{...PRIVATE_INFO};return{exported:!0,visibility:"public",exportedReason:"modifier",apiSurfaceKind:"public"}}return{exported:!1,visibility:ownVisibility,exportedReason:ownVisibility==="unknown"?"unknown":"modifier",apiSurfaceKind:ownVisibility==="private"?"private":"public"}}if(!ctx.isTopLevel&&isMemberLikeNode(ctx.defNode))return{exported:!1,visibility:ownVisibility==="unknown"?"public":ownVisibility,exportedReason:ownVisibility==="unknown"?"module_public":"modifier",apiSurfaceKind:ownVisibility==="private"?"private":"public"};if(!ctx.isTopLevel)return{...PRIVATE_INFO};switch(ctx.grammarId){case"typescript":case"javascript":case"tsx":return{...PRIVATE_INFO};case"python":return pythonVisibility(ctx);case"rust":return rustVisibility(ctx);case"go":return isUppercasePublic(ctx.localName)?{...PUBLIC_INFO,exportedReason:"naming_convention"}:{...PRIVATE_INFO};case"java":case"kotlin":case"csharp":case"swift":case"php":return modifierLanguageVisibility(ctx);case"cpp":return cppVisibility(ctx);case"dart":return ctx.localName.startsWith("_")?{...PRIVATE_INFO}:{...PUBLIC_INFO,exportedReason:"naming_convention"};case"ruby":return ctx.localName.startsWith("_")?{...PRIVATE_INFO}:{...PUBLIC_INFO,exportedReason:"module_public"};default:return{exported:!1,visibility:"unknown",exportedReason:"unknown",apiSurfaceKind:"unknown"}}}function pythonVisibility(ctx){if(ctx.pythonAllNames)return ctx.pythonAllNames.has(ctx.localName)?{exported:!0,visibility:"public",exportedReason:"module_public",apiSurfaceKind:"public"}:{...PRIVATE_INFO};return ctx.localName.startsWith("_")?{...PRIVATE_INFO}:{...PUBLIC_INFO,exportedReason:"naming_convention"}}function rustVisibility(ctx){let text=ctx.defNode.text.trimStart();if(!/^pub\b|^pub\s*\(/.test(text))return{...PRIVATE_INFO};return{exported:!0,visibility:/^pub\s*\(\s*(crate|super|in\b)/.test(text)?"internal":"public",exportedReason:"modifier",apiSurfaceKind:"public"}}function modifierLanguageVisibility(ctx){if(ctx.grammarId==="php"&&ctx.localName.startsWith("_"))return{...PRIVATE_INFO};let visibility=visibilityFromText(ctx.grammarId,ctx.defNode.text);if(visibility==="private")return{...PRIVATE_INFO};if(visibility==="unknown")return{exported:!0,visibility:ctx.grammarId==="java"?"package":defaultModuleVisibility(ctx.grammarId),exportedReason:"module_public",apiSurfaceKind:"public"};return{exported:!0,visibility,exportedReason:"modifier",apiSurfaceKind:"public"}}function cppVisibility(ctx){let text=ctx.defNode.text.trimStart();if(/^static\b/.test(text)||ctx.localName.startsWith("_"))return{...PRIVATE_INFO};return{exported:!0,visibility:"public",exportedReason:"namespace_public",apiSurfaceKind:"public"}}function visibilityFromText(grammarId,text){let normalized=declarationPrefix(text).trimStart();if(/\b(private|fileprivate)\b/.test(normalized))return"private";if(/\bprotected\b/.test(normalized))return"protected";if(/\binternal\b/.test(normalized))return"internal";if(/\b(public|open)\b/.test(normalized))return"public";if(grammarId==="rust"&&/^pub\s*\(\s*(crate|super|in\b)/.test(normalized))return"internal";if(grammarId==="rust"&&/^pub\b|^pub\s*\(/.test(normalized))return"public";return"unknown"}function declarationPrefix(text){let bodyStart=text.search(/[{\n]/);return bodyStart===-1?text:text.slice(0,bodyStart)}function defaultModuleVisibility(grammarId){switch(grammarId){case"kotlin":case"swift":case"csharp":return"internal";case"php":return"public";default:return"public"}}function hasPrivateContainer(node){let current=node.parent;while(current){if(isContainerNode(current)&&visibilityFromText("",current.text)==="private")return!0;current=current.parent}return!1}function isContainerNode(node){return/(?:class|struct|interface|object|protocol|namespace|module)/.test(node.type)}function isMemberLikeNode(node){return/(?:method|function)_declaration|function_definition/.test(node.type)}function isUppercasePublic(name){return/^[A-Z]/.test(name)}function isIdentifier(value){return/^[A-Za-z_$][\w$]*$/.test(value)}function maskCommentsAndStrings(source){let chars=[...source],i=0;while(i<chars.length){let ch=chars[i],next=chars[i+1];if(ch==="/"&&next==="/"){chars[i++]=" ",chars[i++]=" ";while(i<chars.length&&chars[i]!==`
5990
+ ${originalText}`})}}init_constants();import*as path222 from"node:path";init_profiles();import*as fsSync12 from"node:fs";import{existsSync as existsSync110,realpathSync as realpathSync35}from"node:fs";import*as fsPromises6 from"node:fs/promises";import*as os25 from"node:os";import*as path216 from"node:path";var PUBLIC_INFO={exported:!0,visibility:"public",exportedReason:"top_level_public",apiSurfaceKind:"public"},PRIVATE_INFO={exported:!1,visibility:"private",exportedReason:"unknown",apiSurfaceKind:"private"};function collectCommonJsExports(source){let sanitized=maskCommentsAndStrings(source),exportsByLocal=new Map,add2=(localName,exportedName,sourceIndex)=>{if(!isIdentifier(localName)||!isIdentifier(exportedName))return;let existing=exportsByLocal.get(localName);if(existing&&existing.sourceIndex<=sourceIndex)return;exportsByLocal.set(localName,{localName,exportedName,exportedReason:"explicit_export",sourceIndex})};for(let match of sanitized.matchAll(/\bmodule\s*\.\s*exports\s*=\s*([A-Za-z_$][\w$]*)\b/g))add2(match[1],match[1],match.index??0);for(let match of sanitized.matchAll(/\bmodule\s*\.\s*exports\s*=\s*\{([^}]*)\}/g)){let body=match[1],baseIndex=match.index??0;for(let part of body.split(",")){let entry=part.trim();if(!entry)continue;let alias=entry.match(/^([A-Za-z_$][\w$]*)\s*:\s*([A-Za-z_$][\w$]*)$/);if(alias){add2(alias[2],alias[1],baseIndex+match[0].indexOf(part));continue}let shorthand=entry.match(/^([A-Za-z_$][\w$]*)$/);if(shorthand)add2(shorthand[1],shorthand[1],baseIndex+match[0].indexOf(part))}}for(let match of sanitized.matchAll(/\b(?:module\s*\.\s*exports|exports)\s*\.\s*([A-Za-z_$][\w$]*)\s*=\s*([A-Za-z_$][\w$]*)\b/g))add2(match[2],match[1],match.index??0);return exportsByLocal}function collectPythonAllNames(source){let match=source.match(/__all__\s*=\s*([[({])([\s\S]*?)[\])}]/);if(!match)return null;let body=match[2].trim();if(!body)return new Set;let names=new Set;for(let part of body.split(",")){let trimmed=part.trim();if(!trimmed)continue;let stringMatch=trimmed.match(/^['"]([^'"]+)['"]$/);if(!stringMatch)return null;names.add(stringMatch[1])}return names}function getSymbolVisibilityInfo(ctx){if(hasPrivateContainer(ctx.defNode))return{...PRIVATE_INFO};if(ctx.explicitExported||ctx.commonJsExport)return{exported:!0,visibility:"public",exportedReason:"explicit_export",apiSurfaceKind:"export"};let ownVisibility=visibilityFromText(ctx.grammarId,ctx.defNode.text);if(ctx.kind==="method"){if(ctx.grammarId==="go")return isUppercasePublic(ctx.localName)?{...PUBLIC_INFO,exportedReason:"naming_convention"}:{...PRIVATE_INFO};if(ctx.grammarId==="python"&&ctx.pythonParentClassExported){let isPrivate=ctx.localName.startsWith("_"),isInit=ctx.localName==="__init__";if(isPrivate||isInit)return{...PRIVATE_INFO};return{exported:!0,visibility:"public",exportedReason:"modifier",apiSurfaceKind:"public"}}return{exported:!1,visibility:ownVisibility,exportedReason:ownVisibility==="unknown"?"unknown":"modifier",apiSurfaceKind:ownVisibility==="private"?"private":"public"}}if(!ctx.isTopLevel&&isMemberLikeNode(ctx.defNode))return{exported:!1,visibility:ownVisibility==="unknown"?"public":ownVisibility,exportedReason:ownVisibility==="unknown"?"module_public":"modifier",apiSurfaceKind:ownVisibility==="private"?"private":"public"};if(!ctx.isTopLevel)return{...PRIVATE_INFO};switch(ctx.grammarId){case"typescript":case"javascript":case"tsx":return{...PRIVATE_INFO};case"python":return pythonVisibility(ctx);case"rust":return rustVisibility(ctx);case"go":return isUppercasePublic(ctx.localName)?{...PUBLIC_INFO,exportedReason:"naming_convention"}:{...PRIVATE_INFO};case"java":case"kotlin":case"csharp":case"swift":case"php":return modifierLanguageVisibility(ctx);case"cpp":return cppVisibility(ctx);case"dart":return ctx.localName.startsWith("_")?{...PRIVATE_INFO}:{...PUBLIC_INFO,exportedReason:"naming_convention"};case"ruby":return ctx.localName.startsWith("_")?{...PRIVATE_INFO}:{...PUBLIC_INFO,exportedReason:"module_public"};default:return{exported:!1,visibility:"unknown",exportedReason:"unknown",apiSurfaceKind:"unknown"}}}function pythonVisibility(ctx){if(ctx.pythonAllNames)return ctx.pythonAllNames.has(ctx.localName)?{exported:!0,visibility:"public",exportedReason:"module_public",apiSurfaceKind:"public"}:{...PRIVATE_INFO};return ctx.localName.startsWith("_")?{...PRIVATE_INFO}:{...PUBLIC_INFO,exportedReason:"naming_convention"}}function rustVisibility(ctx){let text=ctx.defNode.text.trimStart();if(!/^pub\b|^pub\s*\(/.test(text))return{...PRIVATE_INFO};return{exported:!0,visibility:/^pub\s*\(\s*(crate|super|in\b)/.test(text)?"internal":"public",exportedReason:"modifier",apiSurfaceKind:"public"}}function modifierLanguageVisibility(ctx){if(ctx.grammarId==="php"&&ctx.localName.startsWith("_"))return{...PRIVATE_INFO};let visibility=visibilityFromText(ctx.grammarId,ctx.defNode.text);if(visibility==="private")return{...PRIVATE_INFO};if(visibility==="unknown")return{exported:!0,visibility:ctx.grammarId==="java"?"package":defaultModuleVisibility(ctx.grammarId),exportedReason:"module_public",apiSurfaceKind:"public"};return{exported:!0,visibility,exportedReason:"modifier",apiSurfaceKind:"public"}}function cppVisibility(ctx){let text=ctx.defNode.text.trimStart();if(/^static\b/.test(text)||ctx.localName.startsWith("_"))return{...PRIVATE_INFO};return{exported:!0,visibility:"public",exportedReason:"namespace_public",apiSurfaceKind:"public"}}function visibilityFromText(grammarId,text){let normalized=declarationPrefix(text).trimStart();if(/\b(private|fileprivate)\b/.test(normalized))return"private";if(/\bprotected\b/.test(normalized))return"protected";if(/\binternal\b/.test(normalized))return"internal";if(/\b(public|open)\b/.test(normalized))return"public";if(grammarId==="rust"&&/^pub\s*\(\s*(crate|super|in\b)/.test(normalized))return"internal";if(grammarId==="rust"&&/^pub\b|^pub\s*\(/.test(normalized))return"public";return"unknown"}function declarationPrefix(text){let bodyStart=text.search(/[{\n]/);return bodyStart===-1?text:text.slice(0,bodyStart)}function defaultModuleVisibility(grammarId){switch(grammarId){case"kotlin":case"swift":case"csharp":return"internal";case"php":return"public";default:return"public"}}function hasPrivateContainer(node){let current=node.parent;while(current){if(isContainerNode(current)&&visibilityFromText("",current.text)==="private")return!0;current=current.parent}return!1}function isContainerNode(node){return/(?:class|struct|interface|object|protocol|namespace|module)/.test(node.type)}function isMemberLikeNode(node){return/(?:method|function)_declaration|function_definition/.test(node.type)}function isUppercasePublic(name){return/^[A-Z]/.test(name)}function isIdentifier(value){return/^[A-Za-z_$][\w$]*$/.test(value)}function maskCommentsAndStrings(source){let chars=[...source],i=0;while(i<chars.length){let ch=chars[i],next=chars[i+1];if(ch==="/"&&next==="/"){chars[i++]=" ",chars[i++]=" ";while(i<chars.length&&chars[i]!==`
5984
5991
  `)chars[i++]=" ";continue}if(ch==="/"&&next==="*"){chars[i++]=" ",chars[i++]=" ";while(i<chars.length){let end=chars[i]==="*"&&chars[i+1]==="/";if(chars[i++]=" ",end){chars[i++]=" ";break}}continue}if(ch==='"'||ch==="'"||ch==="`"){let quote=ch;chars[i++]=" ";while(i<chars.length){if(chars[i]==="\\"){if(chars[i++]=" ",i<chars.length)chars[i++]=" ";continue}let done=chars[i]===quote;if(chars[i++]=" ",done)break}continue}i++}return chars.join("")}var _QueryCtor=null,AST_TIMEOUT_MS2=500,QUERIES2={typescript:{defs:`
5985
5992
  (function_declaration name: (identifier) @func.name) @func.def
5986
5993
  (generator_function_declaration name: (identifier) @func.name) @func.def
@@ -6183,14 +6190,14 @@ ${originalText}`})}}init_constants();import*as path222 from"node:path";init_prof
6183
6190
  `),implDepth=0,braceDelta=(text)=>(text.match(/{/g)?.length??0)-(text.match(/}/g)?.length??0);for(let i=0;i<lines.length;i++){let line=lines[i],trimmed=line.trim(),inImpl=implDepth>0;if(!inImpl&&/^impl\b/.test(trimmed)){implDepth=Math.max(0,implDepth+braceDelta(trimmed));continue}if(inImpl){let method=trimmed.match(/^(pub(?:\s*\([^)]*\))?\s+)?(?:async\s+)?fn\s+([A-Za-z_][A-Za-z0-9_]*)/);if(method){let modifier2=method[1]??"";symbols.push({name:method[2],kind:"method",exported:modifier2.trim().startsWith("pub"),signature:trimmed.substring(0,100),line:i+1})}implDepth=Math.max(0,implDepth+braceDelta(trimmed));continue}if(/^\s/.test(line))continue;let item=trimmed.match(/^(pub(?:\s*\([^)]*\))?\s+)?(?:async\s+)?(fn|struct|enum|trait|mod)\s+([A-Za-z_][A-Za-z0-9_]*)/);if(!item)continue;let exported=(item[1]??"").trim().startsWith("pub"),kindMap={fn:"function",struct:"type",enum:"enum",trait:"interface",mod:"type"};symbols.push({name:item[3],kind:kindMap[item[2]]??"type",exported,signature:trimmed.substring(0,100),line:i+1})}return symbols.sort((a,b)=>{if(a.line!==b.line)return a.line-b.line;return a.name.localeCompare(b.name)})}function extractGoSymbols(filePath,cwd){let content=readValidatedSourceFile(filePath,cwd);if(content===null)return[];let symbols=[],lines=content.split(`
6184
6191
  `);for(let i=0;i<lines.length;i++){let line=lines[i],method=line.match(/^func\s+\([^)]*\)\s+([A-Za-z_][A-Za-z0-9_]*)\s*\(/);if(method){symbols.push({name:method[1],kind:"method",exported:/^[A-Z]/.test(method[1]),signature:line.trim().substring(0,100),line:i+1});continue}let fn2=line.match(/^func\s+([A-Za-z_][A-Za-z0-9_]*)\s*\(/);if(fn2){symbols.push({name:fn2[1],kind:"function",exported:/^[A-Z]/.test(fn2[1]),signature:line.trim().substring(0,100),line:i+1});continue}let typeDecl=line.match(/^type\s+([A-Za-z_][A-Za-z0-9_]*)\b/);if(typeDecl){symbols.push({name:typeDecl[1],kind:"type",exported:/^[A-Z]/.test(typeDecl[1]),signature:line.trim().substring(0,100),line:i+1});continue}let valueDecl=line.match(/^(var|const)\s+([A-Za-z_][A-Za-z0-9_]*)\b/);if(valueDecl)symbols.push({name:valueDecl[2],kind:valueDecl[1]==="const"?"const":"variable",exported:/^[A-Z]/.test(valueDecl[2]),signature:line.trim().substring(0,100),line:i+1})}return symbols.sort((a,b)=>{if(a.line!==b.line)return a.line-b.line;return a.name.localeCompare(b.name)})}function findSourceFiles(cwd,maxFiles){let files=[];return walkDir(cwd,cwd,files,maxFiles),files}function walkDir(currentDir,rootDir,files,maxFiles){let entries;try{entries=fs119.readdirSync(currentDir,{withFileTypes:!0})}catch{return}entries.sort((a,b)=>a.name.toLowerCase().localeCompare(b.name.toLowerCase()));for(let entry of entries){if(files.length>=maxFiles)return;if(SKIP_DIRECTORIES.has(entry.name))continue;let fullPath=path213.join(currentDir,entry.name);if(entry.isDirectory())walkDir(fullPath,rootDir,files,maxFiles);else if(entry.isFile()&&SYMBOL_EXTENSIONS.has(path213.extname(entry.name).toLowerCase()))files.push(path213.relative(rootDir,fullPath))}}function searchWorkspaceSymbols(cwd,name,exportedOnly=!0){let startTime=Date.now(),sourceFiles=findSourceFiles(cwd,MAX_WORKSPACE_SCANNED_FILES),files=[],scannedCount=0,truncated=!1;if(sourceFiles.length>=MAX_WORKSPACE_SCANNED_FILES)truncated=!0;let totalSymbols=0;for(let relFile of sourceFiles){if(Date.now()-startTime>WORKSPACE_TIMEOUT_MS){truncated=!0;break}scannedCount++;let syms;switch(path213.extname(relFile).toLowerCase()){case".ts":case".tsx":case".js":case".jsx":case".mjs":case".cjs":syms=extractTSSymbols(relFile,cwd);break;case".py":case".pyw":syms=extractPythonSymbols(relFile,cwd);break;case".rs":syms=extractRustSymbols(relFile,cwd);break;case".go":syms=extractGoSymbols(relFile,cwd);break;default:continue}if(exportedOnly)syms=syms.filter((s)=>s.exported);if(name)syms=syms.filter((s)=>s.name.includes(name));if(syms.length>0){let remaining=MAX_WORKSPACE_RESULTS-totalSymbols;if(remaining<=0){truncated=!0;break}let cappedSyms=syms.slice(0,remaining);if(files.push({file:relFile,symbolCount:cappedSyms.length,symbols:cappedSyms}),totalSymbols+=cappedSyms.length,totalSymbols>=MAX_WORKSPACE_RESULTS){truncated=syms.length>remaining||scannedCount<sourceFiles.length;break}}}return{query:{workspace:!0,name},fileCount:files.length,scannedFileCount:scannedCount,totalSymbols,files,truncated}}var symbols=createSwarmTool({description:"Extract all exported symbols from a source file: functions with signatures, classes with public members, interfaces, types, enums, constants. Supports TypeScript/JavaScript, Python, Rust, and Go. Use for architect planning, designer scaffolding, and understanding module public API surface.",args:{file:exports_external.string().optional().describe('File path to extract symbols from (e.g., "src/auth/login.ts"). Required when not using workspace mode.'),exported_only:exports_external.boolean().default(!0).describe("If true, only return exported/public symbols. If false, include all top-level symbols."),workspace:exports_external.boolean().optional().describe("When true, search across the workspace instead of a single file. Returns per-file symbol summaries."),name:exports_external.string().optional().describe("Search for symbols by name (case-sensitive substring match). When provided without workspace, only searches the specified file.")},execute:async(args2,directory)=>{let file3,exportedOnly=!0,workspace=!1,name;try{let obj=args2;file3=obj.file!=null&&typeof obj.file==="string"?obj.file:void 0,exportedOnly=obj.exported_only!==!1,workspace=obj.workspace===!0,name=obj.name!=null&&typeof obj.name==="string"?obj.name:void 0}catch{return JSON.stringify({file:"<unknown>",error:"Invalid arguments: could not extract parameters",symbols:[]},null,2)}let cwd=directory;if(workspace)return JSON.stringify(searchWorkspaceSymbols(cwd,name,exportedOnly),null,2);if(!file3)return JSON.stringify({error:"file parameter is required when not using workspace mode",symbols:[]},null,2);if(containsControlChars(file3))return JSON.stringify({file:file3,error:"Path contains invalid control characters",symbols:[]},null,2);if(containsPathTraversal(file3))return JSON.stringify({file:file3,error:"Path contains path traversal sequence",symbols:[]},null,2);if(containsWindowsAttacks(file3))return JSON.stringify({file:file3,error:"Path contains invalid Windows-specific sequence",symbols:[]},null,2);if(!isPathInWorkspace(file3,cwd))return JSON.stringify({file:file3,error:"Path is outside workspace",symbols:[]},null,2);let ext=path213.extname(file3),syms;switch(ext){case".ts":case".tsx":case".js":case".jsx":case".mjs":case".cjs":syms=extractTSSymbols(file3,cwd);break;case".py":case".pyw":syms=extractPythonSymbols(file3,cwd);break;case".rs":syms=extractRustSymbols(file3,cwd);break;case".go":syms=extractGoSymbols(file3,cwd);break;default:return JSON.stringify({file:file3,error:`Unsupported file extension: ${ext}. Supported: .ts, .tsx, .js, .jsx, .mjs, .cjs, .py, .pyw, .rs, .go`,symbols:[]},null,2)}if(exportedOnly)syms=syms.filter((s)=>s.exported);if(name)syms=syms.filter((s)=>s.name.includes(name));return JSON.stringify({file:file3,symbolCount:syms.length,symbols:syms},null,2)}});import*as path215 from"node:path";import*as path214 from"node:path";var REPO_GRAPH_FILENAME="repo-graph.json",GRAPH_SCHEMA_VERSION="1.4.0";function isSchemaVersionAtLeast(version5,minimum){let parse10=(v)=>v.split(".").map((part)=>{let n=Number.parseInt(part,10);return Number.isFinite(n)?n:0}),a=parse10(version5??""),b=parse10(minimum),len=Math.max(a.length,b.length);for(let i=0;i<len;i++){let av=a[i]??0,bv=b[i]??0;if(av>bv)return!0;if(av<bv)return!1}return!0}var FILE_ROLE_VALUES=["api_route","middleware","service_module","data_module","swarm_tool","agent","hook","config","schema","test_file","cli_command","documentation","source_module"],ROUTE_METHOD_VALUES=["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD","ALL"],ROUTE_SOURCE_VALUES=["file_path","handler_export","router_call"],DATA_OPERATION_VALUES=["read","write","delete","transaction","migration"],DATA_ACCESS_VALUES=["database","orm","sql","filesystem","network","unknown"],SECURITY_KIND_VALUES=["authentication","authorization","input_validation","csrf","sanitization","secret_handling"],SECURITY_CONFIDENCE_VALUES=["low","medium","high"],ONTOLOGY_FINDING_SEVERITY_VALUES=["info","low","medium","high"],IMPORT_TYPE_VALUES=["default","named","namespace","require","sideeffect","type"];function normalizeGraphPath(filePath){return path214.normalize(filePath).replace(/\\/g,"/")}var PACKAGE_BOUNDARY_ROOTS=new Set(["packages","crates","apps","libs","services"]);function inferPackageBoundary(moduleName,hasManifest){let parts=moduleName.replace(/\\/g,"/").replace(/^(?:\.\/)+/,"").split("/").filter(Boolean);if(parts.length===0)return".";if(PACKAGE_BOUNDARY_ROOTS.has(parts[0])&&parts.length>=2)return`${parts[0]}/${parts[1]}`;if(parts[0]==="src"&&parts.length>=2)return`src/${parts[1]}`;if(parts[0]==="tests"&&parts.length>=2)return`tests/${parts[1]}`;if(hasManifest&&parts.length>=2){if(hasManifest(parts[0])||hasManifest(`${parts[0]}/${parts[1]}`))return`${parts[0]}/${parts[1]}`}return parts[0]}function createEmptyGraph(workspaceRoot){return{schema_version:GRAPH_SCHEMA_VERSION,workspaceRoot:path214.normalize(workspaceRoot),nodes:{},edges:[],metadata:{generatedAt:new Date().toISOString(),generator:"repo-graph",nodeCount:0,edgeCount:0}}}function updateGraphMetadata(graph){graph.metadata={generatedAt:new Date().toISOString(),generator:"repo-graph",nodeCount:Object.keys(graph.nodes).length,edgeCount:graph.edges.length}}var HTTP_METHODS=["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"],MAX_FACTS_PER_KIND=50;function stripComments(content){let out="",i=0,state="code";while(i<content.length){let ch=content[i],next=i+1<content.length?content[i+1]:"";switch(state){case"code":if(ch==="/"&&next==="/")state="line",i+=2;else if(ch==="/"&&next==="*")state="block",i+=2;else{if(ch==="'")state="single";else if(ch==='"')state="double";else if(ch==="`")state="template";out+=ch,i++}break;case"single":case"double":case"template":{let quote=state==="single"?"'":state==="double"?'"':"`";if(ch==="\\")out+=ch+next,i+=2;else{if(ch===quote)state="code";out+=ch,i++}break}case"line":if(ch===`
6185
6192
  `)state="code",out+=ch;i++;break;case"block":if(ch==="*"&&next==="/")state="code",i+=2;else{if(ch===`
6186
- `)out+=ch;i++}break}}return out}function normalizeModuleName(moduleName){return moduleName.replace(/\\/g,"/").replace(/^(?:\.\/)+/,"")}function uniqueSorted(values){return[...new Set(values)].sort((a,b)=>a.localeCompare(b))}function addRole(roles,role){roles.add(role)}function boundaryForModule(moduleName,hasManifest){return inferPackageBoundary(moduleName,hasManifest)}function inferRoles(moduleName,content){let normalized=normalizeModuleName(moduleName).toLowerCase(),roles=new Set;if(/(^|\/)(__tests__|tests?)\//.test(normalized)||/\.(test|spec)\.[cm]?[jt]sx?$/.test(normalized))addRole(roles,"test_file");if(/(^|\/)(app\/api|pages\/api)\//.test(normalized)||/(^|\/)(routes?|controllers?)\//.test(normalized)||/\/route\.[cm]?[jt]sx?$/.test(normalized)||/\b(router|app|server)\s*\.\s*(get|post|put|patch|delete|all)\s*\(/i.test(content))addRole(roles,"api_route");if(/(^|\/)middleware\.[cm]?[jt]sx?$/.test(normalized))addRole(roles,"middleware");if(normalized.startsWith("src/tools/"))addRole(roles,"swarm_tool");if(normalized.startsWith("src/hooks/"))addRole(roles,"hook");if(normalized.startsWith("src/agents/"))addRole(roles,"agent");if(normalized.startsWith("src/cli/")||normalized.startsWith("src/commands/"))addRole(roles,"cli_command");if(normalized.startsWith("src/config/")||/(^|\/)(config|settings)\.[cm]?[jt]s$/.test(normalized))addRole(roles,"config");if(/(^|\/)(schema|schemas|types)\//.test(normalized)||/\b(z\.object|type\s+\w+\s*=|interface\s+\w+)/.test(content))addRole(roles,"schema");if(/(^|\/)(db|database|repositories?|models?|migrations?)\//.test(normalized)||/\b(prisma|drizzle|sequelize|knex|sqlite|sql`|db\.)/i.test(content))addRole(roles,"data_module");if(/(^|\/)(services?|lib|utils?)\//.test(normalized)||/\bexport\s+(async\s+)?function\b/.test(content))addRole(roles,"service_module");if(/\.(md|mdx|rst)$/.test(normalized))addRole(roles,"documentation");if(roles.size===0)addRole(roles,"source_module");return uniqueSorted(roles)}function pathRouteFromModule(moduleName){let parts=normalizeModuleName(moduleName).split("/"),appApi=parts.findIndex((part,index)=>{return part==="api"&&index>0&&parts[index-1]==="app"});if(appApi>=0)return`/${parts.slice(appApi).filter((part)=>!/^route\.[cm]?[jt]sx?$/.test(part)).map(routeSegment).join("/")}`.replace(/\/+/g,"/");let pagesApi=parts.findIndex((part,index)=>{return part==="api"&&index>0&&parts[index-1]==="pages"});if(pagesApi>=0){let last=parts[parts.length-1]?.replace(/\.[^.]+$/,"");return`/${[...parts.slice(pagesApi,-1),last].filter(Boolean).map(routeSegment).join("/")}`.replace(/\/+/g,"/")}return null}function routeSegment(segment){return segment.replace(/^\[(\.\.\.)?(.+)]$/,(_m,rest,name)=>rest?`:${name}*`:`:${name}`).replace(/\.[^.]+$/,"")}function extractRoutes(moduleName,content){let routes=[],pathRoute=pathRouteFromModule(moduleName),lines=content.split(/\r?\n/);for(let i=0;i<lines.length;i++){let line=lines[i];for(let method of HTTP_METHODS){let exportPattern=new RegExp(`\\bexport\\s+(?:async\\s+)?(?:function|const)\\s+${method}\\b`);if(pathRoute&&exportPattern.test(line))routes.push({method,path:pathRoute,line:i+1,source:"handler_export"})}let routerMatch=line.match(/\b(?:router|app|server)\s*\.\s*(get|post|put|patch|delete|options|head|all)\s*\(\s*['"`]([^'"`\0\r\n]+)['"`]/i);if(routerMatch)routes.push({method:routerMatch[1].toUpperCase(),path:routerMatch[2],line:i+1,source:"router_call"})}if(pathRoute&&routes.length===0)routes.push({method:"ALL",path:pathRoute,source:"file_path"});return routes.slice(0,MAX_FACTS_PER_KIND)}function classifyDataOperation(line){let trimmed=line.trim(),lower=trimmed.toLowerCase(),evidence2=trimmed.slice(0,160),operation=null,access5="unknown",entity;if(/\b(transaction|begintransaction|commit|rollback)\b/i.test(trimmed))operation="transaction",access5="database";if(/\b(migrate|migration|schema\.alter|createTable|dropTable)\b/i.test(trimmed))operation="migration",access5="database";if(/\b(findMany|findUnique|findFirst|select|query|count|aggregate)\b/.test(trimmed))operation??="read";if(/\b(create|insert|update|upsert|save|patch)\b/.test(trimmed))operation??="write";if(/\b(delete|deleteMany|remove|destroy)\b/.test(trimmed))operation="delete";if(/\b(sql`|\bselect\b|\binsert\b|\bupdate\b|\bdelete\b|\bfrom\b)/i.test(trimmed))access5="sql";if(/\b(prisma|drizzle|sequelize|knex|db\.|database\.|repository\.)/i.test(trimmed))access5=access5==="sql"?"sql":"orm";if(/\b(readFile|writeFile|appendFile|rmSync|unlink)\b/.test(trimmed))access5="filesystem",operation??=lower.includes("read")?"read":"write";if(/\b(fetch|axios|http\.|https\.)\b/.test(trimmed))access5="network",operation??="read";let entityMatch=trimmed.match(/\b(?:prisma|db|database)\.(\w+)/i);if(entityMatch)entity=entityMatch[1];if(!operation)return null;return{operation,access:access5,entity,line:0,evidence:evidence2}}function extractDataOperations(content){let facts=[],lines=content.split(/\r?\n/);for(let i=0;i<lines.length;i++){let fact=classifyDataOperation(lines[i]);if(!fact)continue;if(fact.line=i+1,facts.push(fact),facts.length>=MAX_FACTS_PER_KIND)break}return facts}function extractSecurityFacts(content){let facts=[],lines=content.split(/\r?\n/),push=(kind,line,evidence2,confidence)=>{facts.push({kind,line,evidence:evidence2.trim().slice(0,160),confidence})};for(let i=0;i<lines.length&&facts.length<MAX_FACTS_PER_KIND;i++){let line=lines[i];if(/\b(requireAuth|requireUser|getServerSession|currentUser|verifyToken|jwt|isAuthenticated|ctx\.user|session)\b/i.test(line))push("authentication",i+1,line,"high");if(/\b(requireRole|hasPermission|authorize|authorization|isAdmin|rbac|policy\.check|can\()\b/i.test(line))push("authorization",i+1,line,"high");if(/\b(z\.object|safeParse|\.parse\(|joi\.|yup\.|validate\w*)\b/i.test(line))push("input_validation",i+1,line,"high");if(/\b(csrf|csrfToken|sameSite)\b/i.test(line))push("csrf",i+1,line,"medium");if(/\b(sanitize|escapeHtml|DOMPurify|xss)\b/i.test(line))push("sanitization",i+1,line,"medium");if(/\b(secret|api[_-]?key|token|password)\b/i.test(line))push("secret_handling",i+1,line,"low")}return facts}function extractConventions(moduleName,roles,routes){let conventions=[];if(roles.includes("test_file"))conventions.push({name:"test_file_naming",evidence:`${path215.basename(moduleName)} matches test/spec naming`});if(routes.some((route)=>route.source==="handler_export"))conventions.push({name:"next_app_route_handler",evidence:"HTTP method exports map to route handlers"});if(roles.includes("swarm_tool"))conventions.push({name:"swarm_tool_module",evidence:"module lives under src/tools"});if(roles.includes("hook"))conventions.push({name:"hook_module",evidence:"module lives under src/hooks"});return conventions}function buildFindings(roles,routes,dataOperations,security){let findings=[],hasAuth=security.some((fact)=>fact.kind==="authentication"||fact.kind==="authorization"||fact.kind==="csrf"),hasValidation=security.some((fact)=>fact.kind==="input_validation"||fact.kind==="sanitization"),mutatingRoute=routes.some((route)=>["POST","PUT","PATCH","DELETE","ALL"].includes(route.method)),writes=dataOperations.filter((fact)=>["write","delete","migration"].includes(fact.operation)),hasTransaction=dataOperations.some((fact)=>fact.operation==="transaction");if(roles.includes("api_route")&&routes.length>0&&!hasAuth)findings.push({code:"api_route_without_detected_auth",severity:"medium",message:"No authentication, authorization, or CSRF guard was detected near this route.",line:routes[0]?.line});if(mutatingRoute&&!hasValidation)findings.push({code:"mutating_route_without_detected_validation",severity:"medium",message:"Route appears to mutate state without a detected validation or sanitization fact.",line:routes.find((route)=>["POST","PUT","PATCH","DELETE","ALL"].includes(route.method))?.line});if(writes.length>1&&!hasTransaction)findings.push({code:"multiple_writes_without_detected_transaction",severity:"low",message:"Multiple write/delete operations were detected without a transaction fact.",line:writes[0]?.line});return findings}function extractFileOntology(input){let moduleName=normalizeModuleName(input.moduleName),content=stripComments(input.content),roles=inferRoles(moduleName,content),routes=extractRoutes(moduleName,content),dataOperations=extractDataOperations(content),security=extractSecurityFacts(content),conventions=extractConventions(moduleName,roles,routes),findings=buildFindings(roles,routes,dataOperations,security);return{roles,packageBoundary:boundaryForModule(moduleName,input.hasManifest),routes,dataOperations,security,conventions,findings}}import{realpathSync as realpathSync34}from"node:fs";function safeRealpathSync(targetPath,fallback,realpathResolver=realpathSync34){try{return realpathResolver(targetPath)}catch(error93){if(error93 instanceof Error&&error93.code==="ENOENT")return fallback;return null}}init_path_security();var FILE_ROLE_SET=new Set(FILE_ROLE_VALUES),ROUTE_METHOD_SET=new Set(ROUTE_METHOD_VALUES),ROUTE_SOURCE_SET=new Set(ROUTE_SOURCE_VALUES),DATA_OPERATION_SET=new Set(DATA_OPERATION_VALUES),DATA_ACCESS_SET=new Set(DATA_ACCESS_VALUES),SECURITY_KIND_SET=new Set(SECURITY_KIND_VALUES),SECURITY_CONFIDENCE_SET=new Set(SECURITY_CONFIDENCE_VALUES),ONTOLOGY_FINDING_SEVERITY_SET=new Set(ONTOLOGY_FINDING_SEVERITY_VALUES),IMPORT_TYPE_SET=new Set(IMPORT_TYPE_VALUES),ONTOLOGY_NAME_PATTERN=/^[a-z][a-z0-9_]*$/;function validateWorkspace(workspace){if(!workspace||typeof workspace!=="string"||workspace.trim()==="")throw Error("Invalid workspace: must be a non-empty string");if(containsControlChars(workspace))throw Error("Invalid workspace: control characters detected");if(containsPathTraversal(workspace))throw Error("Invalid workspace: path traversal detected")}function validateGraphNode(node){if(!node||typeof node!=="object")throw Error("Invalid node: must be an object");if(!node.filePath||typeof node.filePath!=="string")throw Error("Invalid node: filePath is required");if(!node.filePath.startsWith("/")&&!/^[A-Za-z]:[/\\]/.test(node.filePath))throw Error("Invalid node: filePath must be absolute");if(containsPathTraversal(node.filePath))throw Error("Invalid node: filePath contains path traversal");if(containsControlChars(node.filePath))throw Error("Invalid node: filePath contains control characters");if(!node.moduleName||typeof node.moduleName!=="string")throw Error("Invalid node: moduleName is required");if(node.moduleName.startsWith("/")||node.moduleName.startsWith("\\")||/^[A-Za-z]:[/\\]/.test(node.moduleName))throw Error("Invalid node: moduleName must be relative");if(containsPathTraversal(node.moduleName))throw Error("Invalid node: moduleName contains path traversal");if(containsControlChars(node.moduleName))throw Error("Invalid node: moduleName contains control characters");if(typeof node.language!=="string")throw Error("Invalid node: language is required");if(typeof node.mtime!=="string")throw Error("Invalid node: mtime is required");if(node.sizeBytes===void 0!==(node.mtimeMs===void 0))throw Error("Invalid node: sizeBytes and mtimeMs must either both be present or both be absent");if(node.sizeBytes!==void 0&&(typeof node.sizeBytes!=="number"||!Number.isFinite(node.sizeBytes)||node.sizeBytes<0))throw Error("Invalid node: sizeBytes must be a finite non-negative number");if(node.mtimeMs!==void 0&&(typeof node.mtimeMs!=="number"||!Number.isFinite(node.mtimeMs)||node.mtimeMs<0))throw Error("Invalid node: mtimeMs must be a finite non-negative number");if(!Array.isArray(node.exports))throw Error("Invalid node: exports must be an array");for(let exp of node.exports){if(typeof exp!=="string")throw Error("Invalid node: exports must be an array of strings");if(containsControlChars(exp)){let preview=exp.slice(0,120);throw Error(`Invalid node: exports contains control characters (file=${node.filePath}, value="${preview}")`)}}if(!Array.isArray(node.imports))throw Error("Invalid node: imports must be an array");for(let imp of node.imports){if(typeof imp!=="string")throw Error("Invalid node: imports must be an array of strings");if(containsControlChars(imp)){let preview=imp.slice(0,120);throw Error(`Invalid node: imports contains control characters (file=${node.filePath}, value="${preview}")`)}}if(node.exportLines!==void 0){if(typeof node.exportLines!=="object"||node.exportLines===null||Array.isArray(node.exportLines))throw Error("Invalid node: exportLines must be an object");for(let[name,line]of Object.entries(node.exportLines)){if(containsControlChars(name))throw Error("Invalid node: exportLines key contains control characters");if(typeof line!=="number"||!Number.isFinite(line)||line<0)throw Error("Invalid node: exportLines values must be non-negative numbers")}}if(node.exportRanges!==void 0){if(typeof node.exportRanges!=="object"||node.exportRanges===null||Array.isArray(node.exportRanges))throw Error("Invalid node: exportRanges must be an object");for(let[name,range]of Object.entries(node.exportRanges)){if(containsControlChars(name))throw Error("Invalid node: exportRanges key contains control characters");if(typeof range!=="object"||range===null||Array.isArray(range))throw Error("Invalid node: exportRanges values must be objects");let r=range;if(typeof r.startLine!=="number"||!Number.isFinite(r.startLine)||!Number.isInteger(r.startLine)||r.startLine<1||typeof r.endLine!=="number"||!Number.isFinite(r.endLine)||!Number.isInteger(r.endLine)||r.endLine<1)throw Error("Invalid node: exportRanges value must have positive integer startLine and endLine (1-based)");if(r.startLine>r.endLine)throw Error("Invalid node: exportRanges value must have startLine <= endLine")}}if(node.ontology!==void 0)validateOntologyStrings(node)}function validateOntologyStrings(node){let ontology=node.ontology;if(!ontology||typeof ontology!=="object")throw Error("Invalid node: ontology must be an object");let values=[...ontology.roles??[],ontology.packageBoundary,...(ontology.routes??[]).flatMap((route)=>[route.method,route.path,route.source]),...(ontology.dataOperations??[]).flatMap((fact)=>[fact.operation,fact.access,fact.entity??"",fact.evidence]),...(ontology.security??[]).flatMap((fact)=>[fact.kind,fact.evidence,fact.confidence]),...(ontology.conventions??[]).flatMap((fact)=>[fact.name,fact.evidence]),...(ontology.findings??[]).flatMap((finding)=>[finding.code,finding.severity,finding.message])];for(let value of values){if(typeof value!=="string")throw Error("Invalid node: ontology contains non-string value");if(containsControlChars(value)){let preview=value.slice(0,120);throw Error(`Invalid node: ontology contains control characters (file=${node.filePath}, value="${preview}")`)}}for(let role of ontology.roles??[])validateAllowedOntologyValue(node,"ontology.roles",role,FILE_ROLE_SET);for(let route of ontology.routes??[])validateAllowedOntologyValue(node,"ontology.routes.method",route.method,ROUTE_METHOD_SET),validateAllowedOntologyValue(node,"ontology.routes.source",route.source,ROUTE_SOURCE_SET);for(let fact of ontology.dataOperations??[])validateAllowedOntologyValue(node,"ontology.dataOperations.operation",fact.operation,DATA_OPERATION_SET),validateAllowedOntologyValue(node,"ontology.dataOperations.access",fact.access,DATA_ACCESS_SET);for(let fact of ontology.security??[])validateAllowedOntologyValue(node,"ontology.security.kind",fact.kind,SECURITY_KIND_SET),validateAllowedOntologyValue(node,"ontology.security.confidence",fact.confidence,SECURITY_CONFIDENCE_SET);for(let finding of ontology.findings??[])validateOntologyName(node,"ontology.findings.code",finding.code),validateAllowedOntologyValue(node,"ontology.findings.severity",finding.severity,ONTOLOGY_FINDING_SEVERITY_SET)}function validateOntologyName(node,field,value){if(ONTOLOGY_NAME_PATTERN.test(value))return;let preview=value.slice(0,120);throw Error(`Invalid node: ${field} must be lower_snake_case (file=${node.filePath}, value="${preview}")`)}function validateAllowedOntologyValue(node,field,value,allowed){if(allowed.has(value))return;let preview=value.slice(0,120);throw Error(`Invalid node: ${field} contains invalid value (file=${node.filePath}, value="${preview}")`)}function validateGraphEdge(edge){if(!edge||typeof edge!=="object")throw Error("Invalid edge: must be an object");if(!edge.source||typeof edge.source!=="string")throw Error("Invalid edge: source is required");if(!edge.target||typeof edge.target!=="string")throw Error("Invalid edge: target is required");if(containsPathTraversal(edge.source)||containsPathTraversal(edge.target))throw Error("Invalid edge: path traversal detected");if(containsControlChars(edge.source)||containsControlChars(edge.target))throw Error("Invalid edge: control characters detected");if(!edge.importSpecifier||typeof edge.importSpecifier!=="string")throw Error("Invalid edge: importSpecifier is required");if(containsControlChars(edge.importSpecifier))throw Error("Invalid edge: importSpecifier contains control characters");if(!IMPORT_TYPE_SET.has(edge.importType))throw Error("Invalid edge: importType is invalid");if(edge.importedSymbols!==void 0){if(!Array.isArray(edge.importedSymbols))throw Error("Invalid edge: importedSymbols must be an array");for(let symbol3 of edge.importedSymbols){if(typeof symbol3!=="string")throw Error("Invalid edge: importedSymbols must be an array of strings");if(containsControlChars(symbol3))throw Error("Invalid edge: importedSymbols contains control characters")}}if(edge.usedSymbols!==void 0){if(!Array.isArray(edge.usedSymbols))throw Error("Invalid edge: usedSymbols must be an array");for(let symbol3 of edge.usedSymbols){if(typeof symbol3!=="string")throw Error("Invalid edge: usedSymbols must be an array of strings");if(containsControlChars(symbol3))throw Error("Invalid edge: usedSymbols contains control characters")}}if(edge.targetKind!==void 0&&edge.targetKind!=="node"&&edge.targetKind!=="asset")throw Error('Invalid edge: targetKind must be "node" or "asset"')}var _internals162={now:Date.now,safeRealpathSync,extractTSSymbols,extractPythonSymbols,extractRustSymbols,extractGoSymbols,parseFileImports,extractFileOntology,stripComments:stripComments2,computeUsedSymbols,extractFileSymbols},SKIP_DIRECTORIES2=new Set(["node_modules",".git","dist","build","out","coverage",".next",".nuxt",".cache","vendor",".svn",".hg",".svelte-kit"]);function resolveSkipDirectories(excludeDirs){let extras=excludeDirs?.filter((d)=>d.length>0)??[];if(extras.length===0)return SKIP_DIRECTORIES2;return new Set([...SKIP_DIRECTORIES2,...extras])}var SUPPORTED_EXTENSIONS=new Set(LANGUAGE_REGISTRY.getAll().filter((p)=>!p.parserOnly).flatMap((p)=>p.extensions));function isScannableSourcePath(p){return SUPPORTED_EXTENSIONS.has(path216.extname(p).toLowerCase())}function isAssetEdge(edge){if(edge.targetKind==="asset")return!0;if(edge.targetKind==="node")return!1;return!isScannableSourcePath(edge.target)}var DEFAULT_WALK_FILE_CAP=1e4,DEFAULT_WALK_BUDGET_MS=5000,ASYNC_WALK_YIELD_INTERVAL=200,ASYNC_SCAN_YIELD_INTERVAL=16,MAX_DIAGNOSTIC_ENTRIES=200,MAX_EXTRACTOR_INPUT_WITNESSES=100256,EXTENSION_TO_LANGUAGE={};for(let profile of LANGUAGE_REGISTRY.getAll()){if(profile.parserOnly)continue;for(let ext of profile.extensions)EXTENSION_TO_LANGUAGE[ext]=profile.treeSitter.grammarId}var JS_FAMILY_EXTENSION_TO_LANGUAGE={".js":"javascript",".jsx":"javascript",".mjs":"javascript",".cjs":"javascript",".ts":"typescript",".tsx":"tsx"};function upsertNode(graph,node){validateGraphNode(node);let key=normalizeGraphPath(node.filePath);graph.nodes[key]=node,updateGraphMetadata(graph)}function addEdge(graph,edge){if(validateGraphEdge(edge),!graph.edges.some((e)=>e.source===edge.source&&e.target===edge.target&&e.importSpecifier===edge.importSpecifier))graph.edges.push(edge),updateGraphMetadata(graph)}function buildLoopEdgeKey(edge){return`${edge.source}\x00${edge.target}\x00${edge.importSpecifier}`}function appendNodeFast(graph,node){validateGraphNode(node),graph.nodes[normalizeGraphPath(node.filePath)]=node}function appendEdgeFast(graph,edge,seenEdgeKeys){validateGraphEdge(edge);let key=buildLoopEdgeKey(edge);if(seenEdgeKeys.has(key))return;seenEdgeKeys.add(key),graph.edges.push(edge)}function resolveModuleSpecifier(workspaceRoot,sourceFile,specifier){if(containsControlChars(specifier))return null;if(specifier.startsWith("/")||specifier.startsWith("\\"))return null;if(/^[A-Za-z]:[/\\]/.test(specifier))return null;if(specifier.startsWith("http://")||specifier.startsWith("https://"))return null;try{let normalizedSpecifier=specifier,rustParts=specifier.split("::").filter(Boolean);if(rustParts[0]==="crate"){let target=path216.join(workspaceRoot,...rustParts.slice(1));if(!(existsSync109(target)||existsSync109(`${target}.rs`)||existsSync109(path216.join(target,"mod.rs"))))target=path216.join(path216.dirname(sourceFile),...rustParts.slice(1));if(normalizedSpecifier=path216.relative(path216.dirname(sourceFile),target).replace(/\\/g,"/"),!normalizedSpecifier.startsWith("."))normalizedSpecifier=`./${normalizedSpecifier}`}else if(rustParts[0]==="self")normalizedSpecifier=`./${rustParts.slice(1).join("/")}`;else if(rustParts[0]==="super"){let superCount=0;while(rustParts[superCount]==="super")superCount++;normalizedSpecifier=`${"../".repeat(superCount)}${rustParts.slice(superCount).join("/")}`}if(normalizedSpecifier.startsWith(".")){let sourceDir=path216.dirname(sourceFile),resolved=path216.resolve(sourceDir,normalizedSpecifier),initialRealResolved=_internals162.safeRealpathSync(resolved,resolved);if(initialRealResolved===null)return null;let realResolved=initialRealResolved,realRoot=_internals162.safeRealpathSync(workspaceRoot,path216.normalize(workspaceRoot));if(realRoot===null)return null;let findDirectoryEntry=(directory)=>{for(let initName of["__init__.py","__init__.pyw","mod.rs"]){let candidate2=path216.join(directory,initName);if(existsSync109(candidate2))return candidate2}if(path216.extname(sourceFile).toLowerCase()===".go"){let basenameCandidate=path216.join(directory,`${path216.basename(directory)}.go`);if(existsSync109(basenameCandidate))return basenameCandidate;try{let firstGo=fsSync12.readdirSync(directory).filter((entry)=>entry.endsWith(".go")&&!entry.endsWith("_test.go")).sort((a,b)=>a.localeCompare(b))[0];if(firstGo)return path216.join(directory,firstGo)}catch{return null}}return null};if(existsSync109(resolved))try{if(fsSync12.statSync(resolved).isDirectory()){let found=findDirectoryEntry(resolved);if(!found)return null;let foundRealPath=_internals162.safeRealpathSync(found,found);if(foundRealPath===null)return null;realResolved=foundRealPath,resolved=found}}catch{return null}if(!existsSync109(resolved)){let EXTENSIONS=path216.extname(sourceFile).toLowerCase()===".pyw"?[".pyw",".py",".rs",".go",".ts",".tsx",".js",".jsx",".mjs",".cjs",".json"]:[".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".pyw",".rs",".go",".json"],found=null;for(let ext of EXTENSIONS){let candidate2=resolved+ext;if(existsSync109(candidate2)){found=candidate2;break}}if(!found)found=findDirectoryEntry(resolved);if(found){let foundRealPath=_internals162.safeRealpathSync(found,found);if(foundRealPath===null)return null;realResolved=foundRealPath,resolved=found}else return null}let normalizedResolved=path216.normalize(realResolved),normalizedRoot=path216.normalize(realRoot);if(!normalizedResolved.startsWith(normalizedRoot+path216.sep)&&normalizedResolved!==normalizedRoot)return null;return resolved}return null}catch{return null}}function isRefusedWorkspaceRoot(target){let resolved;try{resolved=realpathSync35(target)}catch{resolved=path216.resolve(target)}let refused=new Set,add2=(p)=>{if(typeof p==="string"&&p.length>0)refused.add(path216.resolve(p))};if(add2(os25.homedir()),add2(os25.tmpdir()),add2("/"),add2("/Users"),add2("/home"),add2("/root"),process.platform==="win32")add2("C:\\"),add2("C:\\Users");return refused.has(resolved)}function createEmptyDiagnostics(){return{extractionFailures:[],unresolvedImports:[],oversizedFiles:[],unsupportedFiles:[],binaryFiles:[],unreadableFiles:[],validationSkippedFiles:[],extractorInputWitnesses:[],lowConfidenceEdgeCount:0,walkTruncated:!1,incrementalFallbacks:0}}function diagnosticsHaveEntries(diagnostics){return(diagnostics.extractionFailures?.length??0)>0||(diagnostics.unresolvedImports?.length??0)>0||(diagnostics.oversizedFiles?.length??0)>0||(diagnostics.unsupportedFiles?.length??0)>0||(diagnostics.binaryFiles?.length??0)>0||(diagnostics.unreadableFiles?.length??0)>0||(diagnostics.validationSkippedFiles?.length??0)>0||(diagnostics.extractorInputWitnesses?.length??0)>0||(diagnostics.lowConfidenceEdgeCount??0)>0||diagnostics.walkTruncated===!0||diagnostics.walkTruncationReason!==void 0||(diagnostics.incrementalFallbacks??0)>0}function pushCapped(target,value){if(target.length<MAX_DIAGNOSTIC_ENTRIES)target.push(value)}function pushInputWitness(target,value){if(target.length<MAX_EXTRACTOR_INPUT_WITNESSES)target.push(value)}function mergeDiagnostics(target,source){if(!source)return;for(let entry of source.extractionFailures??[])pushCapped(target.extractionFailures,entry);for(let entry of source.unresolvedImports??[])pushCapped(target.unresolvedImports,entry);for(let entry of source.oversizedFiles??[])pushCapped(target.oversizedFiles,entry);for(let entry of source.unsupportedFiles??[])pushCapped(target.unsupportedFiles,entry);for(let entry of source.binaryFiles??[])pushCapped(target.binaryFiles,entry);for(let entry of source.unreadableFiles??[])pushCapped(target.unreadableFiles,entry);for(let entry of source.validationSkippedFiles??[])pushCapped(target.validationSkippedFiles,entry);for(let entry of source.extractorInputWitnesses??[])pushInputWitness(target.extractorInputWitnesses,entry);target.lowConfidenceEdgeCount+=source.lowConfidenceEdgeCount??0,target.incrementalFallbacks+=source.incrementalFallbacks??0}function isRelativeImportSpecifier(specifier){return specifier==="."||specifier===".."||specifier.startsWith("./")||specifier.startsWith("../")}function unresolvedRelativeImportsFor(parsedImports,filePath,absoluteRoot){let unresolved=[],moduleName=toModuleName(filePath,absoluteRoot);for(let parsed of parsedImports){if(!isRelativeImportSpecifier(parsed.specifier))continue;if(resolveModuleSpecifier(absoluteRoot,filePath,parsed.specifier)===null)unresolved.push({file:moduleName,specifier:parsed.specifier})}return unresolved}var REGEX_ALLOWED_AFTER=new Set("(,=:[!&|?{};*+-~^<>%".split(""));function stripComments2(content){let out="",i=0,n=content.length,state="code",prevSignificant="",regexInClass=!1;while(i<n){let ch=content[i],next=i+1<n?content[i+1]:"";switch(state){case"code":if(ch==="/"&&next==="/")state="line",i+=2;else if(ch==="/"&&next==="*")state="block",i+=2;else if(ch==="/"&&REGEX_ALLOWED_AFTER.has(prevSignificant))state="regex",regexInClass=!1,out+=ch,i+=1;else{if(ch==="'")state="single";else if(ch==='"')state="double";else if(ch==="`")state="template";if(out+=ch,ch.trim()!=="")prevSignificant=ch;i+=1}break;case"single":case"double":case"template":{let quote=state==="single"?"'":state==="double"?'"':"`";if(ch==="\\")out+=ch+next,i+=2;else{if(ch===quote)state="code",prevSignificant=quote;out+=ch,i+=1}break}case"regex":if(ch==="\\")out+=ch+next,i+=2;else if(ch===`
6193
+ `)out+=ch;i++}break}}return out}function normalizeModuleName(moduleName){return moduleName.replace(/\\/g,"/").replace(/^(?:\.\/)+/,"")}function uniqueSorted(values){return[...new Set(values)].sort((a,b)=>a.localeCompare(b))}function addRole(roles,role){roles.add(role)}function boundaryForModule(moduleName,hasManifest){return inferPackageBoundary(moduleName,hasManifest)}function inferRoles(moduleName,content){let normalized=normalizeModuleName(moduleName).toLowerCase(),roles=new Set;if(/(^|\/)(__tests__|tests?)\//.test(normalized)||/\.(test|spec)\.[cm]?[jt]sx?$/.test(normalized))addRole(roles,"test_file");if(/(^|\/)(app\/api|pages\/api)\//.test(normalized)||/(^|\/)(routes?|controllers?)\//.test(normalized)||/\/route\.[cm]?[jt]sx?$/.test(normalized)||/\b(router|app|server)\s*\.\s*(get|post|put|patch|delete|all)\s*\(/i.test(content))addRole(roles,"api_route");if(/(^|\/)middleware\.[cm]?[jt]sx?$/.test(normalized))addRole(roles,"middleware");if(normalized.startsWith("src/tools/"))addRole(roles,"swarm_tool");if(normalized.startsWith("src/hooks/"))addRole(roles,"hook");if(normalized.startsWith("src/agents/"))addRole(roles,"agent");if(normalized.startsWith("src/cli/")||normalized.startsWith("src/commands/"))addRole(roles,"cli_command");if(normalized.startsWith("src/config/")||/(^|\/)(config|settings)\.[cm]?[jt]s$/.test(normalized))addRole(roles,"config");if(/(^|\/)(schema|schemas|types)\//.test(normalized)||/\b(z\.object|type\s+\w+\s*=|interface\s+\w+)/.test(content))addRole(roles,"schema");if(/(^|\/)(db|database|repositories?|models?|migrations?)\//.test(normalized)||/\b(prisma|drizzle|sequelize|knex|sqlite|sql`|db\.)/i.test(content))addRole(roles,"data_module");if(/(^|\/)(services?|lib|utils?)\//.test(normalized)||/\bexport\s+(async\s+)?function\b/.test(content))addRole(roles,"service_module");if(/\.(md|mdx|rst)$/.test(normalized))addRole(roles,"documentation");if(roles.size===0)addRole(roles,"source_module");return uniqueSorted(roles)}function pathRouteFromModule(moduleName){let parts=normalizeModuleName(moduleName).split("/"),appApi=parts.findIndex((part,index)=>{return part==="api"&&index>0&&parts[index-1]==="app"});if(appApi>=0)return`/${parts.slice(appApi).filter((part)=>!/^route\.[cm]?[jt]sx?$/.test(part)).map(routeSegment).join("/")}`.replace(/\/+/g,"/");let pagesApi=parts.findIndex((part,index)=>{return part==="api"&&index>0&&parts[index-1]==="pages"});if(pagesApi>=0){let last=parts[parts.length-1]?.replace(/\.[^.]+$/,"");return`/${[...parts.slice(pagesApi,-1),last].filter(Boolean).map(routeSegment).join("/")}`.replace(/\/+/g,"/")}return null}function routeSegment(segment){return segment.replace(/^\[(\.\.\.)?(.+)]$/,(_m,rest,name)=>rest?`:${name}*`:`:${name}`).replace(/\.[^.]+$/,"")}function extractRoutes(moduleName,content){let routes=[],pathRoute=pathRouteFromModule(moduleName),lines=content.split(/\r?\n/);for(let i=0;i<lines.length;i++){let line=lines[i];for(let method of HTTP_METHODS){let exportPattern=new RegExp(`\\bexport\\s+(?:async\\s+)?(?:function|const)\\s+${method}\\b`);if(pathRoute&&exportPattern.test(line))routes.push({method,path:pathRoute,line:i+1,source:"handler_export"})}let routerMatch=line.match(/\b(?:router|app|server)\s*\.\s*(get|post|put|patch|delete|options|head|all)\s*\(\s*['"`]([^'"`\0\r\n]+)['"`]/i);if(routerMatch)routes.push({method:routerMatch[1].toUpperCase(),path:routerMatch[2],line:i+1,source:"router_call"})}if(pathRoute&&routes.length===0)routes.push({method:"ALL",path:pathRoute,source:"file_path"});return routes.slice(0,MAX_FACTS_PER_KIND)}function classifyDataOperation(line){let trimmed=line.trim(),lower=trimmed.toLowerCase(),evidence2=trimmed.slice(0,160),operation=null,access5="unknown",entity;if(/\b(transaction|begintransaction|commit|rollback)\b/i.test(trimmed))operation="transaction",access5="database";if(/\b(migrate|migration|schema\.alter|createTable|dropTable)\b/i.test(trimmed))operation="migration",access5="database";if(/\b(findMany|findUnique|findFirst|select|query|count|aggregate)\b/.test(trimmed))operation??="read";if(/\b(create|insert|update|upsert|save|patch)\b/.test(trimmed))operation??="write";if(/\b(delete|deleteMany|remove|destroy)\b/.test(trimmed))operation="delete";if(/\b(sql`|\bselect\b|\binsert\b|\bupdate\b|\bdelete\b|\bfrom\b)/i.test(trimmed))access5="sql";if(/\b(prisma|drizzle|sequelize|knex|db\.|database\.|repository\.)/i.test(trimmed))access5=access5==="sql"?"sql":"orm";if(/\b(readFile|writeFile|appendFile|rmSync|unlink)\b/.test(trimmed))access5="filesystem",operation??=lower.includes("read")?"read":"write";if(/\b(fetch|axios|http\.|https\.)\b/.test(trimmed))access5="network",operation??="read";let entityMatch=trimmed.match(/\b(?:prisma|db|database)\.(\w+)/i);if(entityMatch)entity=entityMatch[1];if(!operation)return null;return{operation,access:access5,entity,line:0,evidence:evidence2}}function extractDataOperations(content){let facts=[],lines=content.split(/\r?\n/);for(let i=0;i<lines.length;i++){let fact=classifyDataOperation(lines[i]);if(!fact)continue;if(fact.line=i+1,facts.push(fact),facts.length>=MAX_FACTS_PER_KIND)break}return facts}function extractSecurityFacts(content){let facts=[],lines=content.split(/\r?\n/),push=(kind,line,evidence2,confidence)=>{facts.push({kind,line,evidence:evidence2.trim().slice(0,160),confidence})};for(let i=0;i<lines.length&&facts.length<MAX_FACTS_PER_KIND;i++){let line=lines[i];if(/\b(requireAuth|requireUser|getServerSession|currentUser|verifyToken|jwt|isAuthenticated|ctx\.user|session)\b/i.test(line))push("authentication",i+1,line,"high");if(/\b(requireRole|hasPermission|authorize|authorization|isAdmin|rbac|policy\.check|can\()\b/i.test(line))push("authorization",i+1,line,"high");if(/\b(z\.object|safeParse|\.parse\(|joi\.|yup\.|validate\w*)\b/i.test(line))push("input_validation",i+1,line,"high");if(/\b(csrf|csrfToken|sameSite)\b/i.test(line))push("csrf",i+1,line,"medium");if(/\b(sanitize|escapeHtml|DOMPurify|xss)\b/i.test(line))push("sanitization",i+1,line,"medium");if(/\b(secret|api[_-]?key|token|password)\b/i.test(line))push("secret_handling",i+1,line,"low")}return facts}function extractConventions(moduleName,roles,routes){let conventions=[];if(roles.includes("test_file"))conventions.push({name:"test_file_naming",evidence:`${path215.basename(moduleName)} matches test/spec naming`});if(routes.some((route)=>route.source==="handler_export"))conventions.push({name:"next_app_route_handler",evidence:"HTTP method exports map to route handlers"});if(roles.includes("swarm_tool"))conventions.push({name:"swarm_tool_module",evidence:"module lives under src/tools"});if(roles.includes("hook"))conventions.push({name:"hook_module",evidence:"module lives under src/hooks"});return conventions}function buildFindings(roles,routes,dataOperations,security){let findings=[],hasAuth=security.some((fact)=>fact.kind==="authentication"||fact.kind==="authorization"||fact.kind==="csrf"),hasValidation=security.some((fact)=>fact.kind==="input_validation"||fact.kind==="sanitization"),mutatingRoute=routes.some((route)=>["POST","PUT","PATCH","DELETE","ALL"].includes(route.method)),writes=dataOperations.filter((fact)=>["write","delete","migration"].includes(fact.operation)),hasTransaction=dataOperations.some((fact)=>fact.operation==="transaction");if(roles.includes("api_route")&&routes.length>0&&!hasAuth)findings.push({code:"api_route_without_detected_auth",severity:"medium",message:"No authentication, authorization, or CSRF guard was detected near this route.",line:routes[0]?.line});if(mutatingRoute&&!hasValidation)findings.push({code:"mutating_route_without_detected_validation",severity:"medium",message:"Route appears to mutate state without a detected validation or sanitization fact.",line:routes.find((route)=>["POST","PUT","PATCH","DELETE","ALL"].includes(route.method))?.line});if(writes.length>1&&!hasTransaction)findings.push({code:"multiple_writes_without_detected_transaction",severity:"low",message:"Multiple write/delete operations were detected without a transaction fact.",line:writes[0]?.line});return findings}function extractFileOntology(input){let moduleName=normalizeModuleName(input.moduleName),content=stripComments(input.content),roles=inferRoles(moduleName,content),routes=extractRoutes(moduleName,content),dataOperations=extractDataOperations(content),security=extractSecurityFacts(content),conventions=extractConventions(moduleName,roles,routes),findings=buildFindings(roles,routes,dataOperations,security);return{roles,packageBoundary:boundaryForModule(moduleName,input.hasManifest),routes,dataOperations,security,conventions,findings}}import{realpathSync as realpathSync34}from"node:fs";function safeRealpathSync(targetPath,fallback,realpathResolver=realpathSync34){try{return realpathResolver(targetPath)}catch(error93){if(error93 instanceof Error&&error93.code==="ENOENT")return fallback;return null}}init_path_security();var FILE_ROLE_SET=new Set(FILE_ROLE_VALUES),ROUTE_METHOD_SET=new Set(ROUTE_METHOD_VALUES),ROUTE_SOURCE_SET=new Set(ROUTE_SOURCE_VALUES),DATA_OPERATION_SET=new Set(DATA_OPERATION_VALUES),DATA_ACCESS_SET=new Set(DATA_ACCESS_VALUES),SECURITY_KIND_SET=new Set(SECURITY_KIND_VALUES),SECURITY_CONFIDENCE_SET=new Set(SECURITY_CONFIDENCE_VALUES),ONTOLOGY_FINDING_SEVERITY_SET=new Set(ONTOLOGY_FINDING_SEVERITY_VALUES),IMPORT_TYPE_SET=new Set(IMPORT_TYPE_VALUES),ONTOLOGY_NAME_PATTERN=/^[a-z][a-z0-9_]*$/;function validateWorkspace(workspace){if(!workspace||typeof workspace!=="string"||workspace.trim()==="")throw Error("Invalid workspace: must be a non-empty string");if(containsControlChars(workspace))throw Error("Invalid workspace: control characters detected");if(containsPathTraversal(workspace))throw Error("Invalid workspace: path traversal detected")}function validateGraphNode(node){if(!node||typeof node!=="object")throw Error("Invalid node: must be an object");if(!node.filePath||typeof node.filePath!=="string")throw Error("Invalid node: filePath is required");if(!node.filePath.startsWith("/")&&!/^[A-Za-z]:[/\\]/.test(node.filePath))throw Error("Invalid node: filePath must be absolute");if(containsPathTraversal(node.filePath))throw Error("Invalid node: filePath contains path traversal");if(containsControlChars(node.filePath))throw Error("Invalid node: filePath contains control characters");if(!node.moduleName||typeof node.moduleName!=="string")throw Error("Invalid node: moduleName is required");if(node.moduleName.startsWith("/")||node.moduleName.startsWith("\\")||/^[A-Za-z]:[/\\]/.test(node.moduleName))throw Error("Invalid node: moduleName must be relative");if(containsPathTraversal(node.moduleName))throw Error("Invalid node: moduleName contains path traversal");if(containsControlChars(node.moduleName))throw Error("Invalid node: moduleName contains control characters");if(typeof node.language!=="string")throw Error("Invalid node: language is required");if(typeof node.mtime!=="string")throw Error("Invalid node: mtime is required");if(node.sizeBytes===void 0!==(node.mtimeMs===void 0))throw Error("Invalid node: sizeBytes and mtimeMs must either both be present or both be absent");if(node.sizeBytes!==void 0&&(typeof node.sizeBytes!=="number"||!Number.isFinite(node.sizeBytes)||node.sizeBytes<0))throw Error("Invalid node: sizeBytes must be a finite non-negative number");if(node.mtimeMs!==void 0&&(typeof node.mtimeMs!=="number"||!Number.isFinite(node.mtimeMs)||node.mtimeMs<0))throw Error("Invalid node: mtimeMs must be a finite non-negative number");if(!Array.isArray(node.exports))throw Error("Invalid node: exports must be an array");for(let exp of node.exports){if(typeof exp!=="string")throw Error("Invalid node: exports must be an array of strings");if(containsControlChars(exp)){let preview=exp.slice(0,120);throw Error(`Invalid node: exports contains control characters (file=${node.filePath}, value="${preview}")`)}}if(!Array.isArray(node.imports))throw Error("Invalid node: imports must be an array");for(let imp of node.imports){if(typeof imp!=="string")throw Error("Invalid node: imports must be an array of strings");if(containsControlChars(imp)){let preview=imp.slice(0,120);throw Error(`Invalid node: imports contains control characters (file=${node.filePath}, value="${preview}")`)}}if(node.exportLines!==void 0){if(typeof node.exportLines!=="object"||node.exportLines===null||Array.isArray(node.exportLines))throw Error("Invalid node: exportLines must be an object");for(let[name,line]of Object.entries(node.exportLines)){if(containsControlChars(name))throw Error("Invalid node: exportLines key contains control characters");if(typeof line!=="number"||!Number.isFinite(line)||line<0)throw Error("Invalid node: exportLines values must be non-negative numbers")}}if(node.exportRanges!==void 0){if(typeof node.exportRanges!=="object"||node.exportRanges===null||Array.isArray(node.exportRanges))throw Error("Invalid node: exportRanges must be an object");for(let[name,range]of Object.entries(node.exportRanges)){if(containsControlChars(name))throw Error("Invalid node: exportRanges key contains control characters");if(typeof range!=="object"||range===null||Array.isArray(range))throw Error("Invalid node: exportRanges values must be objects");let r=range;if(typeof r.startLine!=="number"||!Number.isFinite(r.startLine)||!Number.isInteger(r.startLine)||r.startLine<1||typeof r.endLine!=="number"||!Number.isFinite(r.endLine)||!Number.isInteger(r.endLine)||r.endLine<1)throw Error("Invalid node: exportRanges value must have positive integer startLine and endLine (1-based)");if(r.startLine>r.endLine)throw Error("Invalid node: exportRanges value must have startLine <= endLine")}}if(node.ontology!==void 0)validateOntologyStrings(node)}function validateOntologyStrings(node){let ontology=node.ontology;if(!ontology||typeof ontology!=="object")throw Error("Invalid node: ontology must be an object");let values=[...ontology.roles??[],ontology.packageBoundary,...(ontology.routes??[]).flatMap((route)=>[route.method,route.path,route.source]),...(ontology.dataOperations??[]).flatMap((fact)=>[fact.operation,fact.access,fact.entity??"",fact.evidence]),...(ontology.security??[]).flatMap((fact)=>[fact.kind,fact.evidence,fact.confidence]),...(ontology.conventions??[]).flatMap((fact)=>[fact.name,fact.evidence]),...(ontology.findings??[]).flatMap((finding)=>[finding.code,finding.severity,finding.message])];for(let value of values){if(typeof value!=="string")throw Error("Invalid node: ontology contains non-string value");if(containsControlChars(value)){let preview=value.slice(0,120);throw Error(`Invalid node: ontology contains control characters (file=${node.filePath}, value="${preview}")`)}}for(let role of ontology.roles??[])validateAllowedOntologyValue(node,"ontology.roles",role,FILE_ROLE_SET);for(let route of ontology.routes??[])validateAllowedOntologyValue(node,"ontology.routes.method",route.method,ROUTE_METHOD_SET),validateAllowedOntologyValue(node,"ontology.routes.source",route.source,ROUTE_SOURCE_SET);for(let fact of ontology.dataOperations??[])validateAllowedOntologyValue(node,"ontology.dataOperations.operation",fact.operation,DATA_OPERATION_SET),validateAllowedOntologyValue(node,"ontology.dataOperations.access",fact.access,DATA_ACCESS_SET);for(let fact of ontology.security??[])validateAllowedOntologyValue(node,"ontology.security.kind",fact.kind,SECURITY_KIND_SET),validateAllowedOntologyValue(node,"ontology.security.confidence",fact.confidence,SECURITY_CONFIDENCE_SET);for(let finding of ontology.findings??[])validateOntologyName(node,"ontology.findings.code",finding.code),validateAllowedOntologyValue(node,"ontology.findings.severity",finding.severity,ONTOLOGY_FINDING_SEVERITY_SET)}function validateOntologyName(node,field,value){if(ONTOLOGY_NAME_PATTERN.test(value))return;let preview=value.slice(0,120);throw Error(`Invalid node: ${field} must be lower_snake_case (file=${node.filePath}, value="${preview}")`)}function validateAllowedOntologyValue(node,field,value,allowed){if(allowed.has(value))return;let preview=value.slice(0,120);throw Error(`Invalid node: ${field} contains invalid value (file=${node.filePath}, value="${preview}")`)}function validateGraphEdge(edge){if(!edge||typeof edge!=="object")throw Error("Invalid edge: must be an object");if(!edge.source||typeof edge.source!=="string")throw Error("Invalid edge: source is required");if(!edge.target||typeof edge.target!=="string")throw Error("Invalid edge: target is required");if(containsPathTraversal(edge.source)||containsPathTraversal(edge.target))throw Error("Invalid edge: path traversal detected");if(containsControlChars(edge.source)||containsControlChars(edge.target))throw Error("Invalid edge: control characters detected");if(!edge.importSpecifier||typeof edge.importSpecifier!=="string")throw Error("Invalid edge: importSpecifier is required");if(containsControlChars(edge.importSpecifier))throw Error("Invalid edge: importSpecifier contains control characters");if(!IMPORT_TYPE_SET.has(edge.importType))throw Error("Invalid edge: importType is invalid");if(edge.importedSymbols!==void 0){if(!Array.isArray(edge.importedSymbols))throw Error("Invalid edge: importedSymbols must be an array");for(let symbol3 of edge.importedSymbols){if(typeof symbol3!=="string")throw Error("Invalid edge: importedSymbols must be an array of strings");if(containsControlChars(symbol3))throw Error("Invalid edge: importedSymbols contains control characters")}}if(edge.usedSymbols!==void 0){if(!Array.isArray(edge.usedSymbols))throw Error("Invalid edge: usedSymbols must be an array");for(let symbol3 of edge.usedSymbols){if(typeof symbol3!=="string")throw Error("Invalid edge: usedSymbols must be an array of strings");if(containsControlChars(symbol3))throw Error("Invalid edge: usedSymbols contains control characters")}}if(edge.targetKind!==void 0&&edge.targetKind!=="node"&&edge.targetKind!=="asset")throw Error('Invalid edge: targetKind must be "node" or "asset"')}var _internals162={now:Date.now,safeRealpathSync,extractTSSymbols,extractPythonSymbols,extractRustSymbols,extractGoSymbols,parseFileImports,extractFileOntology,stripComments:stripComments2,computeUsedSymbols,extractFileSymbols},SKIP_DIRECTORIES2=new Set(["node_modules",".git","dist","build","out","coverage",".next",".nuxt",".cache","vendor",".svn",".hg",".svelte-kit"]);function resolveSkipDirectories(excludeDirs){let extras=excludeDirs?.filter((d)=>d.length>0)??[];if(extras.length===0)return SKIP_DIRECTORIES2;return new Set([...SKIP_DIRECTORIES2,...extras])}var SUPPORTED_EXTENSIONS=new Set(LANGUAGE_REGISTRY.getAll().filter((p)=>!p.parserOnly).flatMap((p)=>p.extensions));function isScannableSourcePath(p){return SUPPORTED_EXTENSIONS.has(path216.extname(p).toLowerCase())}function isAssetEdge(edge){if(edge.targetKind==="asset")return!0;if(edge.targetKind==="node")return!1;return!isScannableSourcePath(edge.target)}var DEFAULT_WALK_FILE_CAP=1e4,DEFAULT_WALK_BUDGET_MS=5000,ASYNC_WALK_YIELD_INTERVAL=200,ASYNC_SCAN_YIELD_INTERVAL=16,MAX_DIAGNOSTIC_ENTRIES=200,MAX_EXTRACTOR_INPUT_WITNESSES=100256,EXTENSION_TO_LANGUAGE={};for(let profile of LANGUAGE_REGISTRY.getAll()){if(profile.parserOnly)continue;for(let ext of profile.extensions)EXTENSION_TO_LANGUAGE[ext]=profile.treeSitter.grammarId}var JS_FAMILY_EXTENSION_TO_LANGUAGE={".js":"javascript",".jsx":"javascript",".mjs":"javascript",".cjs":"javascript",".ts":"typescript",".tsx":"tsx"};function upsertNode(graph,node){validateGraphNode(node);let key=normalizeGraphPath(node.filePath);graph.nodes[key]=node,updateGraphMetadata(graph)}function addEdge(graph,edge){if(validateGraphEdge(edge),!graph.edges.some((e)=>e.source===edge.source&&e.target===edge.target&&e.importSpecifier===edge.importSpecifier))graph.edges.push(edge),updateGraphMetadata(graph)}function buildLoopEdgeKey(edge){return`${edge.source}\x00${edge.target}\x00${edge.importSpecifier}`}function appendNodeFast(graph,node){validateGraphNode(node),graph.nodes[normalizeGraphPath(node.filePath)]=node}function appendEdgeFast(graph,edge,seenEdgeKeys){validateGraphEdge(edge);let key=buildLoopEdgeKey(edge);if(seenEdgeKeys.has(key))return;seenEdgeKeys.add(key),graph.edges.push(edge)}function resolveModuleSpecifier(workspaceRoot,sourceFile,specifier){if(containsControlChars(specifier))return null;if(specifier.startsWith("/")||specifier.startsWith("\\"))return null;if(/^[A-Za-z]:[/\\]/.test(specifier))return null;if(specifier.startsWith("http://")||specifier.startsWith("https://"))return null;try{let normalizedSpecifier=specifier,rustParts=specifier.split("::").filter(Boolean);if(rustParts[0]==="crate"){let target=path216.join(workspaceRoot,...rustParts.slice(1));if(!(existsSync110(target)||existsSync110(`${target}.rs`)||existsSync110(path216.join(target,"mod.rs"))))target=path216.join(path216.dirname(sourceFile),...rustParts.slice(1));if(normalizedSpecifier=path216.relative(path216.dirname(sourceFile),target).replace(/\\/g,"/"),!normalizedSpecifier.startsWith("."))normalizedSpecifier=`./${normalizedSpecifier}`}else if(rustParts[0]==="self")normalizedSpecifier=`./${rustParts.slice(1).join("/")}`;else if(rustParts[0]==="super"){let superCount=0;while(rustParts[superCount]==="super")superCount++;normalizedSpecifier=`${"../".repeat(superCount)}${rustParts.slice(superCount).join("/")}`}if(normalizedSpecifier.startsWith(".")){let sourceDir=path216.dirname(sourceFile),resolved=path216.resolve(sourceDir,normalizedSpecifier),initialRealResolved=_internals162.safeRealpathSync(resolved,resolved);if(initialRealResolved===null)return null;let realResolved=initialRealResolved,realRoot=_internals162.safeRealpathSync(workspaceRoot,path216.normalize(workspaceRoot));if(realRoot===null)return null;let findDirectoryEntry=(directory)=>{for(let initName of["__init__.py","__init__.pyw","mod.rs"]){let candidate2=path216.join(directory,initName);if(existsSync110(candidate2))return candidate2}if(path216.extname(sourceFile).toLowerCase()===".go"){let basenameCandidate=path216.join(directory,`${path216.basename(directory)}.go`);if(existsSync110(basenameCandidate))return basenameCandidate;try{let firstGo=fsSync12.readdirSync(directory).filter((entry)=>entry.endsWith(".go")&&!entry.endsWith("_test.go")).sort((a,b)=>a.localeCompare(b))[0];if(firstGo)return path216.join(directory,firstGo)}catch{return null}}return null};if(existsSync110(resolved))try{if(fsSync12.statSync(resolved).isDirectory()){let found=findDirectoryEntry(resolved);if(!found)return null;let foundRealPath=_internals162.safeRealpathSync(found,found);if(foundRealPath===null)return null;realResolved=foundRealPath,resolved=found}}catch{return null}if(!existsSync110(resolved)){let EXTENSIONS=path216.extname(sourceFile).toLowerCase()===".pyw"?[".pyw",".py",".rs",".go",".ts",".tsx",".js",".jsx",".mjs",".cjs",".json"]:[".ts",".tsx",".js",".jsx",".mjs",".cjs",".py",".pyw",".rs",".go",".json"],found=null;for(let ext of EXTENSIONS){let candidate2=resolved+ext;if(existsSync110(candidate2)){found=candidate2;break}}if(!found)found=findDirectoryEntry(resolved);if(found){let foundRealPath=_internals162.safeRealpathSync(found,found);if(foundRealPath===null)return null;realResolved=foundRealPath,resolved=found}else return null}let normalizedResolved=path216.normalize(realResolved),normalizedRoot=path216.normalize(realRoot);if(!normalizedResolved.startsWith(normalizedRoot+path216.sep)&&normalizedResolved!==normalizedRoot)return null;return resolved}return null}catch{return null}}function isRefusedWorkspaceRoot(target){let resolved;try{resolved=realpathSync35(target)}catch{resolved=path216.resolve(target)}let refused=new Set,add2=(p)=>{if(typeof p==="string"&&p.length>0)refused.add(path216.resolve(p))};if(add2(os25.homedir()),add2(os25.tmpdir()),add2("/"),add2("/Users"),add2("/home"),add2("/root"),process.platform==="win32")add2("C:\\"),add2("C:\\Users");return refused.has(resolved)}function createEmptyDiagnostics(){return{extractionFailures:[],unresolvedImports:[],oversizedFiles:[],unsupportedFiles:[],binaryFiles:[],unreadableFiles:[],validationSkippedFiles:[],extractorInputWitnesses:[],lowConfidenceEdgeCount:0,walkTruncated:!1,incrementalFallbacks:0}}function diagnosticsHaveEntries(diagnostics){return(diagnostics.extractionFailures?.length??0)>0||(diagnostics.unresolvedImports?.length??0)>0||(diagnostics.oversizedFiles?.length??0)>0||(diagnostics.unsupportedFiles?.length??0)>0||(diagnostics.binaryFiles?.length??0)>0||(diagnostics.unreadableFiles?.length??0)>0||(diagnostics.validationSkippedFiles?.length??0)>0||(diagnostics.extractorInputWitnesses?.length??0)>0||(diagnostics.lowConfidenceEdgeCount??0)>0||diagnostics.walkTruncated===!0||diagnostics.walkTruncationReason!==void 0||(diagnostics.incrementalFallbacks??0)>0}function pushCapped(target,value){if(target.length<MAX_DIAGNOSTIC_ENTRIES)target.push(value)}function pushInputWitness(target,value){if(target.length<MAX_EXTRACTOR_INPUT_WITNESSES)target.push(value)}function mergeDiagnostics(target,source){if(!source)return;for(let entry of source.extractionFailures??[])pushCapped(target.extractionFailures,entry);for(let entry of source.unresolvedImports??[])pushCapped(target.unresolvedImports,entry);for(let entry of source.oversizedFiles??[])pushCapped(target.oversizedFiles,entry);for(let entry of source.unsupportedFiles??[])pushCapped(target.unsupportedFiles,entry);for(let entry of source.binaryFiles??[])pushCapped(target.binaryFiles,entry);for(let entry of source.unreadableFiles??[])pushCapped(target.unreadableFiles,entry);for(let entry of source.validationSkippedFiles??[])pushCapped(target.validationSkippedFiles,entry);for(let entry of source.extractorInputWitnesses??[])pushInputWitness(target.extractorInputWitnesses,entry);target.lowConfidenceEdgeCount+=source.lowConfidenceEdgeCount??0,target.incrementalFallbacks+=source.incrementalFallbacks??0}function isRelativeImportSpecifier(specifier){return specifier==="."||specifier===".."||specifier.startsWith("./")||specifier.startsWith("../")}function unresolvedRelativeImportsFor(parsedImports,filePath,absoluteRoot){let unresolved=[],moduleName=toModuleName(filePath,absoluteRoot);for(let parsed of parsedImports){if(!isRelativeImportSpecifier(parsed.specifier))continue;if(resolveModuleSpecifier(absoluteRoot,filePath,parsed.specifier)===null)unresolved.push({file:moduleName,specifier:parsed.specifier})}return unresolved}var REGEX_ALLOWED_AFTER=new Set("(,=:[!&|?{};*+-~^<>%".split(""));function stripComments2(content){let out="",i=0,n=content.length,state="code",prevSignificant="",regexInClass=!1;while(i<n){let ch=content[i],next=i+1<n?content[i+1]:"";switch(state){case"code":if(ch==="/"&&next==="/")state="line",i+=2;else if(ch==="/"&&next==="*")state="block",i+=2;else if(ch==="/"&&REGEX_ALLOWED_AFTER.has(prevSignificant))state="regex",regexInClass=!1,out+=ch,i+=1;else{if(ch==="'")state="single";else if(ch==='"')state="double";else if(ch==="`")state="template";if(out+=ch,ch.trim()!=="")prevSignificant=ch;i+=1}break;case"single":case"double":case"template":{let quote=state==="single"?"'":state==="double"?'"':"`";if(ch==="\\")out+=ch+next,i+=2;else{if(ch===quote)state="code",prevSignificant=quote;out+=ch,i+=1}break}case"regex":if(ch==="\\")out+=ch+next,i+=2;else if(ch===`
6187
6194
  `)state="code",out+=ch,i+=1;else{if(ch==="[")regexInClass=!0;else if(ch==="]")regexInClass=!1;else if(ch==="/"&&!regexInClass)state="code",prevSignificant="/";out+=ch,i+=1}break;case"line":if(ch===`
6188
6195
  `)state="code",out+=ch;i+=1;break;case"block":if(ch==="*"&&next==="/")state="code",i+=2;else{if(ch===`
6189
- `)out+=ch;i+=1}break}}return out}function parseFileImports(rawContent,sourceFile,workspaceRoot){let ext=sourceFile?path216.extname(sourceFile).toLowerCase():"";if(ext===".py"||ext===".pyw")return parsePythonFileImports(rawContent,sourceFile);if(ext===".rs")return parseRustFileImports(rawContent,sourceFile,workspaceRoot);if(ext===".go")return parseGoFileImports(rawContent);let imports=[],content=stripComments2(rawContent),importRegex=/import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`\0\t\r\n]+)['"`]|import\s+['"`]([^'"`\0\t\r\n]+)['"`]|require\s*\(\s*['"`]([^'"`\0\t\r\n]+)['"`]\s*\)|export\s*\{[^}]*\}\s*from\s+['"`]([^'"`\0\t\r\n]+)['"`]|export\s+\*(?:\s+as\s+\w+)?\s+from\s+['"`]([^'"`\0\t\r\n]+)['"`]|import\s*\(\s*['"`]([^'"`\0\t\r\n]+)['"`]\s*\)/g;for(let match of content.matchAll(importRegex)){let modulePath=match[1]||match[2]||match[3]||match[4]||match[5]||match[6];if(!modulePath)continue;if(containsControlChars(modulePath))continue;let matchedString=match[0],importType="named";if(matchedString.includes("* as"))importType="namespace";else if(/^import\s*\(/.test(matchedString))importType="sideeffect";else if(/^export\s*\{/.test(matchedString))importType="named";else if(/^export\s+\*/.test(matchedString))importType="namespace";else if(/^import\s+\{/.test(matchedString))importType="named";else if(/^import\s+\w+\s+from\s+['"`]/.test(matchedString))importType="default";else if(/^import\s+['"`]/m.test(matchedString))importType="sideeffect";else if(matchedString.includes("require("))importType="require";imports.push({specifier:modulePath,importType,importedSymbols:parseImportedSymbols(matchedString,importType),bindings:parseImportBindings(matchedString,importType),reExport:/^\s*export\b/.test(matchedString)})}return imports}function makeParsedImport(specifier,importType,bindings,reExport=!1){if(!specifier||containsControlChars(specifier))return null;return{specifier,importType,importedSymbols:bindings.map((binding)=>binding.imported),bindings,reExport}}function parsePythonFileImports(rawContent,sourceFile){let imports=[],isPackageInit=sourceFile?["__init__.py","__init__.pyw"].includes(path216.basename(sourceFile)):!1;for(let line of rawContent.split(/\r?\n/)){let trimmed=line.trim();if(!trimmed||trimmed.startsWith("#"))continue;let fullImport=trimmed.match(/^import\s+(.+?)(?:\s*#.*)?$/);if(fullImport){for(let rawPart of fullImport[1].split(",")){let part=rawPart.trim();if(!part)continue;let alias=part.match(/^([\w.]+)\s+as\s+(\w+)$/),specifier=alias?alias[1]:part,local=alias?alias[2]:specifier.split(".")[0];if(!/^\w+$/.test(local))continue;let parsed2=makeParsedImport(specifier,"namespace",[{imported:specifier,local}]);if(parsed2)imports.push(parsed2)}continue}let fromImport=trimmed.match(/^from\s+(\S+)\s+import\s+(.+?)(?:\s*#.*)?$/);if(!fromImport)continue;if(fromImport[2].trim()==="*"){let parsed2=makeParsedImport(normalizePythonModuleSpecifier2(fromImport[1]),"namespace",[],isPackageInit);if(parsed2)imports.push(parsed2);continue}let bindings=[];for(let rawPart of fromImport[2].split(",")){let part=rawPart.trim();if(!part)continue;let alias=part.match(/^(\w+)\s+as\s+(\w+)$/);if(alias)bindings.push({imported:alias[1],local:alias[2]});else if(/^\w+$/.test(part))bindings.push({imported:part,local:part})}let parsed=makeParsedImport(normalizePythonModuleSpecifier2(fromImport[1]),"named",bindings,isPackageInit);if(parsed)imports.push(parsed)}return imports}function normalizePythonModuleSpecifier2(specifier){let leadingDots=specifier.match(/^\.+/)?.[0].length??0;if(leadingDots===0)return specifier;let rest=specifier.slice(leadingDots).replace(/\./g,"/");return`${leadingDots===1?"./":"../".repeat(leadingDots-1)}${rest}`}function rustModulePathToSpecifier(modulePath,sourceFile,workspaceRoot){let parts=modulePath.split("::").filter(Boolean);if(parts.length===0)return modulePath;if(parts[0]==="self")return`./${parts.slice(1).join("/")}`;if(parts[0]==="super"){let superCount=0;while(parts[superCount]==="super")superCount++;return`${"../".repeat(superCount)}${parts.slice(superCount).join("/")}`}if(parts[0]==="crate"&&sourceFile&&workspaceRoot){let target=path216.join(workspaceRoot,...parts.slice(1)),relative47=path216.relative(path216.dirname(sourceFile),target).replace(/\\/g,"/");if(!relative47.startsWith("."))relative47=`./${relative47}`;return relative47}return modulePath}function parseRustFileImports(rawContent,sourceFile,workspaceRoot){let imports=[];for(let line of rawContent.split(/\r?\n/)){let trimmed=line.trim();if(!trimmed.startsWith("use "))continue;let grouped=trimmed.match(/^use\s+(.+?)::\{(.+)\}\s*;?\s*$/);if(grouped){let specifier2=rustModulePathToSpecifier(grouped[1].trim(),sourceFile,workspaceRoot),bindings=[];for(let rawPart of grouped[2].split(",")){let part=rawPart.trim();if(!part)continue;let alias2=part.match(/^(\w+)\s+as\s+(\w+)$/);if(alias2)bindings.push({imported:alias2[1],local:alias2[2]});else if(/^\w+$/.test(part)){let local2=part==="self"?grouped[1].split("::").pop()||grouped[1]:part;bindings.push({imported:part,local:local2})}}let parsed2=makeParsedImport(specifier2,"named",bindings);if(parsed2)imports.push(parsed2);continue}let simple=trimmed.match(/^use\s+(.+?)\s*;?\s*$/);if(!simple)continue;let rawPath=simple[1].trim(),alias=rawPath.match(/^(.+?)\s+as\s+(\w+)$/),fullPath=(alias?alias[1]:rawPath).trim(),parts=fullPath.split("::").filter(Boolean),imported=parts.pop()??fullPath,specifier=rustModulePathToSpecifier(parts.join("::")||fullPath,sourceFile,workspaceRoot),local=alias?alias[2]:imported,parsed=makeParsedImport(specifier,"named",/^\w+$/.test(imported)&&/^\w+$/.test(local)?[{imported,local}]:[]);if(parsed)imports.push(parsed)}return imports}function parseGoFileImports(rawContent){let imports=[],content=stripComments2(rawContent),parseSpec=(text)=>{let spec=text.trim();if(!spec)return;let aliased=spec.match(/^([\w._]+)\s+["`]([^"`]+)["`]$/);if(aliased){if(aliased[1]==="_"){let parsed2=makeParsedImport(aliased[2],"sideeffect",[]);if(parsed2)imports.push(parsed2);return}if(aliased[1]==="."){let parsed2=makeParsedImport(aliased[2],"namespace",[{imported:"*",local:"."}]);if(parsed2)imports.push(parsed2);return}let parsed=makeParsedImport(aliased[2],"named",[{imported:aliased[2],local:aliased[1]}]);if(parsed)imports.push(parsed);return}let simple=spec.match(/^["`]([^"`]+)["`]$/);if(simple){let parsed=makeParsedImport(simple[1],"namespace",[]);if(parsed)imports.push(parsed)}};for(let block of content.matchAll(/import\s*\(([\s\S]*?)\)/g))for(let line of block[1].split(/\r?\n/))parseSpec(line);let withoutBlocks=content.replace(/import\s*\([\s\S]*?\)/g,"");for(let match of withoutBlocks.matchAll(/^\s*import\s+(.+)$/gm))parseSpec(match[1]);return imports}function parseImportBindings(matchedString,importType){if(importType==="namespace")return[];if(importType==="default"){let defaultMatch=matchedString.match(/^import\s+(\w+)\s+from\s+['"`]/);return defaultMatch?[{imported:"default",local:defaultMatch[1]}]:[]}if(importType!=="named")return[];let braceMatch=matchedString.match(/\{\s*([\s\S]*?)\s*\}/);if(!braceMatch)return[];let bindings=[],seen=new Set;for(let rawPart of braceMatch[1].split(",")){let part=rawPart.trim().replace(/^type\s+/,"");if(!part)continue;let aliasSplit=part.split(/\s+as\s+/i),imported=aliasSplit[0].trim(),local=(aliasSplit[1]??aliasSplit[0]).trim();if(!/^[A-Za-z_$][\w$]*$/.test(imported))continue;if(!/^[A-Za-z_$][\w$]*$/.test(local))continue;if(seen.has(imported))continue;seen.add(imported),bindings.push({imported,local})}return bindings}var SAFE_USAGE_IDENTIFIER=/^[A-Za-z_][A-Za-z0-9_]*$/;function computeUsedSymbols(strippedContent,bindings){if(bindings.length===0)return[];let used=new Set;for(let binding of bindings){if(!SAFE_USAGE_IDENTIFIER.test(binding.local)){used.add(binding.imported);continue}let re=new RegExp(`\\b${binding.local}\\b`,"g"),count=0;for(let _match of strippedContent.matchAll(re))if(count++,count>1)break;if(count>1)used.add(binding.imported)}return[...used].sort((a,b)=>a.localeCompare(b))}function usedSymbolsForImport(parsed,strippedContent){if(parsed.importType==="namespace"||parsed.importType==="sideeffect"||parsed.importType==="require")return;if(parsed.reExport)return[...new Set(parsed.bindings.map((b)=>b.imported))].sort((a,b)=>a.localeCompare(b));return computeUsedSymbols(strippedContent,parsed.bindings)}function collectExports(symbols2){let exported=symbols2.filter((s)=>s.exported),exports=exported.map((s)=>s.signature===`default ${s.name}`?"default":s.name),exportLines={};for(let i=0;i<exported.length;i++){let s=exported[i],name=exports[i];if(typeof s.line==="number"&&Number.isFinite(s.line)&&exportLines[name]===void 0)exportLines[name]=s.line}return{exports,exportLines}}function parseImportedSymbols(matchedString,importType){if(importType==="namespace")return["*"];if(importType==="default")return matchedString.match(/^import\s+(\w+)\s+from\s+['"`]/)?["default"]:[];if(importType!=="named")return[];let braceMatch=matchedString.match(/\{\s*([\s\S]*?)\s*\}/);if(!braceMatch)return[];let symbols2=new Set;for(let rawPart of braceMatch[1].split(",")){let part=rawPart.trim();if(!part)continue;let cleaned=part.replace(/^type\s+/,"").split(/\s+as\s+/i)[0].trim();if(/^[A-Za-z_$][\w$]*$/.test(cleaned))symbols2.add(cleaned)}return[...symbols2].sort((a,b)=>a.localeCompare(b))}var MANIFEST_BASENAMES=new Set(["package.json","Cargo.toml","pyproject.toml","go.mod"]);function isGraphWideInputPath(filePath){return MANIFEST_BASENAMES.has(path216.basename(filePath))}function recordManifestDir(manifestDirs,absoluteRoot,dir,entryName){if(!MANIFEST_BASENAMES.has(entryName))return;let rel=path216.relative(absoluteRoot,dir).split(path216.sep).join("/");if(rel.startsWith("./"))rel=rel.slice(2);manifestDirs.add(rel)}function isWalkBudgetExceeded(ctx){if(ctx.abortReason!==void 0)return!0;if(_internals162.now()-ctx.startedAt>ctx.walkBudgetMs)return ctx.abortReason="budget",!0;return!1}function isFileCapReached(ctx,filesLength){if(filesLength>=ctx.maxFiles)return ctx.abortReason="cap",!0;return!1}async function canonicalDirKeyAsync(dir){try{return await fsPromises6.realpath(dir)}catch{return null}}async function walkRepoGraphInputs(dir,options){let absoluteRoot=path216.resolve(dir),stats2={filesScanned:0,skippedDirs:0,skippedFiles:0,truncated:!1,_absoluteRoot:absoluteRoot},ctx={stats:stats2,seenRealPaths:new Set,startedAt:_internals162.now(),walkBudgetMs:options?.walkBudgetMs??DEFAULT_WALK_BUDGET_MS,maxFiles:options?.maxFiles??DEFAULT_WALK_FILE_CAP,followSymlinks:options?.followSymlinks??!1,skipDirs:resolveSkipDirectories(options?.excludeDirs),manifestDirs:new Set,manifestWitnesses:[]},files=[],manifestFiles=[],metadata=[],unreadableDirectories=[],unreadableFiles=[],queue=[absoluteRoot],processed=0;while(queue.length>0){if(isWalkBudgetExceeded(ctx)||isFileCapReached(ctx,files.length))break;let current=queue.shift(),key=await canonicalDirKeyAsync(current);if(key!==null){if(ctx.seenRealPaths.has(key)){ctx.stats.skippedDirs++;continue}ctx.seenRealPaths.add(key)}else unreadableDirectories.push(current);let entries;try{entries=await fsPromises6.readdir(current,{withFileTypes:!0})}catch{unreadableDirectories.push(current);continue}entries.sort((a,b)=>a.name.toLowerCase().localeCompare(b.name.toLowerCase()));let absoluteRoot2=ctx.stats._absoluteRoot;for(let entry of entries){if(isWalkBudgetExceeded(ctx)||isFileCapReached(ctx,files.length))break;if(ctx.skipDirs.has(entry.name)){ctx.stats.skippedDirs++;continue}let fullPath=path216.join(current,entry.name);if(entry.isSymbolicLink()&&!ctx.followSymlinks){ctx.stats.skippedDirs++;continue}if(entry.isDirectory())queue.push(fullPath);else if(entry.isFile()){if(absoluteRoot2!==void 0)recordManifestDir(ctx.manifestDirs,absoluteRoot2,current,entry.name);let ext=path216.extname(fullPath).toLowerCase(),isSource=SUPPORTED_EXTENSIONS.has(ext),isManifest=isGraphWideInputPath(fullPath);if(isSource)files.push(fullPath);if(isManifest)manifestFiles.push(fullPath);if(options?.captureMetadata&&(isSource||isManifest)||options?.captureManifestMetadata&&isManifest)try{let fileStats=await fsPromises6.stat(fullPath);metadata.push({absolutePath:fullPath,kind:isManifest?"manifest":"source",sizeBytes:fileStats.size,mtimeMs:fileStats.mtimeMs})}catch{unreadableFiles.push(fullPath)}}if(processed++,processed%ASYNC_WALK_YIELD_INTERVAL===0)await yieldToEventLoop()}}if(ctx.abortReason==="cap"||ctx.abortReason==="budget")ctx.stats.truncated=!0;return{sourceFiles:files,manifestFiles,metadata,manifestDirs:ctx.manifestDirs,truncated:stats2.truncated,truncationReason:ctx.abortReason,incomplete:stats2.truncated||unreadableDirectories.length>0||unreadableFiles.length>0,unreadableDirectories,unreadableFiles,probedFiles:metadata.length,elapsedMs:Math.max(0,_internals162.now()-ctx.startedAt)}}function toModuleName(filePath,workspaceRoot){return path216.relative(workspaceRoot,filePath).split(path216.sep).join("/")}function getLanguage(filePath){let ext=path216.extname(filePath).toLowerCase(),jsFamilyLanguage=JS_FAMILY_EXTENSION_TO_LANGUAGE[ext];if(jsFamilyLanguage)return jsFamilyLanguage;return EXTENSION_TO_LANGUAGE[ext]??"unknown"}function isBinaryContent(content){if(content.includes("\x00"))return!0;return!1}function scanFile(filePath,absoluteRoot,maxFileSize,hasManifest){let content,fileStats;try{if(fileStats=fsSync12.statSync(filePath),fileStats.size>maxFileSize)return{node:null,edges:[]};content=fsSync12.readFileSync(filePath,"utf-8")}catch{return{node:null,edges:[]}}if(isBinaryContent(content))return{node:null,edges:[]};let ext=path216.extname(filePath).toLowerCase(),exports=[],exportLines={};try{if([".ts",".tsx",".js",".jsx",".mjs",".cjs"].includes(ext)){let relativePath2=path216.relative(absoluteRoot,filePath);({exports,exportLines}=collectExports(_internals162.extractTSSymbols(relativePath2,absoluteRoot)))}else if(ext===".py"||ext===".pyw"){let relativePath2=path216.relative(absoluteRoot,filePath);({exports,exportLines}=collectExports(_internals162.extractPythonSymbols(relativePath2,absoluteRoot)))}else if(ext===".rs"){let relativePath2=path216.relative(absoluteRoot,filePath);({exports,exportLines}=collectExports(_internals162.extractRustSymbols(relativePath2,absoluteRoot)))}else if(ext===".go"){let relativePath2=path216.relative(absoluteRoot,filePath);({exports,exportLines}=collectExports(_internals162.extractGoSymbols(relativePath2,absoluteRoot)))}let parsedImports=_internals162.parseFileImports(content,filePath,absoluteRoot),strippedForUsage=parsedImports.length>0?_internals162.stripComments(content):"",moduleName=toModuleName(filePath,absoluteRoot),node={filePath,moduleName,exports,...Object.keys(exportLines).length>0?{exportLines}:{},imports:parsedImports.map((p)=>p.specifier),language:getLanguage(filePath),mtime:fileStats.mtime.toISOString(),sizeBytes:fileStats.size,mtimeMs:fileStats.mtimeMs,ontology:_internals162.extractFileOntology({moduleName,filePath,content,language:getLanguage(filePath),exports,imports:parsedImports.map((p)=>p.specifier),hasManifest})},edges=[],sortedImports=[...parsedImports].sort((a,b)=>a.specifier.localeCompare(b.specifier));for(let parsed of sortedImports){let resolvedTarget=resolveModuleSpecifier(absoluteRoot,filePath,parsed.specifier);if(resolvedTarget!==null){let usedSymbols=usedSymbolsForImport(parsed,strippedForUsage);edges.push({source:filePath,target:resolvedTarget,importSpecifier:parsed.specifier,importType:parsed.importType,importedSymbols:parsed.importedSymbols,...usedSymbols!==void 0?{usedSymbols}:{},targetKind:isScannableSourcePath(resolvedTarget)?"node":"asset"})}}return{node,edges}}catch{return{node:null,edges:[]}}}async function scanFileAsync(filePath,absoluteRoot,maxFileSize,hasManifest){let content,fileStats;try{if(fileStats=await fsPromises6.stat(filePath),fileStats.size>maxFileSize){let moduleName2=toModuleName(filePath,absoluteRoot);return{node:null,edges:[],symbolEdges:[],diagnostics:{oversizedFiles:[moduleName2]},inputWitness:{file:moduleName2,kind:"stable-skip",sizeBytes:fileStats.size,mtimeMs:fileStats.mtimeMs}}}content=await fsPromises6.readFile(filePath,"utf-8")}catch{return{node:null,edges:[],symbolEdges:[],diagnostics:{unreadableFiles:[toModuleName(filePath,absoluteRoot)]}}}if(isBinaryContent(content)){let moduleName2=toModuleName(filePath,absoluteRoot);return{node:null,edges:[],symbolEdges:[],diagnostics:{binaryFiles:[moduleName2]},inputWitness:{file:moduleName2,kind:"stable-skip",sizeBytes:fileStats.size,mtimeMs:fileStats.mtimeMs}}}let grammarId=getLanguage(filePath),facts=await _internals162.extractFileSymbols(grammarId,content);if(facts===null){let fallback=scanFile(filePath,absoluteRoot,maxFileSize,hasManifest),parsedImports=[];try{parsedImports=_internals162.parseFileImports(content,filePath,absoluteRoot)}catch{parsedImports=[]}return{...fallback,symbolEdges:[],diagnostics:{extractionFailures:[{file:toModuleName(filePath,absoluteRoot),language:grammarId,reason:"symbol_extraction_failed"}],unresolvedImports:unresolvedRelativeImportsFor(parsedImports,filePath,absoluteRoot)}}}let exportedDefs=facts.defs.filter((d)=>d.exported),exports=exportedDefs.map((d)=>d.name),exportLines={},exportRanges={};for(let d of exportedDefs)exportLines[d.name]=d.startLine,exportRanges[d.name]={startLine:d.startLine,endLine:d.endLine};let exportsSet=new Set(exports),isPythonPackageInit=grammarId==="python"&&["__init__.py","__init__.pyw"].includes(path216.basename(filePath));for(let imp of facts.imports){let packageInitBindings=isPythonPackageInit&&imp.bindings.length>0?imp.bindings.filter((binding)=>!binding.local.startsWith("_")).map((binding)=>({imported:binding.imported,exported:binding.local})):[],exportedBindings=imp.reExport&&imp.exportedBindings?imp.exportedBindings:packageInitBindings;if(exportedBindings.length===0)continue;for(let binding of exportedBindings){if(binding.imported==="*"){if(!exportsSet.has(binding.exported))exportsSet.add(binding.exported),exports.push(binding.exported);if(imp.startLine!==void 0&&exportLines[binding.exported]===void 0)exportLines[binding.exported]=imp.startLine;if(imp.startLine!==void 0&&imp.endLine!==void 0&&exportRanges[binding.exported]===void 0)exportRanges[binding.exported]={startLine:imp.startLine,endLine:imp.endLine};continue}if(!exportsSet.has(binding.exported))exportsSet.add(binding.exported),exports.push(binding.exported);if(imp.startLine!==void 0&&exportLines[binding.exported]===void 0)exportLines[binding.exported]=imp.startLine;if(imp.startLine!==void 0&&imp.endLine!==void 0&&exportRanges[binding.exported]===void 0)exportRanges[binding.exported]={startLine:imp.startLine,endLine:imp.endLine}}}let imports=facts.imports.map((i)=>i.specifier),moduleName=toModuleName(filePath,absoluteRoot),language=grammarId,node={filePath,moduleName,exports,...Object.keys(exportLines).length>0?{exportLines}:{},...Object.keys(exportRanges).length>0?{exportRanges}:{},imports,language,mtime:fileStats.mtime.toISOString(),sizeBytes:fileStats.size,mtimeMs:fileStats.mtimeMs,ontology:_internals162.extractFileOntology({moduleName,filePath,content,language,exports,imports,hasManifest})},edges=[],sortedImports=[...facts.imports].sort((a,b)=>a.specifier.localeCompare(b.specifier));for(let imp of sortedImports){let edgeImportType=imp.importType==="commonjs"?"require":imp.importType,resolvedTarget=resolveModuleSpecifier(absoluteRoot,filePath,imp.specifier);if(resolvedTarget!==null){let usedBindings=imp.reExport?imp.bindings:imp.bindings.filter((b)=>facts.refs.some((r)=>r.identifier===b.local)),usedSymbols=edgeImportType!=="namespace"&&edgeImportType!=="require"&&edgeImportType!=="sideeffect"?usedBindings.map((b)=>b.imported):void 0;edges.push({source:filePath,target:resolvedTarget,importSpecifier:imp.specifier,importType:edgeImportType,importedSymbols:imp.bindings.map((b)=>b.imported),...usedSymbols!==void 0?{usedSymbols}:{},targetKind:isScannableSourcePath(resolvedTarget)?"node":"asset"})}}let unresolvedImports=sortedImports.filter((imp)=>isRelativeImportSpecifier(imp.specifier)).filter((imp)=>resolveModuleSpecifier(absoluteRoot,filePath,imp.specifier)===null).map((imp)=>({file:moduleName,specifier:imp.specifier})),symbolEdges=[],localToImported=new Map;for(let imp of facts.imports){if(imp.reExport)continue;for(let binding of imp.bindings)localToImported.set(binding.local,{specifier:imp.specifier,imported:binding.imported})}let seenSymbolEdgeKeys=new Set;for(let ref of facts.refs){let mapping=localToImported.get(ref.identifier);if(!mapping)continue;let resolvedTarget=resolveModuleSpecifier(absoluteRoot,filePath,mapping.specifier);if(!resolvedTarget)continue;let fromSymbol=ref.enclosingDecl??"<module>",key=filePath+"\x00"+fromSymbol+"\x00"+resolvedTarget+"\x00"+mapping.imported;if(seenSymbolEdgeKeys.has(key))continue;seenSymbolEdgeKeys.add(key),symbolEdges.push({fromFile:filePath,fromSymbol,toFile:resolvedTarget,toSymbol:mapping.imported})}for(let imp of facts.imports){let packageInitBindings=isPythonPackageInit&&imp.bindings.length>0?imp.bindings.filter((binding)=>!binding.local.startsWith("_")).map((binding)=>({imported:binding.imported,exported:binding.local})):[],exportedBindings=imp.reExport&&imp.exportedBindings?imp.exportedBindings:packageInitBindings;if(exportedBindings.length===0)continue;let resolvedTarget=resolveModuleSpecifier(absoluteRoot,filePath,imp.specifier);if(!resolvedTarget)continue;for(let binding of exportedBindings){if(binding.imported==="*")continue;let key=filePath+"\x00"+binding.exported+"\x00"+resolvedTarget+"\x00"+binding.imported;if(seenSymbolEdgeKeys.has(key))continue;seenSymbolEdgeKeys.add(key),symbolEdges.push({fromFile:filePath,fromSymbol:binding.exported,toFile:resolvedTarget,toSymbol:binding.imported})}}return{node,edges,symbolEdges,diagnostics:unresolvedImports.length>0?{unresolvedImports}:void 0}}async function buildWorkspaceGraphAsync(workspaceRoot,options){validateWorkspace(workspaceRoot);let maxFileSize=options?.maxFileSizeBytes??1048576,maxFiles=options?.maxFiles??DEFAULT_WALK_FILE_CAP,walkBudgetMs=options?.walkBudgetMs??DEFAULT_WALK_BUDGET_MS,followSymlinks=options?.followSymlinks??!1,absoluteRoot=path216.resolve(workspaceRoot);if(!existsSync109(absoluteRoot))throw Error(`Workspace directory does not exist: ${workspaceRoot}`);if(isRefusedWorkspaceRoot(absoluteRoot))throw Error(`Refusing to scan top-level system path as workspace: ${absoluteRoot}. Set workspaceRoot to a project directory.`);let graph=createEmptyGraph(workspaceRoot),stats2={filesScanned:0,skippedDirs:0,skippedFiles:0,truncated:!1,_absoluteRoot:absoluteRoot},diagnostics=createEmptyDiagnostics(),walked=await walkRepoGraphInputs(absoluteRoot,{walkBudgetMs,maxFiles,followSymlinks,excludeDirs:options?.excludeDirs,captureManifestMetadata:!0}),sourceFiles=walked.sourceFiles;stats2.truncated=walked.truncated;for(let input of walked.metadata){if(input.kind!=="manifest")continue;let relative47=toModuleName(input.absolutePath,absoluteRoot);pushInputWitness(diagnostics.extractorInputWitnesses,{file:relative47,kind:"manifest",sizeBytes:input.sizeBytes,mtimeMs:input.mtimeMs})}if(sourceFiles.sort((a,b)=>{let normA=normalizeGraphPath(a),normB=normalizeGraphPath(b);return normA.localeCompare(normB)}),stats2.truncated)warn(`[repo-graph] Walk truncated: collected ${sourceFiles.length} files within ${walkBudgetMs}ms / ${maxFiles}-file budget.`);let hasManifest=(relDir)=>walked.manifestDirs.has(relDir),seenEdges=new Set,seenSymbolEdges=new Set,allSymbolEdges=[],processedSinceYield=0;for(let filePath of sourceFiles){let result=await scanFileAsync(filePath,absoluteRoot,maxFileSize,hasManifest);if(mergeDiagnostics(diagnostics,result.diagnostics),result.inputWitness)pushInputWitness(diagnostics.extractorInputWitnesses,result.inputWitness);if(result.node){let appended=!1;try{appendNodeFast(graph,result.node),appended=!0}catch{stats2.skippedFiles++,pushCapped(diagnostics.validationSkippedFiles,result.node.moduleName),pushInputWitness(diagnostics.extractorInputWitnesses,{file:result.node.moduleName,kind:"stable-skip",sizeBytes:result.node.sizeBytes,mtimeMs:result.node.mtimeMs})}if(appended){for(let edge of result.edges)try{appendEdgeFast(graph,edge,seenEdges)}catch{}for(let symbolEdge of result.symbolEdges){let key=symbolEdge.fromFile+"\x00"+symbolEdge.fromSymbol+"\x00"+symbolEdge.toFile+"\x00"+symbolEdge.toSymbol;if(!seenSymbolEdges.has(key))seenSymbolEdges.add(key),allSymbolEdges.push(symbolEdge)}stats2.filesScanned++}}else stats2.skippedFiles++;if(processedSinceYield++,processedSinceYield%ASYNC_SCAN_YIELD_INTERVAL===0)await yieldToEventLoop()}if(graph.metadata={generatedAt:new Date().toISOString(),generator:"repo-graph",nodeCount:Object.keys(graph.nodes).length,edgeCount:graph.edges.length},allSymbolEdges.length>0)graph.symbolEdges=allSymbolEdges;if(diagnostics.walkTruncated=stats2.truncated,diagnostics.walkTruncationReason=walked.truncationReason,graph.diagnostics=diagnosticsHaveEntries(diagnostics)?diagnostics:createEmptyDiagnostics(),stats2.skippedFiles>0||stats2.skippedDirs>0||stats2.truncated)log(`[repo-graph] Scan stats: ${stats2.filesScanned} files scanned, ${stats2.skippedFiles} files skipped, ${stats2.skippedDirs} dirs skipped`+(stats2.truncated?", TRUNCATED":""));return graph}var DEFAULT_TOP_N=8,MAX_TOP_N=25,ALPHA=0.25,MAX_ITERATIONS=25,CONVERGENCE_THRESHOLD=0.000001,FIELD_WEIGHTS={moduleName:3,exports:2,imports:1},TEST_PATH_FACTOR=0.35,TEST_PATH_RE=/(?:^|[/\\])(?:tests?|__tests?__|spec|__spec__|__mocks?__)[/\\]|\.(?:test|spec|stories)\./i;function tokenize2(text){let raw=text.replace(/[^a-zA-Z0-9_]/g," ").split(/\s+/).filter((t)=>t.length>1),expanded=[];for(let token of raw){expanded.push(token.toLowerCase());for(let sub of splitCompound(token)){let lower=sub.toLowerCase();if(lower!==token.toLowerCase())expanded.push(lower)}}return[...new Set(expanded)]}function splitCompound(token){let parts=[],camel=token.replace(/([a-z])([A-Z])/g,"$1 $2").split(/\s+/);if(camel.length>1){for(let p of camel)if(p.length>1)parts.push(p)}let snake=token.split("_");if(snake.length>1){for(let p of snake)if(p.length>1)parts.push(p)}return parts}function buildVocabulary(graph){let vocab=new Set;for(let node of Object.values(graph.nodes)){for(let sub of splitCompound(node.moduleName))vocab.add(sub.toLowerCase());let baseName=node.moduleName.replace(/^.*[/\\]/,"").replace(/\.[^.]+$/,"");vocab.add(baseName.toLowerCase());for(let seg of node.moduleName.split(/[/\\]/))if(seg.length>1)vocab.add(seg.toLowerCase());for(let exp of node.exports){vocab.add(exp.toLowerCase());for(let sub of splitCompound(exp))vocab.add(sub.toLowerCase())}}let nodes=Object.values(graph.nodes),distinctRoles=new Set;for(let node of nodes)if(node.ontology)for(let role of node.ontology.roles)distinctRoles.add(role.toLowerCase());for(let r of distinctRoles)if(!vocab.has(r)&&wouldScore(r,nodes))vocab.add(r);return vocab}function wouldScore(term,nodes){for(let node of nodes)if(node.moduleName.toLowerCase().includes(term)||node.exports.some((e)=>e.toLowerCase().includes(term))||node.imports.some((i)=>i.toLowerCase().includes(term)))return!0;return!1}function expandTerms(tokens,vocab){let expanded=new Set;for(let token of tokens){if(vocab.has(token))expanded.add(token);for(let sub of splitCompound(token)){let lower=sub.toLowerCase();if(vocab.has(lower))expanded.add(lower)}}return[...expanded].sort()}function computeIDF(term,nodes){let docFreq=0,lower=term.toLowerCase();for(let node of nodes){let moduleLower=node.moduleName.toLowerCase(),baseName=moduleLower.replace(/^.*[/\\]/,"").replace(/\.[^.]+$/,"");if(moduleLower.includes(lower)||baseName===lower||node.exports.some((e)=>e.toLowerCase().includes(lower))||node.imports.some((i)=>i.toLowerCase().includes(lower)))docFreq++}if(docFreq===0)return 0;return Math.log((nodes.length+1)/(docFreq+1))+1}function lexicalScore(node,terms,idfMap){let score=0,matched=[],moduleLower=node.moduleName.toLowerCase(),baseName=moduleLower.replace(/^.*[/\\]/,"").replace(/\.[^.]+$/,"");for(let term of terms){let idf=idfMap.get(term)??0;if(idf===0)continue;let termScore=0;if(moduleLower.includes(term)||baseName===term)termScore+=FIELD_WEIGHTS.moduleName*idf;if(node.exports.some((e)=>e.toLowerCase().includes(term)))termScore+=FIELD_WEIGHTS.exports*idf;if(node.imports.some((i)=>i.toLowerCase().includes(term)))termScore+=FIELD_WEIGHTS.imports*idf;if(termScore>0)score+=termScore,matched.push(term)}if(TEST_PATH_RE.test(node.moduleName))score*=TEST_PATH_FACTOR;return{score,matchedTerms:matched}}function buildUndirectedAdjacency(graph,nodeKeys){let adj=new Map;for(let key of nodeKeys)adj.set(key,new Set);for(let edge of graph.edges){if(isAssetEdge(edge))continue;let s=normalizeGraphPath(edge.source),t=normalizeGraphPath(edge.target);if(adj.has(s)&&adj.has(t))adj.get(s).add(t),adj.get(t).add(s)}return adj}function personalizedPageRank(adj,restart,nodeKeys){let n=nodeKeys.length;if(n===0)return new Map;let scores=new Map;for(let key of nodeKeys)scores.set(key,restart.get(key)??0);for(let iter=0;iter<MAX_ITERATIONS;iter++){let next=new Map;for(let key of nodeKeys)next.set(key,0);let danglingMass=0;for(let key of nodeKeys){let neighbors=adj.get(key);if(!neighbors||neighbors.size===0)danglingMass+=scores.get(key)??0;else{let share=(scores.get(key)??0)/neighbors.size;for(let neighbor of neighbors)next.set(neighbor,(next.get(neighbor)??0)+share)}}let danglingShare=danglingMass/n,l1Delta=0;for(let key of nodeKeys){let damped=(1-ALPHA)*(restart.get(key)??0)+ALPHA*((next.get(key)??0)+danglingShare);l1Delta+=Math.abs(damped-(scores.get(key)??0)),next.set(key,damped)}if(scores=next,l1Delta<CONVERGENCE_THRESHOLD)break}return scores}function askGraph(graph,question,options={}){let topN=Math.min(options.topN??DEFAULT_TOP_N,MAX_TOP_N),nodes=Object.values(graph.nodes),nodeKeys=Object.keys(graph.nodes).sort();if(!question.trim()||nodes.length===0)return{hits:[],expandedTerms:[],budget:{requested:topN,returned:0,dropped:0}};let vocab=buildVocabulary(graph),rawTokens=tokenize2(question),expandedTerms=expandTerms(rawTokens,vocab);if(expandedTerms.length===0)return{hits:[],expandedTerms:[],budget:{requested:topN,returned:0,dropped:0}};let idfMap=new Map;for(let term of expandedTerms)idfMap.set(term,computeIDF(term,nodes));let lexScores=new Map,totalLexScore=0;for(let key of nodeKeys){let node=graph.nodes[key],result=lexicalScore(node,expandedTerms,idfMap);lexScores.set(key,result),totalLexScore+=result.score}let restart=new Map;if(totalLexScore>0)for(let key of nodeKeys)restart.set(key,(lexScores.get(key)?.score??0)/totalLexScore);else{let uniform=1/nodeKeys.length;for(let key of nodeKeys)restart.set(key,uniform)}let adj=buildUndirectedAdjacency(graph,nodeKeys),prScores=personalizedPageRank(adj,restart,nodeKeys),scored=[];for(let key of nodeKeys){let pr=prScores.get(key)??0,lex=lexScores.get(key);if(pr>0||lex&&lex.score>0)scored.push({key,score:Math.round(pr*1e6)/1e6,matchedTerms:lex?.matchedTerms??[]})}scored.sort((a,b)=>{if(b.score!==a.score)return b.score-a.score;return a.key.localeCompare(b.key)});let total=scored.length,hits=scored.slice(0,topN).map(({key,score,matchedTerms})=>{let node=graph.nodes[key];return{file:node.moduleName,score,matchedTerms,topExports:node.exports.slice(0,5),role:node.ontology?.roles[0]??"source_module",community:node.ontology?.packageBoundary??inferPackageBoundary(node.moduleName)}});return{hits,expandedTerms,budget:{requested:topN,returned:hits.length,dropped:Math.max(0,total-topN)}}}import*as path217 from"node:path";var MAX_CACHED_WORKSPACES=16,workspaceCache=new Map;function normalizeWorkspace(workspace){let resolved=path217.normalize(path217.resolve(workspace));return process.platform==="win32"?resolved.toLowerCase():resolved}function touch(key,entry){return workspaceCache.delete(key),workspaceCache.set(key,entry),entry}function getEntry(workspace){let key=normalizeWorkspace(workspace),entry=workspaceCache.get(key);return entry?touch(key,entry):void 0}function setEntry(workspace,entry){let key=normalizeWorkspace(workspace);touch(key,entry);while(workspaceCache.size>MAX_CACHED_WORKSPACES){let oldestKey=workspaceCache.keys().next().value;if(oldestKey===void 0)break;workspaceCache.delete(oldestKey)}}function getCachedGraph(workspace){return getEntry(workspace)?.graph}function setCachedGraph(workspace,graph,mtime){setEntry(workspace,{graph,dirty:!1,...mtime===void 0?{}:{mtime}})}function isDirty(workspace){return getEntry(workspace)?.dirty??!1}function clearCache(workspace){workspaceCache.delete(normalizeWorkspace(workspace))}function getCachedMtime(workspace){return getEntry(workspace)?.mtime}init_package();init_utils2();init_bun_compat();init_path_security();import{createHash as createHash48}from"node:crypto";import*as fsPromises7 from"node:fs/promises";import*as path218 from"node:path";var REPO_GRAPH_FINGERPRINT_FILENAME="repo-graph.fingerprint.json",FINGERPRINT_SCHEMA_VERSION=1,EXTRACTOR_STAMP=createHash48("sha256").update(`${package_default.version}\x00${GRAPH_SCHEMA_VERSION}`).digest("hex"),DEFAULT_WALK_BUDGET_MS2=5000,DEFAULT_MAX_FILES=1e4,CACHE_TTL_MS3=30000,MAX_CACHE_ENTRIES4=16,MAX_FINGERPRINT_BYTES=25165824,MAX_FINGERPRINT_ENTRIES=100256,MAX_RELATIVE_PATH_LENGTH=4096,WINDOWS_RENAME_MAX_RETRIES4=5,WINDOWS_RENAME_RETRY_DELAY_MS2=100,probeCache=new Map,_internals163={now:Date.now,walkRepoGraphInputs,open:fsPromises7.open,bunWrite,fsRename:fsPromises7.rename,fsUnlink:fsPromises7.unlink,retryDelayMs:WINDOWS_RENAME_RETRY_DELAY_MS2};function normalizeRoot(root){let resolved=path218.normalize(path218.resolve(root));return process.platform==="win32"?resolved.toLowerCase():resolved}function normalizedExcludes(options){return[...new Set((options?.excludeDirs??[]).filter(Boolean))].sort((a,b)=>a.localeCompare(b))}function exclusionStamp(options){return createHash48("sha256").update(JSON.stringify({excludeDirs:normalizedExcludes(options),followSymlinks:options?.followSymlinks??!1})).digest("hex")}function optionSignature(options){return JSON.stringify({walkBudgetMs:options?.walkBudgetMs??DEFAULT_WALK_BUDGET_MS2,maxFiles:options?.maxFiles??DEFAULT_MAX_FILES,followSymlinks:options?.followSymlinks??!1,excludeDirs:normalizedExcludes(options)})}function touchCache(rootKey,entry){probeCache.delete(rootKey),probeCache.set(rootKey,entry);while(probeCache.size>MAX_CACHE_ENTRIES4){let oldest=probeCache.keys().next().value;if(oldest===void 0)break;probeCache.delete(oldest)}}function invalidateFreshnessCache(root){if(root===void 0){probeCache.clear();return}probeCache.delete(normalizeRoot(root))}function fingerprintPath(root){let target=validateSwarmPath(root,REPO_GRAPH_FINGERPRINT_FILENAME);return validateSymlinkBoundary(target,root),target}async function writeFingerprintAtomic(root,data){let target=fingerprintPath(root),temp=path218.join(path218.dirname(target),`.repo-graph.fingerprint.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2,10)}.tmp`);validateSymlinkBoundary(temp,root);try{await _internals163.bunWrite(temp,data);let lastError;for(let attempt=0;attempt<WINDOWS_RENAME_MAX_RETRIES4;attempt++)try{await _internals163.fsRename(temp,target),lastError=void 0;break}catch(error93){lastError=error93;let code=error93.code;if(code!=="EEXIST"&&code!=="EPERM"&&code!=="EBUSY"||attempt===WINDOWS_RENAME_MAX_RETRIES4-1)break;await new Promise((resolve86)=>setTimeout(resolve86,_internals163.retryDelayMs))}if(lastError!==void 0)throw lastError}finally{try{await _internals163.fsUnlink(temp)}catch{}}}async function refuseFingerprint(root){try{await _internals163.fsUnlink(fingerprintPath(root))}catch{}return invalidateFreshnessCache(root),!1}function safeRelativePath(value){if(value.length===0||value.length>MAX_RELATIVE_PATH_LENGTH||containsControlChars(value)||path218.isAbsolute(value)||/^[A-Za-z]:[/\\]/.test(value))return null;let normalized=value.replace(/\\/g,"/").replace(/^(?:\.\/)+/,"");if(normalized.length===0||normalized.split("/").some((segment)=>segment===".."||segment===""))return null;return normalized}function relativeFromRoot(root,absolutePath2){let relative48=path218.relative(path218.resolve(root),path218.resolve(absolutePath2));if(relative48.startsWith("..")||path218.isAbsolute(relative48))return null;return safeRelativePath(relative48)}function absoluteFromRelative(root,relativePath2){let safe=safeRelativePath(relativePath2);if(safe===null)return null;let resolvedRoot=path218.resolve(root),absolute=path218.resolve(resolvedRoot,safe),relative48=path218.relative(resolvedRoot,absolute);if(relative48.startsWith("..")||path218.isAbsolute(relative48))return null;return absolute}function validMetadata(value){if(!value||typeof value!=="object"||Array.isArray(value))return!1;let record3=value;return Object.keys(record3).length===2&&typeof record3.size==="number"&&Number.isFinite(record3.size)&&record3.size>=0&&typeof record3.mtimeMs==="number"&&Number.isFinite(record3.mtimeMs)&&record3.mtimeMs>=0}function parseFingerprint(value,options){if(!value||typeof value!=="object"||Array.isArray(value))return null;let record3=value;if(Object.keys(record3).sort().join(",")!=="exclusionStamp,extractorStamp,files,schema_version"||record3.schema_version!==FINGERPRINT_SCHEMA_VERSION||record3.extractorStamp!==EXTRACTOR_STAMP||record3.exclusionStamp!==exclusionStamp(options)||!record3.files||typeof record3.files!=="object"||Array.isArray(record3.files))return null;let rawFiles=record3.files,entries=Object.entries(rawFiles);if(entries.length>MAX_FINGERPRINT_ENTRIES)return null;let files=Object.create(null);for(let[rawPath,metadata]of entries){let safe=safeRelativePath(rawPath);if(safe===null||safe!==rawPath||!validMetadata(metadata))return null;files[safe]=metadata}return{schema_version:FINGERPRINT_SCHEMA_VERSION,extractorStamp:EXTRACTOR_STAMP,exclusionStamp:exclusionStamp(options),files}}function emptyProbe(state,elapsedMs){return{state,changed:[],removed:[],truncated:!1,probedFiles:0,elapsedMs:Math.max(0,elapsedMs)}}async function readFingerprint(root,options){let target=fingerprintPath(root),handle=await _internals163.open(target,"r");try{let stats2=await handle.stat();if(stats2.size>MAX_FINGERPRINT_BYTES)return null;let buffer=Buffer.alloc(stats2.size),offset=0;while(offset<buffer.length){let read=await handle.read(buffer,offset,buffer.length-offset,offset);if(read.bytesRead===0)break;offset+=read.bytesRead}let data=buffer.subarray(0,offset).toString("utf8");return parseFingerprint(JSON.parse(data),options)}finally{await handle.close()}}async function probeUncached(root,options){let startedAt=_internals163.now(),fingerprint2;try{fingerprint2=await readFingerprint(root,options)}catch{fingerprint2=null}if(fingerprint2===null)return emptyProbe("no-fingerprint",_internals163.now()-startedAt);let walk;try{walk=await _internals163.walkRepoGraphInputs(root,{walkBudgetMs:options?.walkBudgetMs,maxFiles:options?.maxFiles,followSymlinks:options?.followSymlinks,excludeDirs:options?.excludeDirs,captureMetadata:!0})}catch{return{...emptyProbe("inconclusive",_internals163.now()-startedAt),truncated:!1}}let current=new Map,changed2=[];for(let input of walk.metadata){let relative48=relativeFromRoot(root,input.absolutePath);if(relative48===null)continue;let metadata={size:input.sizeBytes,mtimeMs:input.mtimeMs};current.set(relative48,metadata);let previous=fingerprint2.files[relative48];if(previous===void 0||previous.size!==metadata.size||previous.mtimeMs!==metadata.mtimeMs)changed2.push(path218.resolve(input.absolutePath))}let incomplete=walk.incomplete,removed=[];if(!incomplete){for(let relative48 of Object.keys(fingerprint2.files))if(!current.has(relative48)){let absolute=absoluteFromRelative(root,relative48);if(absolute!==null)removed.push(absolute)}}return changed2.sort((a,b)=>a.localeCompare(b)),removed.sort((a,b)=>a.localeCompare(b)),{state:incomplete?"inconclusive":changed2.length>0||removed.length>0?"drifted":"clean",changed:changed2,removed:incomplete?[]:removed,truncated:walk.truncated,probedFiles:walk.probedFiles,elapsedMs:Math.max(0,_internals163.now()-startedAt)}}async function probeFreshness(root,options){let rootKey=normalizeRoot(root),signature=optionSignature(options),now2=_internals163.now(),cached3=probeCache.get(rootKey);if(cached3?.signature===signature){if(cached3.value&&cached3.expiresAt>now2)return touchCache(rootKey,cached3),cached3.value;if(cached3.inFlight)return touchCache(rootKey,cached3),cached3.inFlight}let inFlight=probeUncached(root,options),entry={signature,expiresAt:0,inFlight};touchCache(rootKey,entry);try{let value=await inFlight;if(probeCache.get(rootKey)?.inFlight===inFlight)entry.value=value,entry.expiresAt=_internals163.now()+CACHE_TTL_MS3,entry.inFlight=void 0,touchCache(rootKey,entry);return value}catch{if(probeCache.get(rootKey)?.inFlight===inFlight)probeCache.delete(rootKey);return emptyProbe("inconclusive",0)}}function diagnosticPaths(root,diagnostics){let reportedStable=new Set;for(let raw of[...diagnostics?.oversizedFiles??[],...diagnostics?.binaryFiles??[],...diagnostics?.validationSkippedFiles??[]]){let safe=safeRelativePath(raw);if(safe===null)return null;if(absoluteFromRelative(root,safe)===null)return null;reportedStable.add(safe)}let witnesses=new Map,stable=new Set;for(let witness of diagnostics?.extractorInputWitnesses??[]){let safe=safeRelativePath(witness.file);if(safe===null||witness.kind!=="manifest"&&witness.kind!=="stable-skip"||!Number.isFinite(witness.sizeBytes)||witness.sizeBytes<0||!Number.isFinite(witness.mtimeMs)||witness.mtimeMs<0||witnesses.has(safe))return null;if(witnesses.set(safe,{...witness,file:safe}),witness.kind==="stable-skip")stable.add(safe)}for(let relative48 of reportedStable)if(witnesses.get(relative48)?.kind!=="stable-skip")return null;return{stable,witnesses}}async function writeFingerprint(root,graph,options){invalidateFreshnessCache(root);try{let walk=await _internals163.walkRepoGraphInputs(root,{walkBudgetMs:options?.walkBudgetMs,maxFiles:options?.maxFiles,followSymlinks:options?.followSymlinks,excludeDirs:options?.excludeDirs,captureMetadata:!0});if(walk.unreadableDirectories.length>0||walk.unreadableFiles.length>0)return refuseFingerprint(root);let certifiedInputs=diagnosticPaths(root,graph.diagnostics);if(certifiedInputs===null)return refuseFingerprint(root);let current=new Map;for(let input of walk.metadata){let relative48=relativeFromRoot(root,input.absolutePath);if(relative48===null)return refuseFingerprint(root);current.set(relative48,{size:input.sizeBytes,mtimeMs:input.mtimeMs})}for(let[relative48,witness]of certifiedInputs.witnesses){let observed=current.get(relative48);if(observed===void 0||observed.size!==witness.sizeBytes||observed.mtimeMs!==witness.mtimeMs)return refuseFingerprint(root)}let nodePaths=new Set;for(let node of Object.values(graph.nodes)){let relative48=relativeFromRoot(root,node.filePath);if(relative48===null)return refuseFingerprint(root);if(typeof node.sizeBytes!=="number"||!Number.isFinite(node.sizeBytes)||node.sizeBytes<0||typeof node.mtimeMs!=="number"||!Number.isFinite(node.mtimeMs)||node.mtimeMs<0)return refuseFingerprint(root);let observed=current.get(relative48);if(observed===void 0||observed.size!==node.sizeBytes||observed.mtimeMs!==node.mtimeMs)return refuseFingerprint(root);nodePaths.add(relative48)}for(let input of walk.metadata){let relative48=relativeFromRoot(root,input.absolutePath);if(relative48===null)return refuseFingerprint(root);if(input.kind==="manifest"&&certifiedInputs.witnesses.get(relative48)?.kind!=="manifest")return refuseFingerprint(root);if(input.kind!=="source")continue;if(!nodePaths.has(relative48)&&!certifiedInputs.stable.has(relative48))return refuseFingerprint(root)}let files=Object.create(null);for(let relative48 of[...current.keys()].sort((a,b)=>a.localeCompare(b)))files[relative48]=current.get(relative48);if(Object.keys(files).length>MAX_FINGERPRINT_ENTRIES)return refuseFingerprint(root);let sidecar={schema_version:FINGERPRINT_SCHEMA_VERSION,extractorStamp:EXTRACTOR_STAMP,exclusionStamp:exclusionStamp(options),files},serialized3=`${JSON.stringify(sidecar,null,2)}
6190
- `;if(Buffer.byteLength(serialized3,"utf8")>MAX_FINGERPRINT_BYTES)return refuseFingerprint(root);return await writeFingerprintAtomic(root,serialized3),invalidateFreshnessCache(root),!0}catch{return refuseFingerprint(root)}}init_logger();init_path_security();import{existsSync as existsSync111,readdirSync as readdirSync31}from"node:fs";import*as fsPromises9 from"node:fs/promises";import*as path221 from"node:path";init_path_security();import*as fs120 from"node:fs";import*as path219 from"node:path";var GRAPH_HEALTH_OUTPUT_LIMIT=50,MAX_HEALTH_PATH_LENGTH=500,cachedReverseIndex=null;function normalizeLookupPath(input){return normalizeGraphPath(input).replace(/^(?:\.\/)+/,"")}function graphRoot(graph){return path219.resolve(graph.workspaceRoot)}function toModuleName2(graph,input){let normalized=normalizeLookupPath(input);if(path219.isAbsolute(normalized)||/^[A-Za-z]:\//.test(normalized))return normalizeLookupPath(path219.relative(graphRoot(graph),normalized));return normalized}function absoluteKeyForModule(graph,moduleName){return normalizeGraphPath(path219.resolve(graphRoot(graph),moduleName))}function getGraphNode(graph,input){let moduleName=toModuleName2(graph,input),direct=graph.nodes[absoluteKeyForModule(graph,moduleName)];if(direct)return direct;return getQueryIndexes(graph).moduleNameIndex.get(moduleName)}function moduleNameForEdgePath(graph,edgePath){let key=normalizeGraphPath(edgePath),node=graph.nodes[key];if(node)return normalizeLookupPath(node.moduleName);return normalizeLookupPath(path219.relative(graphRoot(graph),edgePath))}function buildReverseIndex(graph){let reverse=new Map,forward=new Map,moduleNameIndex=new Map;for(let node of Object.values(graph.nodes))moduleNameIndex.set(normalizeLookupPath(node.moduleName),node);for(let edge of graph.edges){if(isAssetEdge(edge))continue;let source=normalizeGraphPath(edge.source),target=normalizeGraphPath(edge.target),sourceRef={file:moduleNameForEdgePath(graph,edge.source),importType:edge.importType},targetRef={file:moduleNameForEdgePath(graph,edge.target),importType:edge.importType},reverseRefs=reverse.get(target);if(reverseRefs)reverseRefs.push(sourceRef);else reverse.set(target,[sourceRef]);let forwardRefs=forward.get(source);if(forwardRefs)forwardRefs.push(targetRef);else forward.set(source,[targetRef])}for(let refs of reverse.values())refs.sort((a,b)=>a.file.localeCompare(b.file));for(let refs of forward.values())refs.sort((a,b)=>a.file.localeCompare(b.file));return cachedReverseIndex={graph,index:reverse,forwardIndex:forward,moduleNameIndex},reverse}function getQueryIndexes(graph){if(cachedReverseIndex&&cachedReverseIndex.graph===graph)return cachedReverseIndex;return buildReverseIndex(graph),cachedReverseIndex}function getReverseIndex(graph){return getQueryIndexes(graph).index}function getForwardIndex(graph){return getQueryIndexes(graph).forwardIndex}function resetQueryCache(){cachedReverseIndex=null}function isSafeHealthPath(value){if(typeof value!=="string")return!1;if(value.length===0||value.length>MAX_HEALTH_PATH_LENGTH)return!1;if(containsControlChars(value)||containsPathTraversal(value))return!1;if(path219.isAbsolute(value)||/^[A-Za-z]:[\\/]/.test(value))return!1;return!0}function isSafeHealthText(value){if(typeof value!=="string")return!1;if(value.length===0||value.length>MAX_HEALTH_PATH_LENGTH)return!1;if(containsControlChars(value))return!1;return!0}function cap(entries){return entries.slice(0,GRAPH_HEALTH_OUTPUT_LIMIT)}function sanitizeExtractionFailures(value){if(!Array.isArray(value))return[];let entries=[];for(let raw of value){if(!raw||typeof raw!=="object")continue;let entry=raw;if(isSafeHealthPath(entry.file)&&isSafeHealthText(entry.language)&&isSafeHealthText(entry.reason))entries.push({file:entry.file,language:entry.language,reason:entry.reason})}return cap(entries)}function sanitizeUnresolvedImports(value){if(!Array.isArray(value))return[];let entries=[];for(let raw of value){if(!raw||typeof raw!=="object")continue;let entry=raw;if(isSafeHealthPath(entry.file)&&isSafeHealthText(entry.specifier))entries.push({file:entry.file,specifier:entry.specifier})}return cap(entries)}function sanitizePathList(value){if(!Array.isArray(value))return[];return cap(value.filter(isSafeHealthPath))}function getProbeStaleFiles(probe2,workspaceRoot){if(!probe2)return[];let root=path219.resolve(workspaceRoot),stale=new Set;for(let absolutePath2 of[...probe2.changed,...probe2.removed]){if(typeof absolutePath2!=="string"||!path219.isAbsolute(absolutePath2))continue;let relative49=normalizeGraphPath(path219.relative(root,absolutePath2));if(!isSafeHealthPath(relative49))continue;stale.add(relative49)}return[...stale].sort((a,b)=>a.localeCompare(b)).slice(0,GRAPH_HEALTH_OUTPUT_LIMIT)}function getGraphHealth(graph,workspaceRoot,probe2){let probeState=probe2?.state??"no-fingerprint";if(!graph)return{schemaVersion:null,fresh:!1,probeState,staleFiles:[],extractionFailures:[],unresolvedImports:[],oversizedFiles:[],unsupportedFiles:[],binaryFiles:[],unreadableFiles:[],validationSkippedFiles:[],lowConfidenceEdgeCount:0,walkTruncated:!1,walkTruncationReason:null,incrementalFallbacks:0,notes:['No repo graph found at .swarm/repo-graph.json. Run repo_map with action="build" first.']};let diagnostics=graph.diagnostics,fresh=probeState==="clean",staleFiles=getProbeStaleFiles(probe2,workspaceRoot??graph.workspaceRoot),notes=[];if(probeState==="drifted")notes.push('Graph content is stale relative to the workspace. Run repo_map with action="build" if automatic refresh is unavailable.');else if(probeState==="no-fingerprint")notes.push('Graph has no matching content fingerprint. Run repo_map with action="build" to certify it.');else if(probeState==="inconclusive")notes.push("Graph freshness is unknown because the bounded workspace probe did not complete; no refresh or deletion was attempted.");if(!diagnostics)notes.push('Graph has no recorded diagnostics. Rebuild with repo_map action="build" to collect health details.');let binaryFiles=sanitizePathList(diagnostics?.binaryFiles),binaryCount=binaryFiles.length;if(binaryCount>0)notes.push(`${binaryCount} binary files skipped during last build.`);let unreadableFiles=sanitizePathList(diagnostics?.unreadableFiles),unreadableCount=unreadableFiles.length;if(unreadableCount>0)notes.push(`${unreadableCount} unreadable files skipped during last build.`);let walkTruncated=diagnostics?.walkTruncated===!0,rawReason=diagnostics?.walkTruncationReason,walkTruncationReason=rawReason==="budget"||rawReason==="cap"?rawReason:null,incrementalFallbacks=typeof diagnostics?.incrementalFallbacks==="number"&&Number.isFinite(diagnostics.incrementalFallbacks)&&diagnostics.incrementalFallbacks>0?Math.floor(diagnostics.incrementalFallbacks):0;if(walkTruncated)notes.push("Graph is INCOMPLETE: walk hit the file-cap/wall-clock budget — results may be missing files."+(walkTruncationReason?` (reason: ${walkTruncationReason})`:""));if(incrementalFallbacks>0)notes.push(`${incrementalFallbacks} incremental update(s) fell back to a full rebuild (validation failure or concurrent modification).`);return{schemaVersion:graph.schema_version,fresh,probeState,staleFiles,extractionFailures:sanitizeExtractionFailures(diagnostics?.extractionFailures),unresolvedImports:sanitizeUnresolvedImports(diagnostics?.unresolvedImports),oversizedFiles:sanitizePathList(diagnostics?.oversizedFiles),unsupportedFiles:sanitizePathList(diagnostics?.unsupportedFiles),binaryFiles,unreadableFiles,validationSkippedFiles:sanitizePathList(diagnostics?.validationSkippedFiles),lowConfidenceEdgeCount:typeof diagnostics?.lowConfidenceEdgeCount==="number"&&Number.isFinite(diagnostics.lowConfidenceEdgeCount)&&diagnostics.lowConfidenceEdgeCount>0?Math.floor(diagnostics.lowConfidenceEdgeCount):0,walkTruncated,walkTruncationReason,incrementalFallbacks,notes}}function getImporters(graph,filePath){let node=getGraphNode(graph,filePath);if(!node)return[];return getReverseIndex(graph).get(normalizeGraphPath(node.filePath))??[]}function getDependencies(graph,filePath){let node=getGraphNode(graph,filePath);if(!node)return[];let sourceKey=normalizeGraphPath(node.filePath);return getForwardIndex(graph).get(sourceKey)??[]}function getSymbolConsumers(graph,filePath,symbolName){let node=getGraphNode(graph,filePath);if(!node)return[];let targetKey=normalizeGraphPath(node.filePath),refs=[];for(let edge of graph.edges){if(isAssetEdge(edge))continue;if(normalizeGraphPath(edge.target)!==targetKey)continue;let importedSymbols=edge.importedSymbols??[];if(edge.importType==="namespace"){refs.push({file:moduleNameForEdgePath(graph,edge.source),importedAs:"*"});continue}if(importedSymbols.includes(symbolName))refs.push({file:moduleNameForEdgePath(graph,edge.source),importedAs:symbolName})}return refs.sort((a,b)=>a.file.localeCompare(b.file)),refs}function getCallers(graph,filePath,symbolName){let node=getGraphNode(graph,filePath);if(!node)return[];let targetKey=normalizeGraphPath(node.filePath),refs=[],seen=new Set;for(let edge of graph.edges){if(isAssetEdge(edge))continue;if(normalizeGraphPath(edge.target)!==targetKey)continue;let file3=moduleNameForEdgePath(graph,edge.source);if(seen.has(file3))continue;if(edge.usedSymbols!==void 0){if(edge.usedSymbols.includes(symbolName))seen.add(file3),refs.push({file:file3,resolution:"used"});continue}let imported=edge.importedSymbols??[];if(edge.importType==="namespace"||imported.includes(symbolName))seen.add(file3),refs.push({file:file3,resolution:"imported"})}return refs.sort((a,b)=>a.file.localeCompare(b.file)),refs}var DEAD_EXPORT_EXCLUDED_ROLES=new Set(["api_route","cli_command","test_file","agent","hook","middleware"]);function getDeadExports(graph,options){if(!isSchemaVersionAtLeast(graph.schema_version,"1.1.0"))return{schemaSupported:!1,analyzedFiles:0,skippedUnresolvable:0,candidates:[],note:'Graph predates schema 1.1.0 (no usedSymbols data). Run repo_map action="build" to enable dead_exports.'};let usage=new Map;for(let edge of graph.edges){if(isAssetEdge(edge))continue;let target=normalizeGraphPath(edge.target),entry=usage.get(target);if(!entry)entry={used:new Set,unresolvable:!1},usage.set(target,entry);if(edge.importType==="namespace"||edge.importType==="sideeffect"||edge.importType==="require")entry.unresolvable=!0;else if(edge.usedSymbols)for(let symbol3 of edge.usedSymbols)entry.used.add(symbol3)}let reverse=getReverseIndex(graph),candidates=[],analyzedFiles=0,skippedUnresolvable=0;for(let node of Object.values(graph.nodes)){if(node.exports.length===0)continue;let key=normalizeGraphPath(node.filePath),importerCount=reverse.get(key)?.length??0;if(importerCount===0)continue;if((node.ontology?.roles??[]).some((r)=>DEAD_EXPORT_EXCLUDED_ROLES.has(r)))continue;let entry=usage.get(key);if(entry?.unresolvable){skippedUnresolvable++;continue}analyzedFiles++;let used=entry?.used??new Set;for(let symbol3 of node.exports){if(symbol3==="default")continue;if(used.has(symbol3))continue;candidates.push({file:node.moduleName,symbol:symbol3,line:node.exportLines?.[symbol3],importerCount})}}candidates.sort((a,b)=>a.file.localeCompare(b.file)||a.symbol.localeCompare(b.symbol));let limit=options?.maxCandidates??100,truncated=candidates.length>limit;return{schemaSupported:!0,analyzedFiles,skippedUnresolvable,candidates:candidates.slice(0,limit),note:"Advisory: exported symbols with no detected in-repo reference, limited to files imported by >=1 other file. Regex analysis cannot see dynamic dispatch, string-keyed access, or namespace/barrel re-export usage; verify before removing."+(truncated?` Showing ${limit} of ${candidates.length}.`:"")}}function getBlastRadius(graph,filePaths,maxDepth=3){let targetNodes=filePaths.map((filePath)=>getGraphNode(graph,filePath)).filter((node)=>node!==void 0),targets=targetNodes.map((node)=>normalizeLookupPath(node.moduleName));if(maxDepth<=0||targetNodes.length===0)return{target:filePaths.map((filePath)=>toModuleName2(graph,filePath)),directDependents:[],transitiveDependents:[],depthReached:0,totalDependents:0,riskLevel:"low"};let reverse=getReverseIndex(graph),visited=new Set(targetNodes.map((node)=>normalizeGraphPath(node.filePath))),direct=new Set,transitive=new Set,depthReached=0,queue=targetNodes.map((node)=>({key:normalizeGraphPath(node.filePath),depth:0}));while(queue.length>0){let next=[];for(let{key,depth}of queue){let importers=reverse.get(key)??[];for(let ref of importers){let importerNode=getGraphNode(graph,ref.file);if(!importerNode)continue;let importerKey=normalizeGraphPath(importerNode.filePath);if(visited.has(importerKey))continue;if(visited.add(importerKey),depth===0)direct.add(ref.file);else transitive.add(ref.file);if(depthReached=Math.max(depthReached,depth+1),depth+1<maxDepth)next.push({key:importerKey,depth:depth+1})}}queue=next}let totalDependents=direct.size+transitive.size;return{target:targets,directDependents:[...direct].sort(),transitiveDependents:[...transitive].sort(),depthReached,totalDependents,riskLevel:classifyRisk(totalDependents)}}function classifyRisk(count){if(count<=3)return"low";if(count<=10)return"medium";if(count<=25)return"high";return"critical"}function getKeyFiles(graph,topN=10){let reverse=getReverseIndex(graph),scored=Object.values(graph.nodes).map((node)=>({node,inDegree:reverse.get(normalizeGraphPath(node.filePath))?.length??0}));return scored.sort((a,b)=>{if(b.inDegree!==a.inDegree)return b.inDegree-a.inDegree;return a.node.moduleName.localeCompare(b.node.moduleName)}),scored.slice(0,topN).map((item)=>item.node)}function getFileOntology(graph,filePath){return getGraphNode(graph,filePath)?.ontology??null}function getLocalizationContext(graph,filePath,options={}){let target=toModuleName2(graph,filePath),node=getGraphNode(graph,target),importers=getImporters(graph,target),dependencies=getDependencies(graph,target),blast=getBlastRadius(graph,[target],options.maxDepth??2),externalSymbols=collectExternallyUsedSymbols(graph,node),summary=formatLocalizationSummary({target,importers,dependencies,blast,externalSymbols,ontology:node?.ontology??null,maxImporters:options.maxImporters??5,maxDeps:options.maxDeps??5});return{target,importerCount:importers.length,importers:importers.slice(0,options.maxImporters??5),dependencyCount:dependencies.length,dependencies:dependencies.slice(0,options.maxDeps??5),exportedSymbolsUsedExternally:externalSymbols,blastRadius:blast,summary}}function getContextPack(graph,file3,symbol3,options={}){if(!isSchemaVersionAtLeast(graph.schema_version,"1.2.0"))return{schemaSupported:!1,target:{file:file3,symbol:symbol3},spans:[],truncated:!1,estimatedTokens:0,note:'rebuild with repo_map action="build"'};let maxDepth=options.maxDepth??2,maxTokens=options.maxTokens??4000,targetNode=getGraphNode(graph,file3);if(!targetNode)return{schemaSupported:!0,target:{file:file3,symbol:symbol3},spans:[],truncated:!1,estimatedTokens:0,note:"Target file not found in graph"};let targetFile=normalizeGraphPath(targetNode.filePath),forward=new Map,reverse=new Map,symbolEdges=graph.symbolEdges??[];for(let edge of symbolEdges){let fromKey=`${normalizeGraphPath(edge.fromFile)}\x00${edge.fromSymbol}`,toKey=`${normalizeGraphPath(edge.toFile)}\x00${edge.toSymbol}`,fromEdges=forward.get(fromKey);if(fromEdges)fromEdges.push(edge);else forward.set(fromKey,[edge]);let toEdges=reverse.get(toKey);if(toEdges)toEdges.push(edge);else reverse.set(toKey,[edge])}let targetKey=`${targetFile}\x00${symbol3}`,visited=new Map,queue=[{key:targetKey,depth:0}];visited.set(targetKey,0);let reached=[],queueHead=0;while(queueHead<queue.length){let{key,depth}=queue[queueHead];queueHead++;let[curFile,curSymbol]=key.split("\x00",2);if(reached.push({file:curFile,symbol:curSymbol,depth}),depth>=maxDepth)continue;let outEdges=forward.get(key)??[];for(let edge of outEdges){let nextKey=`${normalizeGraphPath(edge.toFile)}\x00${edge.toSymbol}`;if(!visited.has(nextKey))visited.set(nextKey,depth+1),queue.push({key:nextKey,depth:depth+1})}let inEdges=reverse.get(key)??[];for(let edge of inEdges){let nextKey=`${normalizeGraphPath(edge.fromFile)}\x00${edge.fromSymbol}`;if(!visited.has(nextKey))visited.set(nextKey,depth+1),queue.push({key:nextKey,depth:depth+1})}}let TOKENS_PER_LINE=12,TOKENS_PER_SIGNATURE=10,spansWithDepth=[];for(let{file:symFile,symbol:sym,depth:d}of reached){let range=graph.nodes[symFile]?.exportRanges?.[sym];if(!range){spansWithDepth.push({span:{file:symFile,symbol:sym,startLine:1,endLine:1,mode:"signature",note:"internal symbol — span unavailable"},depth:d});continue}let mode=d===0?"full":d<maxDepth?"full":"signature";spansWithDepth.push({span:{file:symFile,symbol:sym,startLine:range.startLine,endLine:range.endLine,mode},depth:d})}spansWithDepth.sort((a,b)=>{let aIsTarget=a.span.file===targetFile&&a.span.symbol===symbol3?0:1,bIsTarget=b.span.file===targetFile&&b.span.symbol===symbol3?0:1;if(aIsTarget!==bIsTarget)return aIsTarget-bIsTarget;if(a.depth!==b.depth)return a.depth-b.depth;let fileCmp=a.span.file.localeCompare(b.span.file);if(fileCmp!==0)return fileCmp;return a.span.symbol.localeCompare(b.span.symbol)});let includeSource=options.includeSource??!1,directory=options.directory??graph.workspaceRoot,MAX_SOURCE_LINES=80,estimatedTokens=0,finalSpans=[],truncated=!1;for(let{span}of spansWithDepth){let spanTokens=span.mode==="full"?(span.endLine-span.startLine+1)*TOKENS_PER_LINE:TOKENS_PER_SIGNATURE;if(finalSpans.length>0&&estimatedTokens+spanTokens>maxTokens){truncated=!0;break}if(includeSource&&!span.note&&span.mode==="full"){let absPath=path219.isAbsolute(span.file)?span.file:path219.resolve(directory,span.file),resolved=path219.resolve(absPath),resolvedDir=path219.resolve(directory);if(resolved.startsWith(resolvedDir+path219.sep)||resolved===resolvedDir)try{let lines=fs120.readFileSync(resolved,"utf-8").split(`
6196
+ `)out+=ch;i+=1}break}}return out}function parseFileImports(rawContent,sourceFile,workspaceRoot){let ext=sourceFile?path216.extname(sourceFile).toLowerCase():"";if(ext===".py"||ext===".pyw")return parsePythonFileImports(rawContent,sourceFile);if(ext===".rs")return parseRustFileImports(rawContent,sourceFile,workspaceRoot);if(ext===".go")return parseGoFileImports(rawContent);let imports=[],content=stripComments2(rawContent),importRegex=/import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`\0\t\r\n]+)['"`]|import\s+['"`]([^'"`\0\t\r\n]+)['"`]|require\s*\(\s*['"`]([^'"`\0\t\r\n]+)['"`]\s*\)|export\s*\{[^}]*\}\s*from\s+['"`]([^'"`\0\t\r\n]+)['"`]|export\s+\*(?:\s+as\s+\w+)?\s+from\s+['"`]([^'"`\0\t\r\n]+)['"`]|import\s*\(\s*['"`]([^'"`\0\t\r\n]+)['"`]\s*\)/g;for(let match of content.matchAll(importRegex)){let modulePath=match[1]||match[2]||match[3]||match[4]||match[5]||match[6];if(!modulePath)continue;if(containsControlChars(modulePath))continue;let matchedString=match[0],importType="named";if(matchedString.includes("* as"))importType="namespace";else if(/^import\s*\(/.test(matchedString))importType="sideeffect";else if(/^export\s*\{/.test(matchedString))importType="named";else if(/^export\s+\*/.test(matchedString))importType="namespace";else if(/^import\s+\{/.test(matchedString))importType="named";else if(/^import\s+\w+\s+from\s+['"`]/.test(matchedString))importType="default";else if(/^import\s+['"`]/m.test(matchedString))importType="sideeffect";else if(matchedString.includes("require("))importType="require";imports.push({specifier:modulePath,importType,importedSymbols:parseImportedSymbols(matchedString,importType),bindings:parseImportBindings(matchedString,importType),reExport:/^\s*export\b/.test(matchedString)})}return imports}function makeParsedImport(specifier,importType,bindings,reExport=!1){if(!specifier||containsControlChars(specifier))return null;return{specifier,importType,importedSymbols:bindings.map((binding)=>binding.imported),bindings,reExport}}function parsePythonFileImports(rawContent,sourceFile){let imports=[],isPackageInit=sourceFile?["__init__.py","__init__.pyw"].includes(path216.basename(sourceFile)):!1;for(let line of rawContent.split(/\r?\n/)){let trimmed=line.trim();if(!trimmed||trimmed.startsWith("#"))continue;let fullImport=trimmed.match(/^import\s+(.+?)(?:\s*#.*)?$/);if(fullImport){for(let rawPart of fullImport[1].split(",")){let part=rawPart.trim();if(!part)continue;let alias=part.match(/^([\w.]+)\s+as\s+(\w+)$/),specifier=alias?alias[1]:part,local=alias?alias[2]:specifier.split(".")[0];if(!/^\w+$/.test(local))continue;let parsed2=makeParsedImport(specifier,"namespace",[{imported:specifier,local}]);if(parsed2)imports.push(parsed2)}continue}let fromImport=trimmed.match(/^from\s+(\S+)\s+import\s+(.+?)(?:\s*#.*)?$/);if(!fromImport)continue;if(fromImport[2].trim()==="*"){let parsed2=makeParsedImport(normalizePythonModuleSpecifier2(fromImport[1]),"namespace",[],isPackageInit);if(parsed2)imports.push(parsed2);continue}let bindings=[];for(let rawPart of fromImport[2].split(",")){let part=rawPart.trim();if(!part)continue;let alias=part.match(/^(\w+)\s+as\s+(\w+)$/);if(alias)bindings.push({imported:alias[1],local:alias[2]});else if(/^\w+$/.test(part))bindings.push({imported:part,local:part})}let parsed=makeParsedImport(normalizePythonModuleSpecifier2(fromImport[1]),"named",bindings,isPackageInit);if(parsed)imports.push(parsed)}return imports}function normalizePythonModuleSpecifier2(specifier){let leadingDots=specifier.match(/^\.+/)?.[0].length??0;if(leadingDots===0)return specifier;let rest=specifier.slice(leadingDots).replace(/\./g,"/");return`${leadingDots===1?"./":"../".repeat(leadingDots-1)}${rest}`}function rustModulePathToSpecifier(modulePath,sourceFile,workspaceRoot){let parts=modulePath.split("::").filter(Boolean);if(parts.length===0)return modulePath;if(parts[0]==="self")return`./${parts.slice(1).join("/")}`;if(parts[0]==="super"){let superCount=0;while(parts[superCount]==="super")superCount++;return`${"../".repeat(superCount)}${parts.slice(superCount).join("/")}`}if(parts[0]==="crate"&&sourceFile&&workspaceRoot){let target=path216.join(workspaceRoot,...parts.slice(1)),relative47=path216.relative(path216.dirname(sourceFile),target).replace(/\\/g,"/");if(!relative47.startsWith("."))relative47=`./${relative47}`;return relative47}return modulePath}function parseRustFileImports(rawContent,sourceFile,workspaceRoot){let imports=[];for(let line of rawContent.split(/\r?\n/)){let trimmed=line.trim();if(!trimmed.startsWith("use "))continue;let grouped=trimmed.match(/^use\s+(.+?)::\{(.+)\}\s*;?\s*$/);if(grouped){let specifier2=rustModulePathToSpecifier(grouped[1].trim(),sourceFile,workspaceRoot),bindings=[];for(let rawPart of grouped[2].split(",")){let part=rawPart.trim();if(!part)continue;let alias2=part.match(/^(\w+)\s+as\s+(\w+)$/);if(alias2)bindings.push({imported:alias2[1],local:alias2[2]});else if(/^\w+$/.test(part)){let local2=part==="self"?grouped[1].split("::").pop()||grouped[1]:part;bindings.push({imported:part,local:local2})}}let parsed2=makeParsedImport(specifier2,"named",bindings);if(parsed2)imports.push(parsed2);continue}let simple=trimmed.match(/^use\s+(.+?)\s*;?\s*$/);if(!simple)continue;let rawPath=simple[1].trim(),alias=rawPath.match(/^(.+?)\s+as\s+(\w+)$/),fullPath=(alias?alias[1]:rawPath).trim(),parts=fullPath.split("::").filter(Boolean),imported=parts.pop()??fullPath,specifier=rustModulePathToSpecifier(parts.join("::")||fullPath,sourceFile,workspaceRoot),local=alias?alias[2]:imported,parsed=makeParsedImport(specifier,"named",/^\w+$/.test(imported)&&/^\w+$/.test(local)?[{imported,local}]:[]);if(parsed)imports.push(parsed)}return imports}function parseGoFileImports(rawContent){let imports=[],content=stripComments2(rawContent),parseSpec=(text)=>{let spec=text.trim();if(!spec)return;let aliased=spec.match(/^([\w._]+)\s+["`]([^"`]+)["`]$/);if(aliased){if(aliased[1]==="_"){let parsed2=makeParsedImport(aliased[2],"sideeffect",[]);if(parsed2)imports.push(parsed2);return}if(aliased[1]==="."){let parsed2=makeParsedImport(aliased[2],"namespace",[{imported:"*",local:"."}]);if(parsed2)imports.push(parsed2);return}let parsed=makeParsedImport(aliased[2],"named",[{imported:aliased[2],local:aliased[1]}]);if(parsed)imports.push(parsed);return}let simple=spec.match(/^["`]([^"`]+)["`]$/);if(simple){let parsed=makeParsedImport(simple[1],"namespace",[]);if(parsed)imports.push(parsed)}};for(let block of content.matchAll(/import\s*\(([\s\S]*?)\)/g))for(let line of block[1].split(/\r?\n/))parseSpec(line);let withoutBlocks=content.replace(/import\s*\([\s\S]*?\)/g,"");for(let match of withoutBlocks.matchAll(/^\s*import\s+(.+)$/gm))parseSpec(match[1]);return imports}function parseImportBindings(matchedString,importType){if(importType==="namespace")return[];if(importType==="default"){let defaultMatch=matchedString.match(/^import\s+(\w+)\s+from\s+['"`]/);return defaultMatch?[{imported:"default",local:defaultMatch[1]}]:[]}if(importType!=="named")return[];let braceMatch=matchedString.match(/\{\s*([\s\S]*?)\s*\}/);if(!braceMatch)return[];let bindings=[],seen=new Set;for(let rawPart of braceMatch[1].split(",")){let part=rawPart.trim().replace(/^type\s+/,"");if(!part)continue;let aliasSplit=part.split(/\s+as\s+/i),imported=aliasSplit[0].trim(),local=(aliasSplit[1]??aliasSplit[0]).trim();if(!/^[A-Za-z_$][\w$]*$/.test(imported))continue;if(!/^[A-Za-z_$][\w$]*$/.test(local))continue;if(seen.has(imported))continue;seen.add(imported),bindings.push({imported,local})}return bindings}var SAFE_USAGE_IDENTIFIER=/^[A-Za-z_][A-Za-z0-9_]*$/;function computeUsedSymbols(strippedContent,bindings){if(bindings.length===0)return[];let used=new Set;for(let binding of bindings){if(!SAFE_USAGE_IDENTIFIER.test(binding.local)){used.add(binding.imported);continue}let re=new RegExp(`\\b${binding.local}\\b`,"g"),count=0;for(let _match of strippedContent.matchAll(re))if(count++,count>1)break;if(count>1)used.add(binding.imported)}return[...used].sort((a,b)=>a.localeCompare(b))}function usedSymbolsForImport(parsed,strippedContent){if(parsed.importType==="namespace"||parsed.importType==="sideeffect"||parsed.importType==="require")return;if(parsed.reExport)return[...new Set(parsed.bindings.map((b)=>b.imported))].sort((a,b)=>a.localeCompare(b));return computeUsedSymbols(strippedContent,parsed.bindings)}function collectExports(symbols2){let exported=symbols2.filter((s)=>s.exported),exports=exported.map((s)=>s.signature===`default ${s.name}`?"default":s.name),exportLines={};for(let i=0;i<exported.length;i++){let s=exported[i],name=exports[i];if(typeof s.line==="number"&&Number.isFinite(s.line)&&exportLines[name]===void 0)exportLines[name]=s.line}return{exports,exportLines}}function parseImportedSymbols(matchedString,importType){if(importType==="namespace")return["*"];if(importType==="default")return matchedString.match(/^import\s+(\w+)\s+from\s+['"`]/)?["default"]:[];if(importType!=="named")return[];let braceMatch=matchedString.match(/\{\s*([\s\S]*?)\s*\}/);if(!braceMatch)return[];let symbols2=new Set;for(let rawPart of braceMatch[1].split(",")){let part=rawPart.trim();if(!part)continue;let cleaned=part.replace(/^type\s+/,"").split(/\s+as\s+/i)[0].trim();if(/^[A-Za-z_$][\w$]*$/.test(cleaned))symbols2.add(cleaned)}return[...symbols2].sort((a,b)=>a.localeCompare(b))}var MANIFEST_BASENAMES=new Set(["package.json","Cargo.toml","pyproject.toml","go.mod"]);function isGraphWideInputPath(filePath){return MANIFEST_BASENAMES.has(path216.basename(filePath))}function recordManifestDir(manifestDirs,absoluteRoot,dir,entryName){if(!MANIFEST_BASENAMES.has(entryName))return;let rel=path216.relative(absoluteRoot,dir).split(path216.sep).join("/");if(rel.startsWith("./"))rel=rel.slice(2);manifestDirs.add(rel)}function isWalkBudgetExceeded(ctx){if(ctx.abortReason!==void 0)return!0;if(_internals162.now()-ctx.startedAt>ctx.walkBudgetMs)return ctx.abortReason="budget",!0;return!1}function isFileCapReached(ctx,filesLength){if(filesLength>=ctx.maxFiles)return ctx.abortReason="cap",!0;return!1}async function canonicalDirKeyAsync(dir){try{return await fsPromises6.realpath(dir)}catch{return null}}async function walkRepoGraphInputs(dir,options){let absoluteRoot=path216.resolve(dir),stats2={filesScanned:0,skippedDirs:0,skippedFiles:0,truncated:!1,_absoluteRoot:absoluteRoot},ctx={stats:stats2,seenRealPaths:new Set,startedAt:_internals162.now(),walkBudgetMs:options?.walkBudgetMs??DEFAULT_WALK_BUDGET_MS,maxFiles:options?.maxFiles??DEFAULT_WALK_FILE_CAP,followSymlinks:options?.followSymlinks??!1,skipDirs:resolveSkipDirectories(options?.excludeDirs),manifestDirs:new Set,manifestWitnesses:[]},files=[],manifestFiles=[],metadata=[],unreadableDirectories=[],unreadableFiles=[],queue=[absoluteRoot],processed=0;while(queue.length>0){if(isWalkBudgetExceeded(ctx)||isFileCapReached(ctx,files.length))break;let current=queue.shift(),key=await canonicalDirKeyAsync(current);if(key!==null){if(ctx.seenRealPaths.has(key)){ctx.stats.skippedDirs++;continue}ctx.seenRealPaths.add(key)}else unreadableDirectories.push(current);let entries;try{entries=await fsPromises6.readdir(current,{withFileTypes:!0})}catch{unreadableDirectories.push(current);continue}entries.sort((a,b)=>a.name.toLowerCase().localeCompare(b.name.toLowerCase()));let absoluteRoot2=ctx.stats._absoluteRoot;for(let entry of entries){if(isWalkBudgetExceeded(ctx)||isFileCapReached(ctx,files.length))break;if(ctx.skipDirs.has(entry.name)){ctx.stats.skippedDirs++;continue}let fullPath=path216.join(current,entry.name);if(entry.isSymbolicLink()&&!ctx.followSymlinks){ctx.stats.skippedDirs++;continue}if(entry.isDirectory())queue.push(fullPath);else if(entry.isFile()){if(absoluteRoot2!==void 0)recordManifestDir(ctx.manifestDirs,absoluteRoot2,current,entry.name);let ext=path216.extname(fullPath).toLowerCase(),isSource=SUPPORTED_EXTENSIONS.has(ext),isManifest=isGraphWideInputPath(fullPath);if(isSource)files.push(fullPath);if(isManifest)manifestFiles.push(fullPath);if(options?.captureMetadata&&(isSource||isManifest)||options?.captureManifestMetadata&&isManifest)try{let fileStats=await fsPromises6.stat(fullPath);metadata.push({absolutePath:fullPath,kind:isManifest?"manifest":"source",sizeBytes:fileStats.size,mtimeMs:fileStats.mtimeMs})}catch{unreadableFiles.push(fullPath)}}if(processed++,processed%ASYNC_WALK_YIELD_INTERVAL===0)await yieldToEventLoop()}}if(ctx.abortReason==="cap"||ctx.abortReason==="budget")ctx.stats.truncated=!0;return{sourceFiles:files,manifestFiles,metadata,manifestDirs:ctx.manifestDirs,truncated:stats2.truncated,truncationReason:ctx.abortReason,incomplete:stats2.truncated||unreadableDirectories.length>0||unreadableFiles.length>0,unreadableDirectories,unreadableFiles,probedFiles:metadata.length,elapsedMs:Math.max(0,_internals162.now()-ctx.startedAt)}}function toModuleName(filePath,workspaceRoot){return path216.relative(workspaceRoot,filePath).split(path216.sep).join("/")}function getLanguage(filePath){let ext=path216.extname(filePath).toLowerCase(),jsFamilyLanguage=JS_FAMILY_EXTENSION_TO_LANGUAGE[ext];if(jsFamilyLanguage)return jsFamilyLanguage;return EXTENSION_TO_LANGUAGE[ext]??"unknown"}function isBinaryContent(content){if(content.includes("\x00"))return!0;return!1}function scanFile(filePath,absoluteRoot,maxFileSize,hasManifest){let content,fileStats;try{if(fileStats=fsSync12.statSync(filePath),fileStats.size>maxFileSize)return{node:null,edges:[]};content=fsSync12.readFileSync(filePath,"utf-8")}catch{return{node:null,edges:[]}}if(isBinaryContent(content))return{node:null,edges:[]};let ext=path216.extname(filePath).toLowerCase(),exports=[],exportLines={};try{if([".ts",".tsx",".js",".jsx",".mjs",".cjs"].includes(ext)){let relativePath2=path216.relative(absoluteRoot,filePath);({exports,exportLines}=collectExports(_internals162.extractTSSymbols(relativePath2,absoluteRoot)))}else if(ext===".py"||ext===".pyw"){let relativePath2=path216.relative(absoluteRoot,filePath);({exports,exportLines}=collectExports(_internals162.extractPythonSymbols(relativePath2,absoluteRoot)))}else if(ext===".rs"){let relativePath2=path216.relative(absoluteRoot,filePath);({exports,exportLines}=collectExports(_internals162.extractRustSymbols(relativePath2,absoluteRoot)))}else if(ext===".go"){let relativePath2=path216.relative(absoluteRoot,filePath);({exports,exportLines}=collectExports(_internals162.extractGoSymbols(relativePath2,absoluteRoot)))}let parsedImports=_internals162.parseFileImports(content,filePath,absoluteRoot),strippedForUsage=parsedImports.length>0?_internals162.stripComments(content):"",moduleName=toModuleName(filePath,absoluteRoot),node={filePath,moduleName,exports,...Object.keys(exportLines).length>0?{exportLines}:{},imports:parsedImports.map((p)=>p.specifier),language:getLanguage(filePath),mtime:fileStats.mtime.toISOString(),sizeBytes:fileStats.size,mtimeMs:fileStats.mtimeMs,ontology:_internals162.extractFileOntology({moduleName,filePath,content,language:getLanguage(filePath),exports,imports:parsedImports.map((p)=>p.specifier),hasManifest})},edges=[],sortedImports=[...parsedImports].sort((a,b)=>a.specifier.localeCompare(b.specifier));for(let parsed of sortedImports){let resolvedTarget=resolveModuleSpecifier(absoluteRoot,filePath,parsed.specifier);if(resolvedTarget!==null){let usedSymbols=usedSymbolsForImport(parsed,strippedForUsage);edges.push({source:filePath,target:resolvedTarget,importSpecifier:parsed.specifier,importType:parsed.importType,importedSymbols:parsed.importedSymbols,...usedSymbols!==void 0?{usedSymbols}:{},targetKind:isScannableSourcePath(resolvedTarget)?"node":"asset"})}}return{node,edges}}catch{return{node:null,edges:[]}}}async function scanFileAsync(filePath,absoluteRoot,maxFileSize,hasManifest){let content,fileStats;try{if(fileStats=await fsPromises6.stat(filePath),fileStats.size>maxFileSize){let moduleName2=toModuleName(filePath,absoluteRoot);return{node:null,edges:[],symbolEdges:[],diagnostics:{oversizedFiles:[moduleName2]},inputWitness:{file:moduleName2,kind:"stable-skip",sizeBytes:fileStats.size,mtimeMs:fileStats.mtimeMs}}}content=await fsPromises6.readFile(filePath,"utf-8")}catch{return{node:null,edges:[],symbolEdges:[],diagnostics:{unreadableFiles:[toModuleName(filePath,absoluteRoot)]}}}if(isBinaryContent(content)){let moduleName2=toModuleName(filePath,absoluteRoot);return{node:null,edges:[],symbolEdges:[],diagnostics:{binaryFiles:[moduleName2]},inputWitness:{file:moduleName2,kind:"stable-skip",sizeBytes:fileStats.size,mtimeMs:fileStats.mtimeMs}}}let grammarId=getLanguage(filePath),facts=await _internals162.extractFileSymbols(grammarId,content);if(facts===null){let fallback=scanFile(filePath,absoluteRoot,maxFileSize,hasManifest),parsedImports=[];try{parsedImports=_internals162.parseFileImports(content,filePath,absoluteRoot)}catch{parsedImports=[]}return{...fallback,symbolEdges:[],diagnostics:{extractionFailures:[{file:toModuleName(filePath,absoluteRoot),language:grammarId,reason:"symbol_extraction_failed"}],unresolvedImports:unresolvedRelativeImportsFor(parsedImports,filePath,absoluteRoot)}}}let exportedDefs=facts.defs.filter((d)=>d.exported),exports=exportedDefs.map((d)=>d.name),exportLines={},exportRanges={};for(let d of exportedDefs)exportLines[d.name]=d.startLine,exportRanges[d.name]={startLine:d.startLine,endLine:d.endLine};let exportsSet=new Set(exports),isPythonPackageInit=grammarId==="python"&&["__init__.py","__init__.pyw"].includes(path216.basename(filePath));for(let imp of facts.imports){let packageInitBindings=isPythonPackageInit&&imp.bindings.length>0?imp.bindings.filter((binding)=>!binding.local.startsWith("_")).map((binding)=>({imported:binding.imported,exported:binding.local})):[],exportedBindings=imp.reExport&&imp.exportedBindings?imp.exportedBindings:packageInitBindings;if(exportedBindings.length===0)continue;for(let binding of exportedBindings){if(binding.imported==="*"){if(!exportsSet.has(binding.exported))exportsSet.add(binding.exported),exports.push(binding.exported);if(imp.startLine!==void 0&&exportLines[binding.exported]===void 0)exportLines[binding.exported]=imp.startLine;if(imp.startLine!==void 0&&imp.endLine!==void 0&&exportRanges[binding.exported]===void 0)exportRanges[binding.exported]={startLine:imp.startLine,endLine:imp.endLine};continue}if(!exportsSet.has(binding.exported))exportsSet.add(binding.exported),exports.push(binding.exported);if(imp.startLine!==void 0&&exportLines[binding.exported]===void 0)exportLines[binding.exported]=imp.startLine;if(imp.startLine!==void 0&&imp.endLine!==void 0&&exportRanges[binding.exported]===void 0)exportRanges[binding.exported]={startLine:imp.startLine,endLine:imp.endLine}}}let imports=facts.imports.map((i)=>i.specifier),moduleName=toModuleName(filePath,absoluteRoot),language=grammarId,node={filePath,moduleName,exports,...Object.keys(exportLines).length>0?{exportLines}:{},...Object.keys(exportRanges).length>0?{exportRanges}:{},imports,language,mtime:fileStats.mtime.toISOString(),sizeBytes:fileStats.size,mtimeMs:fileStats.mtimeMs,ontology:_internals162.extractFileOntology({moduleName,filePath,content,language,exports,imports,hasManifest})},edges=[],sortedImports=[...facts.imports].sort((a,b)=>a.specifier.localeCompare(b.specifier));for(let imp of sortedImports){let edgeImportType=imp.importType==="commonjs"?"require":imp.importType,resolvedTarget=resolveModuleSpecifier(absoluteRoot,filePath,imp.specifier);if(resolvedTarget!==null){let usedBindings=imp.reExport?imp.bindings:imp.bindings.filter((b)=>facts.refs.some((r)=>r.identifier===b.local)),usedSymbols=edgeImportType!=="namespace"&&edgeImportType!=="require"&&edgeImportType!=="sideeffect"?usedBindings.map((b)=>b.imported):void 0;edges.push({source:filePath,target:resolvedTarget,importSpecifier:imp.specifier,importType:edgeImportType,importedSymbols:imp.bindings.map((b)=>b.imported),...usedSymbols!==void 0?{usedSymbols}:{},targetKind:isScannableSourcePath(resolvedTarget)?"node":"asset"})}}let unresolvedImports=sortedImports.filter((imp)=>isRelativeImportSpecifier(imp.specifier)).filter((imp)=>resolveModuleSpecifier(absoluteRoot,filePath,imp.specifier)===null).map((imp)=>({file:moduleName,specifier:imp.specifier})),symbolEdges=[],localToImported=new Map;for(let imp of facts.imports){if(imp.reExport)continue;for(let binding of imp.bindings)localToImported.set(binding.local,{specifier:imp.specifier,imported:binding.imported})}let seenSymbolEdgeKeys=new Set;for(let ref of facts.refs){let mapping=localToImported.get(ref.identifier);if(!mapping)continue;let resolvedTarget=resolveModuleSpecifier(absoluteRoot,filePath,mapping.specifier);if(!resolvedTarget)continue;let fromSymbol=ref.enclosingDecl??"<module>",key=filePath+"\x00"+fromSymbol+"\x00"+resolvedTarget+"\x00"+mapping.imported;if(seenSymbolEdgeKeys.has(key))continue;seenSymbolEdgeKeys.add(key),symbolEdges.push({fromFile:filePath,fromSymbol,toFile:resolvedTarget,toSymbol:mapping.imported})}for(let imp of facts.imports){let packageInitBindings=isPythonPackageInit&&imp.bindings.length>0?imp.bindings.filter((binding)=>!binding.local.startsWith("_")).map((binding)=>({imported:binding.imported,exported:binding.local})):[],exportedBindings=imp.reExport&&imp.exportedBindings?imp.exportedBindings:packageInitBindings;if(exportedBindings.length===0)continue;let resolvedTarget=resolveModuleSpecifier(absoluteRoot,filePath,imp.specifier);if(!resolvedTarget)continue;for(let binding of exportedBindings){if(binding.imported==="*")continue;let key=filePath+"\x00"+binding.exported+"\x00"+resolvedTarget+"\x00"+binding.imported;if(seenSymbolEdgeKeys.has(key))continue;seenSymbolEdgeKeys.add(key),symbolEdges.push({fromFile:filePath,fromSymbol:binding.exported,toFile:resolvedTarget,toSymbol:binding.imported})}}return{node,edges,symbolEdges,diagnostics:unresolvedImports.length>0?{unresolvedImports}:void 0}}async function buildWorkspaceGraphAsync(workspaceRoot,options){validateWorkspace(workspaceRoot);let maxFileSize=options?.maxFileSizeBytes??1048576,maxFiles=options?.maxFiles??DEFAULT_WALK_FILE_CAP,walkBudgetMs=options?.walkBudgetMs??DEFAULT_WALK_BUDGET_MS,followSymlinks=options?.followSymlinks??!1,absoluteRoot=path216.resolve(workspaceRoot);if(!existsSync110(absoluteRoot))throw Error(`Workspace directory does not exist: ${workspaceRoot}`);if(isRefusedWorkspaceRoot(absoluteRoot))throw Error(`Refusing to scan top-level system path as workspace: ${absoluteRoot}. Set workspaceRoot to a project directory.`);let graph=createEmptyGraph(workspaceRoot),stats2={filesScanned:0,skippedDirs:0,skippedFiles:0,truncated:!1,_absoluteRoot:absoluteRoot},diagnostics=createEmptyDiagnostics(),walked=await walkRepoGraphInputs(absoluteRoot,{walkBudgetMs,maxFiles,followSymlinks,excludeDirs:options?.excludeDirs,captureManifestMetadata:!0}),sourceFiles=walked.sourceFiles;stats2.truncated=walked.truncated;for(let input of walked.metadata){if(input.kind!=="manifest")continue;let relative47=toModuleName(input.absolutePath,absoluteRoot);pushInputWitness(diagnostics.extractorInputWitnesses,{file:relative47,kind:"manifest",sizeBytes:input.sizeBytes,mtimeMs:input.mtimeMs})}if(sourceFiles.sort((a,b)=>{let normA=normalizeGraphPath(a),normB=normalizeGraphPath(b);return normA.localeCompare(normB)}),stats2.truncated)warn(`[repo-graph] Walk truncated: collected ${sourceFiles.length} files within ${walkBudgetMs}ms / ${maxFiles}-file budget.`);let hasManifest=(relDir)=>walked.manifestDirs.has(relDir),seenEdges=new Set,seenSymbolEdges=new Set,allSymbolEdges=[],processedSinceYield=0;for(let filePath of sourceFiles){let result=await scanFileAsync(filePath,absoluteRoot,maxFileSize,hasManifest);if(mergeDiagnostics(diagnostics,result.diagnostics),result.inputWitness)pushInputWitness(diagnostics.extractorInputWitnesses,result.inputWitness);if(result.node){let appended=!1;try{appendNodeFast(graph,result.node),appended=!0}catch{stats2.skippedFiles++,pushCapped(diagnostics.validationSkippedFiles,result.node.moduleName),pushInputWitness(diagnostics.extractorInputWitnesses,{file:result.node.moduleName,kind:"stable-skip",sizeBytes:result.node.sizeBytes,mtimeMs:result.node.mtimeMs})}if(appended){for(let edge of result.edges)try{appendEdgeFast(graph,edge,seenEdges)}catch{}for(let symbolEdge of result.symbolEdges){let key=symbolEdge.fromFile+"\x00"+symbolEdge.fromSymbol+"\x00"+symbolEdge.toFile+"\x00"+symbolEdge.toSymbol;if(!seenSymbolEdges.has(key))seenSymbolEdges.add(key),allSymbolEdges.push(symbolEdge)}stats2.filesScanned++}}else stats2.skippedFiles++;if(processedSinceYield++,processedSinceYield%ASYNC_SCAN_YIELD_INTERVAL===0)await yieldToEventLoop()}if(graph.metadata={generatedAt:new Date().toISOString(),generator:"repo-graph",nodeCount:Object.keys(graph.nodes).length,edgeCount:graph.edges.length},allSymbolEdges.length>0)graph.symbolEdges=allSymbolEdges;if(diagnostics.walkTruncated=stats2.truncated,diagnostics.walkTruncationReason=walked.truncationReason,graph.diagnostics=diagnosticsHaveEntries(diagnostics)?diagnostics:createEmptyDiagnostics(),stats2.skippedFiles>0||stats2.skippedDirs>0||stats2.truncated)log(`[repo-graph] Scan stats: ${stats2.filesScanned} files scanned, ${stats2.skippedFiles} files skipped, ${stats2.skippedDirs} dirs skipped`+(stats2.truncated?", TRUNCATED":""));return graph}var DEFAULT_TOP_N=8,MAX_TOP_N=25,ALPHA=0.25,MAX_ITERATIONS=25,CONVERGENCE_THRESHOLD=0.000001,FIELD_WEIGHTS={moduleName:3,exports:2,imports:1},TEST_PATH_FACTOR=0.35,TEST_PATH_RE=/(?:^|[/\\])(?:tests?|__tests?__|spec|__spec__|__mocks?__)[/\\]|\.(?:test|spec|stories)\./i;function tokenize2(text){let raw=text.replace(/[^a-zA-Z0-9_]/g," ").split(/\s+/).filter((t)=>t.length>1),expanded=[];for(let token of raw){expanded.push(token.toLowerCase());for(let sub of splitCompound(token)){let lower=sub.toLowerCase();if(lower!==token.toLowerCase())expanded.push(lower)}}return[...new Set(expanded)]}function splitCompound(token){let parts=[],camel=token.replace(/([a-z])([A-Z])/g,"$1 $2").split(/\s+/);if(camel.length>1){for(let p of camel)if(p.length>1)parts.push(p)}let snake=token.split("_");if(snake.length>1){for(let p of snake)if(p.length>1)parts.push(p)}return parts}function buildVocabulary(graph){let vocab=new Set;for(let node of Object.values(graph.nodes)){for(let sub of splitCompound(node.moduleName))vocab.add(sub.toLowerCase());let baseName=node.moduleName.replace(/^.*[/\\]/,"").replace(/\.[^.]+$/,"");vocab.add(baseName.toLowerCase());for(let seg of node.moduleName.split(/[/\\]/))if(seg.length>1)vocab.add(seg.toLowerCase());for(let exp of node.exports){vocab.add(exp.toLowerCase());for(let sub of splitCompound(exp))vocab.add(sub.toLowerCase())}}let nodes=Object.values(graph.nodes),distinctRoles=new Set;for(let node of nodes)if(node.ontology)for(let role of node.ontology.roles)distinctRoles.add(role.toLowerCase());for(let r of distinctRoles)if(!vocab.has(r)&&wouldScore(r,nodes))vocab.add(r);return vocab}function wouldScore(term,nodes){for(let node of nodes)if(node.moduleName.toLowerCase().includes(term)||node.exports.some((e)=>e.toLowerCase().includes(term))||node.imports.some((i)=>i.toLowerCase().includes(term)))return!0;return!1}function expandTerms(tokens,vocab){let expanded=new Set;for(let token of tokens){if(vocab.has(token))expanded.add(token);for(let sub of splitCompound(token)){let lower=sub.toLowerCase();if(vocab.has(lower))expanded.add(lower)}}return[...expanded].sort()}function computeIDF(term,nodes){let docFreq=0,lower=term.toLowerCase();for(let node of nodes){let moduleLower=node.moduleName.toLowerCase(),baseName=moduleLower.replace(/^.*[/\\]/,"").replace(/\.[^.]+$/,"");if(moduleLower.includes(lower)||baseName===lower||node.exports.some((e)=>e.toLowerCase().includes(lower))||node.imports.some((i)=>i.toLowerCase().includes(lower)))docFreq++}if(docFreq===0)return 0;return Math.log((nodes.length+1)/(docFreq+1))+1}function lexicalScore(node,terms,idfMap){let score=0,matched=[],moduleLower=node.moduleName.toLowerCase(),baseName=moduleLower.replace(/^.*[/\\]/,"").replace(/\.[^.]+$/,"");for(let term of terms){let idf=idfMap.get(term)??0;if(idf===0)continue;let termScore=0;if(moduleLower.includes(term)||baseName===term)termScore+=FIELD_WEIGHTS.moduleName*idf;if(node.exports.some((e)=>e.toLowerCase().includes(term)))termScore+=FIELD_WEIGHTS.exports*idf;if(node.imports.some((i)=>i.toLowerCase().includes(term)))termScore+=FIELD_WEIGHTS.imports*idf;if(termScore>0)score+=termScore,matched.push(term)}if(TEST_PATH_RE.test(node.moduleName))score*=TEST_PATH_FACTOR;return{score,matchedTerms:matched}}function buildUndirectedAdjacency(graph,nodeKeys){let adj=new Map;for(let key of nodeKeys)adj.set(key,new Set);for(let edge of graph.edges){if(isAssetEdge(edge))continue;let s=normalizeGraphPath(edge.source),t=normalizeGraphPath(edge.target);if(adj.has(s)&&adj.has(t))adj.get(s).add(t),adj.get(t).add(s)}return adj}function personalizedPageRank(adj,restart,nodeKeys){let n=nodeKeys.length;if(n===0)return new Map;let scores=new Map;for(let key of nodeKeys)scores.set(key,restart.get(key)??0);for(let iter=0;iter<MAX_ITERATIONS;iter++){let next=new Map;for(let key of nodeKeys)next.set(key,0);let danglingMass=0;for(let key of nodeKeys){let neighbors=adj.get(key);if(!neighbors||neighbors.size===0)danglingMass+=scores.get(key)??0;else{let share=(scores.get(key)??0)/neighbors.size;for(let neighbor of neighbors)next.set(neighbor,(next.get(neighbor)??0)+share)}}let danglingShare=danglingMass/n,l1Delta=0;for(let key of nodeKeys){let damped=(1-ALPHA)*(restart.get(key)??0)+ALPHA*((next.get(key)??0)+danglingShare);l1Delta+=Math.abs(damped-(scores.get(key)??0)),next.set(key,damped)}if(scores=next,l1Delta<CONVERGENCE_THRESHOLD)break}return scores}function askGraph(graph,question,options={}){let topN=Math.min(options.topN??DEFAULT_TOP_N,MAX_TOP_N),nodes=Object.values(graph.nodes),nodeKeys=Object.keys(graph.nodes).sort();if(!question.trim()||nodes.length===0)return{hits:[],expandedTerms:[],budget:{requested:topN,returned:0,dropped:0}};let vocab=buildVocabulary(graph),rawTokens=tokenize2(question),expandedTerms=expandTerms(rawTokens,vocab);if(expandedTerms.length===0)return{hits:[],expandedTerms:[],budget:{requested:topN,returned:0,dropped:0}};let idfMap=new Map;for(let term of expandedTerms)idfMap.set(term,computeIDF(term,nodes));let lexScores=new Map,totalLexScore=0;for(let key of nodeKeys){let node=graph.nodes[key],result=lexicalScore(node,expandedTerms,idfMap);lexScores.set(key,result),totalLexScore+=result.score}let restart=new Map;if(totalLexScore>0)for(let key of nodeKeys)restart.set(key,(lexScores.get(key)?.score??0)/totalLexScore);else{let uniform=1/nodeKeys.length;for(let key of nodeKeys)restart.set(key,uniform)}let adj=buildUndirectedAdjacency(graph,nodeKeys),prScores=personalizedPageRank(adj,restart,nodeKeys),scored=[];for(let key of nodeKeys){let pr=prScores.get(key)??0,lex=lexScores.get(key);if(pr>0||lex&&lex.score>0)scored.push({key,score:Math.round(pr*1e6)/1e6,matchedTerms:lex?.matchedTerms??[]})}scored.sort((a,b)=>{if(b.score!==a.score)return b.score-a.score;return a.key.localeCompare(b.key)});let total=scored.length,hits=scored.slice(0,topN).map(({key,score,matchedTerms})=>{let node=graph.nodes[key];return{file:node.moduleName,score,matchedTerms,topExports:node.exports.slice(0,5),role:node.ontology?.roles[0]??"source_module",community:node.ontology?.packageBoundary??inferPackageBoundary(node.moduleName)}});return{hits,expandedTerms,budget:{requested:topN,returned:hits.length,dropped:Math.max(0,total-topN)}}}import*as path217 from"node:path";var MAX_CACHED_WORKSPACES=16,workspaceCache=new Map;function normalizeWorkspace(workspace){let resolved=path217.normalize(path217.resolve(workspace));return process.platform==="win32"?resolved.toLowerCase():resolved}function touch(key,entry){return workspaceCache.delete(key),workspaceCache.set(key,entry),entry}function getEntry(workspace){let key=normalizeWorkspace(workspace),entry=workspaceCache.get(key);return entry?touch(key,entry):void 0}function setEntry(workspace,entry){let key=normalizeWorkspace(workspace);touch(key,entry);while(workspaceCache.size>MAX_CACHED_WORKSPACES){let oldestKey=workspaceCache.keys().next().value;if(oldestKey===void 0)break;workspaceCache.delete(oldestKey)}}function getCachedGraph(workspace){return getEntry(workspace)?.graph}function setCachedGraph(workspace,graph,mtime){setEntry(workspace,{graph,dirty:!1,...mtime===void 0?{}:{mtime}})}function isDirty(workspace){return getEntry(workspace)?.dirty??!1}function clearCache(workspace){workspaceCache.delete(normalizeWorkspace(workspace))}function getCachedMtime(workspace){return getEntry(workspace)?.mtime}init_package();init_utils2();init_bun_compat();init_path_security();import{createHash as createHash48}from"node:crypto";import*as fsPromises7 from"node:fs/promises";import*as path218 from"node:path";var REPO_GRAPH_FINGERPRINT_FILENAME="repo-graph.fingerprint.json",FINGERPRINT_SCHEMA_VERSION=1,EXTRACTOR_STAMP=createHash48("sha256").update(`${package_default.version}\x00${GRAPH_SCHEMA_VERSION}`).digest("hex"),DEFAULT_WALK_BUDGET_MS2=5000,DEFAULT_MAX_FILES=1e4,CACHE_TTL_MS3=30000,MAX_CACHE_ENTRIES4=16,MAX_FINGERPRINT_BYTES=25165824,MAX_FINGERPRINT_ENTRIES=100256,MAX_RELATIVE_PATH_LENGTH=4096,WINDOWS_RENAME_MAX_RETRIES4=5,WINDOWS_RENAME_RETRY_DELAY_MS2=100,probeCache=new Map,_internals163={now:Date.now,walkRepoGraphInputs,open:fsPromises7.open,bunWrite,fsRename:fsPromises7.rename,fsUnlink:fsPromises7.unlink,retryDelayMs:WINDOWS_RENAME_RETRY_DELAY_MS2};function normalizeRoot(root){let resolved=path218.normalize(path218.resolve(root));return process.platform==="win32"?resolved.toLowerCase():resolved}function normalizedExcludes(options){return[...new Set((options?.excludeDirs??[]).filter(Boolean))].sort((a,b)=>a.localeCompare(b))}function exclusionStamp(options){return createHash48("sha256").update(JSON.stringify({excludeDirs:normalizedExcludes(options),followSymlinks:options?.followSymlinks??!1})).digest("hex")}function optionSignature(options){return JSON.stringify({walkBudgetMs:options?.walkBudgetMs??DEFAULT_WALK_BUDGET_MS2,maxFiles:options?.maxFiles??DEFAULT_MAX_FILES,followSymlinks:options?.followSymlinks??!1,excludeDirs:normalizedExcludes(options)})}function touchCache(rootKey,entry){probeCache.delete(rootKey),probeCache.set(rootKey,entry);while(probeCache.size>MAX_CACHE_ENTRIES4){let oldest=probeCache.keys().next().value;if(oldest===void 0)break;probeCache.delete(oldest)}}function invalidateFreshnessCache(root){if(root===void 0){probeCache.clear();return}probeCache.delete(normalizeRoot(root))}function fingerprintPath(root){let target=validateSwarmPath(root,REPO_GRAPH_FINGERPRINT_FILENAME);return validateSymlinkBoundary(target,root),target}async function writeFingerprintAtomic(root,data){let target=fingerprintPath(root),temp=path218.join(path218.dirname(target),`.repo-graph.fingerprint.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2,10)}.tmp`);validateSymlinkBoundary(temp,root);try{await _internals163.bunWrite(temp,data);let lastError;for(let attempt=0;attempt<WINDOWS_RENAME_MAX_RETRIES4;attempt++)try{await _internals163.fsRename(temp,target),lastError=void 0;break}catch(error93){lastError=error93;let code=error93.code;if(code!=="EEXIST"&&code!=="EPERM"&&code!=="EBUSY"||attempt===WINDOWS_RENAME_MAX_RETRIES4-1)break;await new Promise((resolve86)=>setTimeout(resolve86,_internals163.retryDelayMs))}if(lastError!==void 0)throw lastError}finally{try{await _internals163.fsUnlink(temp)}catch{}}}async function refuseFingerprint(root){try{await _internals163.fsUnlink(fingerprintPath(root))}catch{}return invalidateFreshnessCache(root),!1}function safeRelativePath(value){if(value.length===0||value.length>MAX_RELATIVE_PATH_LENGTH||containsControlChars(value)||path218.isAbsolute(value)||/^[A-Za-z]:[/\\]/.test(value))return null;let normalized=value.replace(/\\/g,"/").replace(/^(?:\.\/)+/,"");if(normalized.length===0||normalized.split("/").some((segment)=>segment===".."||segment===""))return null;return normalized}function relativeFromRoot(root,absolutePath2){let relative48=path218.relative(path218.resolve(root),path218.resolve(absolutePath2));if(relative48.startsWith("..")||path218.isAbsolute(relative48))return null;return safeRelativePath(relative48)}function absoluteFromRelative(root,relativePath2){let safe=safeRelativePath(relativePath2);if(safe===null)return null;let resolvedRoot=path218.resolve(root),absolute=path218.resolve(resolvedRoot,safe),relative48=path218.relative(resolvedRoot,absolute);if(relative48.startsWith("..")||path218.isAbsolute(relative48))return null;return absolute}function validMetadata(value){if(!value||typeof value!=="object"||Array.isArray(value))return!1;let record3=value;return Object.keys(record3).length===2&&typeof record3.size==="number"&&Number.isFinite(record3.size)&&record3.size>=0&&typeof record3.mtimeMs==="number"&&Number.isFinite(record3.mtimeMs)&&record3.mtimeMs>=0}function parseFingerprint(value,options){if(!value||typeof value!=="object"||Array.isArray(value))return null;let record3=value;if(Object.keys(record3).sort().join(",")!=="exclusionStamp,extractorStamp,files,schema_version"||record3.schema_version!==FINGERPRINT_SCHEMA_VERSION||record3.extractorStamp!==EXTRACTOR_STAMP||record3.exclusionStamp!==exclusionStamp(options)||!record3.files||typeof record3.files!=="object"||Array.isArray(record3.files))return null;let rawFiles=record3.files,entries=Object.entries(rawFiles);if(entries.length>MAX_FINGERPRINT_ENTRIES)return null;let files=Object.create(null);for(let[rawPath,metadata]of entries){let safe=safeRelativePath(rawPath);if(safe===null||safe!==rawPath||!validMetadata(metadata))return null;files[safe]=metadata}return{schema_version:FINGERPRINT_SCHEMA_VERSION,extractorStamp:EXTRACTOR_STAMP,exclusionStamp:exclusionStamp(options),files}}function emptyProbe(state,elapsedMs){return{state,changed:[],removed:[],truncated:!1,probedFiles:0,elapsedMs:Math.max(0,elapsedMs)}}async function readFingerprint(root,options){let target=fingerprintPath(root),handle=await _internals163.open(target,"r");try{let stats2=await handle.stat();if(stats2.size>MAX_FINGERPRINT_BYTES)return null;let buffer=Buffer.alloc(stats2.size),offset=0;while(offset<buffer.length){let read=await handle.read(buffer,offset,buffer.length-offset,offset);if(read.bytesRead===0)break;offset+=read.bytesRead}let data=buffer.subarray(0,offset).toString("utf8");return parseFingerprint(JSON.parse(data),options)}finally{await handle.close()}}async function probeUncached(root,options){let startedAt=_internals163.now(),fingerprint2;try{fingerprint2=await readFingerprint(root,options)}catch{fingerprint2=null}if(fingerprint2===null)return emptyProbe("no-fingerprint",_internals163.now()-startedAt);let walk;try{walk=await _internals163.walkRepoGraphInputs(root,{walkBudgetMs:options?.walkBudgetMs,maxFiles:options?.maxFiles,followSymlinks:options?.followSymlinks,excludeDirs:options?.excludeDirs,captureMetadata:!0})}catch{return{...emptyProbe("inconclusive",_internals163.now()-startedAt),truncated:!1}}let current=new Map,changed2=[];for(let input of walk.metadata){let relative48=relativeFromRoot(root,input.absolutePath);if(relative48===null)continue;let metadata={size:input.sizeBytes,mtimeMs:input.mtimeMs};current.set(relative48,metadata);let previous=fingerprint2.files[relative48];if(previous===void 0||previous.size!==metadata.size||previous.mtimeMs!==metadata.mtimeMs)changed2.push(path218.resolve(input.absolutePath))}let incomplete=walk.incomplete,removed=[];if(!incomplete){for(let relative48 of Object.keys(fingerprint2.files))if(!current.has(relative48)){let absolute=absoluteFromRelative(root,relative48);if(absolute!==null)removed.push(absolute)}}return changed2.sort((a,b)=>a.localeCompare(b)),removed.sort((a,b)=>a.localeCompare(b)),{state:incomplete?"inconclusive":changed2.length>0||removed.length>0?"drifted":"clean",changed:changed2,removed:incomplete?[]:removed,truncated:walk.truncated,probedFiles:walk.probedFiles,elapsedMs:Math.max(0,_internals163.now()-startedAt)}}async function probeFreshness(root,options){let rootKey=normalizeRoot(root),signature=optionSignature(options),now2=_internals163.now(),cached3=probeCache.get(rootKey);if(cached3?.signature===signature){if(cached3.value&&cached3.expiresAt>now2)return touchCache(rootKey,cached3),cached3.value;if(cached3.inFlight)return touchCache(rootKey,cached3),cached3.inFlight}let inFlight=probeUncached(root,options),entry={signature,expiresAt:0,inFlight};touchCache(rootKey,entry);try{let value=await inFlight;if(probeCache.get(rootKey)?.inFlight===inFlight)entry.value=value,entry.expiresAt=_internals163.now()+CACHE_TTL_MS3,entry.inFlight=void 0,touchCache(rootKey,entry);return value}catch{if(probeCache.get(rootKey)?.inFlight===inFlight)probeCache.delete(rootKey);return emptyProbe("inconclusive",0)}}function diagnosticPaths(root,diagnostics){let reportedStable=new Set;for(let raw of[...diagnostics?.oversizedFiles??[],...diagnostics?.binaryFiles??[],...diagnostics?.validationSkippedFiles??[]]){let safe=safeRelativePath(raw);if(safe===null)return null;if(absoluteFromRelative(root,safe)===null)return null;reportedStable.add(safe)}let witnesses=new Map,stable=new Set;for(let witness of diagnostics?.extractorInputWitnesses??[]){let safe=safeRelativePath(witness.file);if(safe===null||witness.kind!=="manifest"&&witness.kind!=="stable-skip"||!Number.isFinite(witness.sizeBytes)||witness.sizeBytes<0||!Number.isFinite(witness.mtimeMs)||witness.mtimeMs<0||witnesses.has(safe))return null;if(witnesses.set(safe,{...witness,file:safe}),witness.kind==="stable-skip")stable.add(safe)}for(let relative48 of reportedStable)if(witnesses.get(relative48)?.kind!=="stable-skip")return null;return{stable,witnesses}}async function writeFingerprint(root,graph,options){invalidateFreshnessCache(root);try{let walk=await _internals163.walkRepoGraphInputs(root,{walkBudgetMs:options?.walkBudgetMs,maxFiles:options?.maxFiles,followSymlinks:options?.followSymlinks,excludeDirs:options?.excludeDirs,captureMetadata:!0});if(walk.unreadableDirectories.length>0||walk.unreadableFiles.length>0)return refuseFingerprint(root);let certifiedInputs=diagnosticPaths(root,graph.diagnostics);if(certifiedInputs===null)return refuseFingerprint(root);let current=new Map;for(let input of walk.metadata){let relative48=relativeFromRoot(root,input.absolutePath);if(relative48===null)return refuseFingerprint(root);current.set(relative48,{size:input.sizeBytes,mtimeMs:input.mtimeMs})}for(let[relative48,witness]of certifiedInputs.witnesses){let observed=current.get(relative48);if(observed===void 0||observed.size!==witness.sizeBytes||observed.mtimeMs!==witness.mtimeMs)return refuseFingerprint(root)}let nodePaths=new Set;for(let node of Object.values(graph.nodes)){let relative48=relativeFromRoot(root,node.filePath);if(relative48===null)return refuseFingerprint(root);if(typeof node.sizeBytes!=="number"||!Number.isFinite(node.sizeBytes)||node.sizeBytes<0||typeof node.mtimeMs!=="number"||!Number.isFinite(node.mtimeMs)||node.mtimeMs<0)return refuseFingerprint(root);let observed=current.get(relative48);if(observed===void 0||observed.size!==node.sizeBytes||observed.mtimeMs!==node.mtimeMs)return refuseFingerprint(root);nodePaths.add(relative48)}for(let input of walk.metadata){let relative48=relativeFromRoot(root,input.absolutePath);if(relative48===null)return refuseFingerprint(root);if(input.kind==="manifest"&&certifiedInputs.witnesses.get(relative48)?.kind!=="manifest")return refuseFingerprint(root);if(input.kind!=="source")continue;if(!nodePaths.has(relative48)&&!certifiedInputs.stable.has(relative48))return refuseFingerprint(root)}let files=Object.create(null);for(let relative48 of[...current.keys()].sort((a,b)=>a.localeCompare(b)))files[relative48]=current.get(relative48);if(Object.keys(files).length>MAX_FINGERPRINT_ENTRIES)return refuseFingerprint(root);let sidecar={schema_version:FINGERPRINT_SCHEMA_VERSION,extractorStamp:EXTRACTOR_STAMP,exclusionStamp:exclusionStamp(options),files},serialized3=`${JSON.stringify(sidecar,null,2)}
6197
+ `;if(Buffer.byteLength(serialized3,"utf8")>MAX_FINGERPRINT_BYTES)return refuseFingerprint(root);return await writeFingerprintAtomic(root,serialized3),invalidateFreshnessCache(root),!0}catch{return refuseFingerprint(root)}}init_logger();init_path_security();import{existsSync as existsSync112,readdirSync as readdirSync31}from"node:fs";import*as fsPromises9 from"node:fs/promises";import*as path221 from"node:path";init_path_security();import*as fs120 from"node:fs";import*as path219 from"node:path";var GRAPH_HEALTH_OUTPUT_LIMIT=50,MAX_HEALTH_PATH_LENGTH=500,cachedReverseIndex=null;function normalizeLookupPath(input){return normalizeGraphPath(input).replace(/^(?:\.\/)+/,"")}function graphRoot(graph){return path219.resolve(graph.workspaceRoot)}function toModuleName2(graph,input){let normalized=normalizeLookupPath(input);if(path219.isAbsolute(normalized)||/^[A-Za-z]:\//.test(normalized))return normalizeLookupPath(path219.relative(graphRoot(graph),normalized));return normalized}function absoluteKeyForModule(graph,moduleName){return normalizeGraphPath(path219.resolve(graphRoot(graph),moduleName))}function getGraphNode(graph,input){let moduleName=toModuleName2(graph,input),direct=graph.nodes[absoluteKeyForModule(graph,moduleName)];if(direct)return direct;return getQueryIndexes(graph).moduleNameIndex.get(moduleName)}function moduleNameForEdgePath(graph,edgePath){let key=normalizeGraphPath(edgePath),node=graph.nodes[key];if(node)return normalizeLookupPath(node.moduleName);return normalizeLookupPath(path219.relative(graphRoot(graph),edgePath))}function buildReverseIndex(graph){let reverse=new Map,forward=new Map,moduleNameIndex=new Map;for(let node of Object.values(graph.nodes))moduleNameIndex.set(normalizeLookupPath(node.moduleName),node);for(let edge of graph.edges){if(isAssetEdge(edge))continue;let source=normalizeGraphPath(edge.source),target=normalizeGraphPath(edge.target),sourceRef={file:moduleNameForEdgePath(graph,edge.source),importType:edge.importType},targetRef={file:moduleNameForEdgePath(graph,edge.target),importType:edge.importType},reverseRefs=reverse.get(target);if(reverseRefs)reverseRefs.push(sourceRef);else reverse.set(target,[sourceRef]);let forwardRefs=forward.get(source);if(forwardRefs)forwardRefs.push(targetRef);else forward.set(source,[targetRef])}for(let refs of reverse.values())refs.sort((a,b)=>a.file.localeCompare(b.file));for(let refs of forward.values())refs.sort((a,b)=>a.file.localeCompare(b.file));return cachedReverseIndex={graph,index:reverse,forwardIndex:forward,moduleNameIndex},reverse}function getQueryIndexes(graph){if(cachedReverseIndex&&cachedReverseIndex.graph===graph)return cachedReverseIndex;return buildReverseIndex(graph),cachedReverseIndex}function getReverseIndex(graph){return getQueryIndexes(graph).index}function getForwardIndex(graph){return getQueryIndexes(graph).forwardIndex}function resetQueryCache(){cachedReverseIndex=null}function isSafeHealthPath(value){if(typeof value!=="string")return!1;if(value.length===0||value.length>MAX_HEALTH_PATH_LENGTH)return!1;if(containsControlChars(value)||containsPathTraversal(value))return!1;if(path219.isAbsolute(value)||/^[A-Za-z]:[\\/]/.test(value))return!1;return!0}function isSafeHealthText(value){if(typeof value!=="string")return!1;if(value.length===0||value.length>MAX_HEALTH_PATH_LENGTH)return!1;if(containsControlChars(value))return!1;return!0}function cap(entries){return entries.slice(0,GRAPH_HEALTH_OUTPUT_LIMIT)}function sanitizeExtractionFailures(value){if(!Array.isArray(value))return[];let entries=[];for(let raw of value){if(!raw||typeof raw!=="object")continue;let entry=raw;if(isSafeHealthPath(entry.file)&&isSafeHealthText(entry.language)&&isSafeHealthText(entry.reason))entries.push({file:entry.file,language:entry.language,reason:entry.reason})}return cap(entries)}function sanitizeUnresolvedImports(value){if(!Array.isArray(value))return[];let entries=[];for(let raw of value){if(!raw||typeof raw!=="object")continue;let entry=raw;if(isSafeHealthPath(entry.file)&&isSafeHealthText(entry.specifier))entries.push({file:entry.file,specifier:entry.specifier})}return cap(entries)}function sanitizePathList(value){if(!Array.isArray(value))return[];return cap(value.filter(isSafeHealthPath))}function getProbeStaleFiles(probe2,workspaceRoot){if(!probe2)return[];let root=path219.resolve(workspaceRoot),stale=new Set;for(let absolutePath2 of[...probe2.changed,...probe2.removed]){if(typeof absolutePath2!=="string"||!path219.isAbsolute(absolutePath2))continue;let relative49=normalizeGraphPath(path219.relative(root,absolutePath2));if(!isSafeHealthPath(relative49))continue;stale.add(relative49)}return[...stale].sort((a,b)=>a.localeCompare(b)).slice(0,GRAPH_HEALTH_OUTPUT_LIMIT)}function getGraphHealth(graph,workspaceRoot,probe2){let probeState=probe2?.state??"no-fingerprint";if(!graph)return{schemaVersion:null,fresh:!1,probeState,staleFiles:[],extractionFailures:[],unresolvedImports:[],oversizedFiles:[],unsupportedFiles:[],binaryFiles:[],unreadableFiles:[],validationSkippedFiles:[],lowConfidenceEdgeCount:0,walkTruncated:!1,walkTruncationReason:null,incrementalFallbacks:0,notes:['No repo graph found at .swarm/repo-graph.json. Run repo_map with action="build" first.']};let diagnostics=graph.diagnostics,fresh=probeState==="clean",staleFiles=getProbeStaleFiles(probe2,workspaceRoot??graph.workspaceRoot),notes=[];if(probeState==="drifted")notes.push('Graph content is stale relative to the workspace. Run repo_map with action="build" if automatic refresh is unavailable.');else if(probeState==="no-fingerprint")notes.push('Graph has no matching content fingerprint. Run repo_map with action="build" to certify it.');else if(probeState==="inconclusive")notes.push("Graph freshness is unknown because the bounded workspace probe did not complete; no refresh or deletion was attempted.");if(!diagnostics)notes.push('Graph has no recorded diagnostics. Rebuild with repo_map action="build" to collect health details.');let binaryFiles=sanitizePathList(diagnostics?.binaryFiles),binaryCount=binaryFiles.length;if(binaryCount>0)notes.push(`${binaryCount} binary files skipped during last build.`);let unreadableFiles=sanitizePathList(diagnostics?.unreadableFiles),unreadableCount=unreadableFiles.length;if(unreadableCount>0)notes.push(`${unreadableCount} unreadable files skipped during last build.`);let walkTruncated=diagnostics?.walkTruncated===!0,rawReason=diagnostics?.walkTruncationReason,walkTruncationReason=rawReason==="budget"||rawReason==="cap"?rawReason:null,incrementalFallbacks=typeof diagnostics?.incrementalFallbacks==="number"&&Number.isFinite(diagnostics.incrementalFallbacks)&&diagnostics.incrementalFallbacks>0?Math.floor(diagnostics.incrementalFallbacks):0;if(walkTruncated)notes.push("Graph is INCOMPLETE: walk hit the file-cap/wall-clock budget — results may be missing files."+(walkTruncationReason?` (reason: ${walkTruncationReason})`:""));if(incrementalFallbacks>0)notes.push(`${incrementalFallbacks} incremental update(s) fell back to a full rebuild (validation failure or concurrent modification).`);return{schemaVersion:graph.schema_version,fresh,probeState,staleFiles,extractionFailures:sanitizeExtractionFailures(diagnostics?.extractionFailures),unresolvedImports:sanitizeUnresolvedImports(diagnostics?.unresolvedImports),oversizedFiles:sanitizePathList(diagnostics?.oversizedFiles),unsupportedFiles:sanitizePathList(diagnostics?.unsupportedFiles),binaryFiles,unreadableFiles,validationSkippedFiles:sanitizePathList(diagnostics?.validationSkippedFiles),lowConfidenceEdgeCount:typeof diagnostics?.lowConfidenceEdgeCount==="number"&&Number.isFinite(diagnostics.lowConfidenceEdgeCount)&&diagnostics.lowConfidenceEdgeCount>0?Math.floor(diagnostics.lowConfidenceEdgeCount):0,walkTruncated,walkTruncationReason,incrementalFallbacks,notes}}function getImporters(graph,filePath){let node=getGraphNode(graph,filePath);if(!node)return[];return getReverseIndex(graph).get(normalizeGraphPath(node.filePath))??[]}function getDependencies(graph,filePath){let node=getGraphNode(graph,filePath);if(!node)return[];let sourceKey=normalizeGraphPath(node.filePath);return getForwardIndex(graph).get(sourceKey)??[]}function getSymbolConsumers(graph,filePath,symbolName){let node=getGraphNode(graph,filePath);if(!node)return[];let targetKey=normalizeGraphPath(node.filePath),refs=[];for(let edge of graph.edges){if(isAssetEdge(edge))continue;if(normalizeGraphPath(edge.target)!==targetKey)continue;let importedSymbols=edge.importedSymbols??[];if(edge.importType==="namespace"){refs.push({file:moduleNameForEdgePath(graph,edge.source),importedAs:"*"});continue}if(importedSymbols.includes(symbolName))refs.push({file:moduleNameForEdgePath(graph,edge.source),importedAs:symbolName})}return refs.sort((a,b)=>a.file.localeCompare(b.file)),refs}function getCallers(graph,filePath,symbolName){let node=getGraphNode(graph,filePath);if(!node)return[];let targetKey=normalizeGraphPath(node.filePath),refs=[],seen=new Set;for(let edge of graph.edges){if(isAssetEdge(edge))continue;if(normalizeGraphPath(edge.target)!==targetKey)continue;let file3=moduleNameForEdgePath(graph,edge.source);if(seen.has(file3))continue;if(edge.usedSymbols!==void 0){if(edge.usedSymbols.includes(symbolName))seen.add(file3),refs.push({file:file3,resolution:"used"});continue}let imported=edge.importedSymbols??[];if(edge.importType==="namespace"||imported.includes(symbolName))seen.add(file3),refs.push({file:file3,resolution:"imported"})}return refs.sort((a,b)=>a.file.localeCompare(b.file)),refs}var DEAD_EXPORT_EXCLUDED_ROLES=new Set(["api_route","cli_command","test_file","agent","hook","middleware"]);function getDeadExports(graph,options){if(!isSchemaVersionAtLeast(graph.schema_version,"1.1.0"))return{schemaSupported:!1,analyzedFiles:0,skippedUnresolvable:0,candidates:[],note:'Graph predates schema 1.1.0 (no usedSymbols data). Run repo_map action="build" to enable dead_exports.'};let usage=new Map;for(let edge of graph.edges){if(isAssetEdge(edge))continue;let target=normalizeGraphPath(edge.target),entry=usage.get(target);if(!entry)entry={used:new Set,unresolvable:!1},usage.set(target,entry);if(edge.importType==="namespace"||edge.importType==="sideeffect"||edge.importType==="require")entry.unresolvable=!0;else if(edge.usedSymbols)for(let symbol3 of edge.usedSymbols)entry.used.add(symbol3)}let reverse=getReverseIndex(graph),candidates=[],analyzedFiles=0,skippedUnresolvable=0;for(let node of Object.values(graph.nodes)){if(node.exports.length===0)continue;let key=normalizeGraphPath(node.filePath),importerCount=reverse.get(key)?.length??0;if(importerCount===0)continue;if((node.ontology?.roles??[]).some((r)=>DEAD_EXPORT_EXCLUDED_ROLES.has(r)))continue;let entry=usage.get(key);if(entry?.unresolvable){skippedUnresolvable++;continue}analyzedFiles++;let used=entry?.used??new Set;for(let symbol3 of node.exports){if(symbol3==="default")continue;if(used.has(symbol3))continue;candidates.push({file:node.moduleName,symbol:symbol3,line:node.exportLines?.[symbol3],importerCount})}}candidates.sort((a,b)=>a.file.localeCompare(b.file)||a.symbol.localeCompare(b.symbol));let limit=options?.maxCandidates??100,truncated=candidates.length>limit;return{schemaSupported:!0,analyzedFiles,skippedUnresolvable,candidates:candidates.slice(0,limit),note:"Advisory: exported symbols with no detected in-repo reference, limited to files imported by >=1 other file. Regex analysis cannot see dynamic dispatch, string-keyed access, or namespace/barrel re-export usage; verify before removing."+(truncated?` Showing ${limit} of ${candidates.length}.`:"")}}function getBlastRadius(graph,filePaths,maxDepth=3){let targetNodes=filePaths.map((filePath)=>getGraphNode(graph,filePath)).filter((node)=>node!==void 0),targets=targetNodes.map((node)=>normalizeLookupPath(node.moduleName));if(maxDepth<=0||targetNodes.length===0)return{target:filePaths.map((filePath)=>toModuleName2(graph,filePath)),directDependents:[],transitiveDependents:[],depthReached:0,totalDependents:0,riskLevel:"low"};let reverse=getReverseIndex(graph),visited=new Set(targetNodes.map((node)=>normalizeGraphPath(node.filePath))),direct=new Set,transitive=new Set,depthReached=0,queue=targetNodes.map((node)=>({key:normalizeGraphPath(node.filePath),depth:0}));while(queue.length>0){let next=[];for(let{key,depth}of queue){let importers=reverse.get(key)??[];for(let ref of importers){let importerNode=getGraphNode(graph,ref.file);if(!importerNode)continue;let importerKey=normalizeGraphPath(importerNode.filePath);if(visited.has(importerKey))continue;if(visited.add(importerKey),depth===0)direct.add(ref.file);else transitive.add(ref.file);if(depthReached=Math.max(depthReached,depth+1),depth+1<maxDepth)next.push({key:importerKey,depth:depth+1})}}queue=next}let totalDependents=direct.size+transitive.size;return{target:targets,directDependents:[...direct].sort(),transitiveDependents:[...transitive].sort(),depthReached,totalDependents,riskLevel:classifyRisk(totalDependents)}}function classifyRisk(count){if(count<=3)return"low";if(count<=10)return"medium";if(count<=25)return"high";return"critical"}function getKeyFiles(graph,topN=10){let reverse=getReverseIndex(graph),scored=Object.values(graph.nodes).map((node)=>({node,inDegree:reverse.get(normalizeGraphPath(node.filePath))?.length??0}));return scored.sort((a,b)=>{if(b.inDegree!==a.inDegree)return b.inDegree-a.inDegree;return a.node.moduleName.localeCompare(b.node.moduleName)}),scored.slice(0,topN).map((item)=>item.node)}function getFileOntology(graph,filePath){return getGraphNode(graph,filePath)?.ontology??null}function getLocalizationContext(graph,filePath,options={}){let target=toModuleName2(graph,filePath),node=getGraphNode(graph,target),importers=getImporters(graph,target),dependencies=getDependencies(graph,target),blast=getBlastRadius(graph,[target],options.maxDepth??2),externalSymbols=collectExternallyUsedSymbols(graph,node),summary=formatLocalizationSummary({target,importers,dependencies,blast,externalSymbols,ontology:node?.ontology??null,maxImporters:options.maxImporters??5,maxDeps:options.maxDeps??5});return{target,importerCount:importers.length,importers:importers.slice(0,options.maxImporters??5),dependencyCount:dependencies.length,dependencies:dependencies.slice(0,options.maxDeps??5),exportedSymbolsUsedExternally:externalSymbols,blastRadius:blast,summary}}function getContextPack(graph,file3,symbol3,options={}){if(!isSchemaVersionAtLeast(graph.schema_version,"1.2.0"))return{schemaSupported:!1,target:{file:file3,symbol:symbol3},spans:[],truncated:!1,estimatedTokens:0,note:'rebuild with repo_map action="build"'};let maxDepth=options.maxDepth??2,maxTokens=options.maxTokens??4000,targetNode=getGraphNode(graph,file3);if(!targetNode)return{schemaSupported:!0,target:{file:file3,symbol:symbol3},spans:[],truncated:!1,estimatedTokens:0,note:"Target file not found in graph"};let targetFile=normalizeGraphPath(targetNode.filePath),forward=new Map,reverse=new Map,symbolEdges=graph.symbolEdges??[];for(let edge of symbolEdges){let fromKey=`${normalizeGraphPath(edge.fromFile)}\x00${edge.fromSymbol}`,toKey=`${normalizeGraphPath(edge.toFile)}\x00${edge.toSymbol}`,fromEdges=forward.get(fromKey);if(fromEdges)fromEdges.push(edge);else forward.set(fromKey,[edge]);let toEdges=reverse.get(toKey);if(toEdges)toEdges.push(edge);else reverse.set(toKey,[edge])}let targetKey=`${targetFile}\x00${symbol3}`,visited=new Map,queue=[{key:targetKey,depth:0}];visited.set(targetKey,0);let reached=[],queueHead=0;while(queueHead<queue.length){let{key,depth}=queue[queueHead];queueHead++;let[curFile,curSymbol]=key.split("\x00",2);if(reached.push({file:curFile,symbol:curSymbol,depth}),depth>=maxDepth)continue;let outEdges=forward.get(key)??[];for(let edge of outEdges){let nextKey=`${normalizeGraphPath(edge.toFile)}\x00${edge.toSymbol}`;if(!visited.has(nextKey))visited.set(nextKey,depth+1),queue.push({key:nextKey,depth:depth+1})}let inEdges=reverse.get(key)??[];for(let edge of inEdges){let nextKey=`${normalizeGraphPath(edge.fromFile)}\x00${edge.fromSymbol}`;if(!visited.has(nextKey))visited.set(nextKey,depth+1),queue.push({key:nextKey,depth:depth+1})}}let TOKENS_PER_LINE=12,TOKENS_PER_SIGNATURE=10,spansWithDepth=[];for(let{file:symFile,symbol:sym,depth:d}of reached){let range=graph.nodes[symFile]?.exportRanges?.[sym];if(!range){spansWithDepth.push({span:{file:symFile,symbol:sym,startLine:1,endLine:1,mode:"signature",note:"internal symbol — span unavailable"},depth:d});continue}let mode=d===0?"full":d<maxDepth?"full":"signature";spansWithDepth.push({span:{file:symFile,symbol:sym,startLine:range.startLine,endLine:range.endLine,mode},depth:d})}spansWithDepth.sort((a,b)=>{let aIsTarget=a.span.file===targetFile&&a.span.symbol===symbol3?0:1,bIsTarget=b.span.file===targetFile&&b.span.symbol===symbol3?0:1;if(aIsTarget!==bIsTarget)return aIsTarget-bIsTarget;if(a.depth!==b.depth)return a.depth-b.depth;let fileCmp=a.span.file.localeCompare(b.span.file);if(fileCmp!==0)return fileCmp;return a.span.symbol.localeCompare(b.span.symbol)});let includeSource=options.includeSource??!1,directory=options.directory??graph.workspaceRoot,MAX_SOURCE_LINES=80,estimatedTokens=0,finalSpans=[],truncated=!1;for(let{span}of spansWithDepth){let spanTokens=span.mode==="full"?(span.endLine-span.startLine+1)*TOKENS_PER_LINE:TOKENS_PER_SIGNATURE;if(finalSpans.length>0&&estimatedTokens+spanTokens>maxTokens){truncated=!0;break}if(includeSource&&!span.note&&span.mode==="full"){let absPath=path219.isAbsolute(span.file)?span.file:path219.resolve(directory,span.file),resolved=path219.resolve(absPath),resolvedDir=path219.resolve(directory);if(resolved.startsWith(resolvedDir+path219.sep)||resolved===resolvedDir)try{let lines=fs120.readFileSync(resolved,"utf-8").split(`
6191
6198
  `),start=Math.max(0,span.startLine-1),end=Math.min(lines.length,span.startLine-1+MAX_SOURCE_LINES,span.endLine),slice=lines.slice(start,end);span.text=slice.join(`
6192
6199
  `),spanTokens=slice.length*TOKENS_PER_LINE}catch{span.note="source read failed"}}finalSpans.push(span),estimatedTokens+=spanTokens}let result={schemaSupported:!0,target:{file:targetFile,symbol:symbol3},spans:finalSpans,truncated,estimatedTokens};if(includeSource)result.sourceIncluded=!0;return result}function collectExternallyUsedSymbols(graph,node){if(!node)return[];let exported=new Set(node.exports),used=new Set,targetKey=normalizeGraphPath(node.filePath);for(let edge of graph.edges){if(isAssetEdge(edge))continue;if(normalizeGraphPath(edge.target)!==targetKey)continue;for(let symbol3 of edge.importedSymbols??[])if(exported.has(symbol3))used.add(symbol3)}return[...used].sort((a,b)=>a.localeCompare(b))}function formatLocalizationSummary(opts){let importerList=opts.importers.length===0?"(none)":opts.importers.slice(0,opts.maxImporters).map((ref)=>ref.file).join(", ")+(opts.importers.length>opts.maxImporters?`, +${opts.importers.length-opts.maxImporters} more`:""),depList=opts.dependencies.length===0?"(none)":opts.dependencies.slice(0,opts.maxDeps).map((ref)=>ref.file).join(", ")+(opts.dependencies.length>opts.maxDeps?`, +${opts.dependencies.length-opts.maxDeps} more`:""),symbolList=opts.externalSymbols.length===0?"(none used externally)":opts.externalSymbols.slice(0,8).join(", ")+(opts.externalSymbols.length>8?`, +${opts.externalSymbols.length-8} more`:""),roles=opts.ontology?.roles.join(", ")||"unknown",findings=opts.ontology?.findings.length??0;return["LOCALIZATION CONTEXT",` Target: ${opts.target}`,` Roles: ${roles}`,` Imported by (${opts.importers.length}): ${importerList}`,` Imports (${opts.dependencies.length}): ${depList}`,` Exports used externally: ${symbolList}`,` Blast radius: ${opts.blast.totalDependents} files (${opts.blast.riskLevel} risk)`,` Ontology findings: ${findings}`].join(`
6193
- `)}function getPackageBoundaries(graph,topN=25){return summarizePackageBoundaries(Object.values(graph.nodes),graph.edges,topN)}function summarizePackageBoundaries(nodes,edges,topN){let groups=new Map,ensure=(node)=>{let name=node.ontology?.packageBoundary||inferBoundary(node.moduleName),group=groups.get(name);if(!group)group={name,root:name,fileCount:0,roles:{},dependsOn:[],dependedOnBy:[],routeCount:0,dataOperationCount:0,findingCount:0,publicFiles:[]},groups.set(name,group);return group},boundaryByPath=new Map;for(let node of nodes){let group=ensure(node);boundaryByPath.set(normalizeGraphPath(node.filePath),group.name),group.fileCount++;let ontology=node.ontology;for(let role of ontology?.roles??["source_module"])group.roles[role]=(group.roles[role]??0)+1;if(group.routeCount+=ontology?.routes.length??0,group.dataOperationCount+=ontology?.dataOperations.length??0,group.findingCount+=ontology?.findings.length??0,node.exports.length>0)group.publicFiles.push(node.moduleName)}let dependsOn=new Map,dependedOnBy=new Map;for(let edge of edges){if(isAssetEdge(edge))continue;let sourceBoundary=boundaryByPath.get(normalizeGraphPath(edge.source)),targetBoundary=boundaryByPath.get(normalizeGraphPath(edge.target));if(!sourceBoundary||!targetBoundary||sourceBoundary===targetBoundary)continue;if(!dependsOn.has(sourceBoundary))dependsOn.set(sourceBoundary,new Set);if(!dependedOnBy.has(targetBoundary))dependedOnBy.set(targetBoundary,new Set);dependsOn.get(sourceBoundary)?.add(targetBoundary),dependedOnBy.get(targetBoundary)?.add(sourceBoundary)}for(let group of groups.values())group.dependsOn=[...dependsOn.get(group.name)??[]].sort(),group.dependedOnBy=[...dependedOnBy.get(group.name)??[]].sort(),group.publicFiles.sort((a,b)=>a.localeCompare(b)),group.publicFiles=group.publicFiles.slice(0,20);return[...groups.values()].sort((a,b)=>{if(b.findingCount!==a.findingCount)return b.findingCount-a.findingCount;if(b.fileCount!==a.fileCount)return b.fileCount-a.fileCount;return a.name.localeCompare(b.name)}).slice(0,topN)}function summarizeSelectedPackageBoundaries(graph,nodes,topN=25){let summaries=summarizePackageBoundaries(nodes,[],topN),boundaryByModule=new Map;for(let node of nodes)boundaryByModule.set(normalizeLookupPath(node.moduleName),node.ontology?.packageBoundary??inferBoundary(node.moduleName));let byName=new Map(summaries.map((summary)=>[summary.name,summary])),dependsOn=new Map,dependedOnBy=new Map;for(let node of nodes){let sourceBoundary=boundaryByModule.get(normalizeLookupPath(node.moduleName));if(!sourceBoundary)continue;for(let dep of getDependencies(graph,node.moduleName)){let targetBoundary=boundaryByModule.get(normalizeLookupPath(dep.file));if(!targetBoundary||sourceBoundary===targetBoundary||!byName.has(sourceBoundary)||!byName.has(targetBoundary))continue;if(!dependsOn.has(sourceBoundary))dependsOn.set(sourceBoundary,new Set);if(!dependedOnBy.has(targetBoundary))dependedOnBy.set(targetBoundary,new Set);dependsOn.get(sourceBoundary)?.add(targetBoundary),dependedOnBy.get(targetBoundary)?.add(sourceBoundary)}}for(let summary of summaries)summary.dependsOn=[...dependsOn.get(summary.name)??[]].sort(),summary.dependedOnBy=[...dependedOnBy.get(summary.name)??[]].sort();return summaries}function inferBoundary(moduleName){return inferPackageBoundary(moduleName)}function buildOntologyPreflightPacket(graph,filePaths=[],options={}){let maxFiles=options.maxFiles??12,maxFindings=options.maxFindings??20,boundedNodes=(filePaths.length>0?filePaths.map((filePath)=>getGraphNode(graph,filePath)).filter((node)=>node!==void 0):getKeyFiles(graph,maxFiles)).slice(0,maxFiles),findings=boundedNodes.flatMap((node)=>(node.ontology?.findings??[]).map((finding)=>({file:node.moduleName,...finding}))).slice(0,maxFindings),routes=boundedNodes.flatMap((node)=>(node.ontology?.routes??[]).map((route)=>({file:node.moduleName,...route}))),dataOperations=boundedNodes.flatMap((node)=>(node.ontology?.dataOperations??[]).map((fact)=>({file:node.moduleName,...fact}))),security=boundedNodes.flatMap((node)=>(node.ontology?.security??[]).map((fact)=>({file:node.moduleName,...fact})));return{generatedAt:new Date().toISOString(),targets:boundedNodes.map((node)=>node.moduleName),summary:{fileCount:Object.keys(graph.nodes).length,edgeCount:graph.edges.length,targetCount:boundedNodes.length,findingCount:findings.length,routeCount:routes.length,dataOperationCount:dataOperations.length,securityFactCount:security.length},files:boundedNodes.map((node)=>({file:node.moduleName,roles:node.ontology?.roles??[],packageBoundary:node.ontology?.packageBoundary??inferBoundary(node.moduleName),importerCount:getImporters(graph,node.moduleName).length,dependencyCount:getDependencies(graph,node.moduleName).length,routeCount:node.ontology?.routes.length??0,dataOperationCount:node.ontology?.dataOperations.length??0,securityFactCount:node.ontology?.security.length??0,findingCount:node.ontology?.findings.length??0})),routes,dataOperations,security,findings,packageBoundaries:summarizeSelectedPackageBoundaries(graph,boundedNodes,options.maxBoundaries??10)}}init_utils2();init_logger();init_path_security();import{constants as constants5,existsSync as existsSync110,readFileSync as readFileSync88,statSync as statSync46}from"node:fs";import*as fsPromises8 from"node:fs/promises";import*as path220 from"node:path";var WINDOWS_RENAME_MAX_RETRIES5=5,WINDOWS_RENAME_RETRY_DELAY_MS3=100,_internals164={safeRealpathSync,fsRename:fsPromises8.rename.bind(fsPromises8),retryDelayMs:WINDOWS_RENAME_RETRY_DELAY_MS3,writeFingerprint};function validateLoadedGraph(parsed){if(!parsed.schema_version)throw Object.assign(Error("repo-graph.json missing schema_version"),{code:"CORRUPTION"});if(!parsed.nodes||typeof parsed.nodes!=="object")throw Object.assign(Error("repo-graph.json missing or invalid nodes"),{code:"CORRUPTION"});if(!Array.isArray(parsed.edges))throw Object.assign(Error("repo-graph.json missing or invalid edges"),{code:"CORRUPTION"});for(let[key,node]of Object.entries(parsed.nodes)){if(!key||typeof key!=="string")throw Object.assign(Error("repo-graph.json contains invalid node key"),{code:"CORRUPTION"});try{validateGraphNode(node)}catch(err){let msg=err instanceof Error?err.message:"Invalid node structure";throw Object.assign(Error(`repo-graph.json node validation failed: ${msg}`),{code:"CORRUPTION"})}}for(let edge of parsed.edges)try{validateGraphEdge(edge)}catch(err){let msg=err instanceof Error?err.message:"Invalid edge structure";throw Object.assign(Error(`repo-graph.json edge validation failed: ${msg}`),{code:"CORRUPTION"})}if(!parsed.metadata||typeof parsed.metadata!=="object"||typeof parsed.metadata.generatedAt!=="string"||typeof parsed.metadata.generator!=="string"||typeof parsed.metadata.nodeCount!=="number"||typeof parsed.metadata.edgeCount!=="number")throw Object.assign(Error("repo-graph.json missing or invalid metadata"),{code:"CORRUPTION"});if(parsed.symbolEdges!==void 0){if(!Array.isArray(parsed.symbolEdges))throw Object.assign(Error("repo-graph.json symbolEdges must be an array"),{code:"CORRUPTION"});for(let entry of parsed.symbolEdges)if(typeof entry!=="object"||entry===null||typeof entry.fromFile!=="string"||typeof entry.fromSymbol!=="string"||typeof entry.toFile!=="string"||typeof entry.toSymbol!=="string"||entry.fromFile===""||entry.fromSymbol===""||entry.toFile===""||entry.toSymbol===""||containsControlChars(entry.fromFile)||containsControlChars(entry.fromSymbol)||containsControlChars(entry.toFile)||containsControlChars(entry.toSymbol)||containsPathTraversal(entry.fromFile)||containsPathTraversal(entry.toFile))throw Object.assign(Error("repo-graph.json contains invalid symbolEdges entry"),{code:"CORRUPTION"})}}function getGraphPath(workspace){validateWorkspace(workspace);let basePath=validateSwarmPath(workspace,REPO_GRAPH_FILENAME);return validateSymlinkBoundary(basePath,workspace),basePath}async function loadGraph(workspace){validateWorkspace(workspace);let normalized=path220.normalize(workspace),cached3=getCachedGraph(normalized);if(cached3&&!isDirty(normalized))try{let graphPath=getGraphPath(workspace);if(existsSync110(graphPath)){let stats2=await fsPromises8.stat(graphPath),cachedMtime=getCachedMtime(normalized);if(cachedMtime!==void 0&&stats2.mtimeMs!==cachedMtime)clearCache(normalized);else return cached3}else clearCache(normalized)}catch{clearCache(normalized)}try{let graphPath=getGraphPath(workspace);if(!existsSync110(graphPath))return null;let stats2=await fsPromises8.stat(graphPath),content=await fsPromises8.readFile(graphPath,"utf-8");if(content.includes("\x00")||content.includes("�"))throw Object.assign(Error("repo-graph.json contains null bytes or invalid encoding"),{code:"CORRUPTION"});let parsed;try{parsed=JSON.parse(content)}catch{throw Object.assign(Error("repo-graph.json contains invalid JSON"),{code:"CORRUPTION"})}return validateLoadedGraph(parsed),setCachedGraph(normalized,parsed,stats2.mtimeMs),parsed}catch(error93){if(error93 instanceof Error&&"code"in error93&&error93.code==="CORRUPTION")throw error93;if(error93 instanceof Error&&"code"in error93&&error93.code==="ENOENT")return null;throw error93}}function loadGraphSync(workspace){validateWorkspace(workspace);let normalized=path220.normalize(workspace);try{let graphPath=getGraphPath(workspace);if(!existsSync110(graphPath))return null;let stats2=statSync46(graphPath),content=readFileSync88(graphPath,"utf-8");if(content.includes("\x00")||content.includes("�"))throw Object.assign(Error("repo-graph.json contains null bytes or invalid encoding"),{code:"CORRUPTION"});let parsed;try{parsed=JSON.parse(content)}catch{throw Object.assign(Error("repo-graph.json contains invalid JSON"),{code:"CORRUPTION"})}return validateLoadedGraph(parsed),setCachedGraph(normalized,parsed,stats2.mtimeMs),parsed}catch(error93){if(error93 instanceof Error&&"code"in error93&&error93.code==="ENOENT")return null;throw error93}}async function saveGraph(workspace,graph,options){if(validateWorkspace(workspace),!graph.schema_version)throw Error("Graph must have schema_version");if(!graph.nodes||typeof graph.nodes!=="object")throw Error("Graph must have nodes object");if(!Array.isArray(graph.edges))throw Error("Graph must have edges array");let normalizedWorkspace=path220.normalize(workspace),realWorkspace=_internals164.safeRealpathSync(workspace,normalizedWorkspace);if(realWorkspace===null)throw Error(`Workspace realpath security check failed (non-ENOENT): ${workspace}`);let normalizedGraphRoot=path220.normalize(graph.workspaceRoot),realGraphRoot=_internals164.safeRealpathSync(graph.workspaceRoot,normalizedGraphRoot);if(realGraphRoot===null)throw Error(`Graph workspaceRoot realpath security check failed (non-ENOENT): ${graph.workspaceRoot}`);if(path220.normalize(realWorkspace)!==path220.normalize(realGraphRoot))throw Error(`Graph workspaceRoot mismatch: graph was built for "${graph.workspaceRoot}" but save was called for "${workspace}"`);let normalized=normalizedWorkspace,graphPath=getGraphPath(workspace);updateGraphMetadata(graph);let tempPath=`${graphPath}.tmp.${Date.now()}.${Math.floor(Math.random()*1e9)}`;await fsPromises8.mkdir(path220.dirname(tempPath),{recursive:!0});let lastError=null;try{if(options?.createAtomic)try{let handle=await fsPromises8.open(tempPath,"wx",420);await handle.writeFile(JSON.stringify(graph,null,2),"utf-8"),await handle.close()}catch(error93){if(error93 instanceof Error&&"code"in error93&&error93.code==="EEXIST")throw Error("file already exists");throw error93}else await fsPromises8.writeFile(tempPath,JSON.stringify(graph,null,2),"utf-8");if(options?.createAtomic)try{await fsPromises8.copyFile(tempPath,graphPath,constants5.COPYFILE_EXCL)}catch(error93){throw lastError=error93 instanceof Error?error93:Error(String(error93)),lastError}else{for(let attempt=0;attempt<WINDOWS_RENAME_MAX_RETRIES5;attempt++)try{await _internals164.fsRename(tempPath,graphPath),lastError=null;break}catch(error93){lastError=error93 instanceof Error?error93:Error(String(error93));let code=lastError.code;if(code!=="EEXIST"&&code!=="EPERM"&&code!=="EBUSY")break;if(attempt<WINDOWS_RENAME_MAX_RETRIES5-1)await new Promise((resolve87)=>setTimeout(resolve87,_internals164.retryDelayMs))}if(lastError)throw lastError}}finally{try{await fsPromises8.unlink(tempPath)}catch(error93){if(error93 instanceof Error&&"code"in error93&&error93.code!=="ENOENT")error48(`Failed to clean up temp file ${tempPath}:`,error93)}}let stats2=await fsPromises8.stat(graphPath);setCachedGraph(normalized,graph,stats2.mtimeMs)}var _internals165={stat:(p)=>fsPromises9.stat(p),scanFileAsync,buildWorkspaceGraphAsync,saveGraph,writeFingerprint},MAX_DIAGNOSTIC_ENTRIES2=200,MANIFEST_BASENAMES2=new Set(["package.json","Cargo.toml","pyproject.toml","go.mod"]);function buildManifestClosure(graph,absoluteRoot){let dirs=new Set;for(let node of Object.values(graph.nodes)){let absDir=path221.dirname(node.filePath),rel=path221.relative(absoluteRoot,absDir).split(path221.sep).join("/");rel=rel.replace(/^(?:\.\/)+/,"");while(!0){dirs.add(rel);let idx=rel.lastIndexOf("/");if(idx<0){if(rel!=="")dirs.add("");break}rel=rel.slice(0,idx)}}let manifestDirs=new Set;for(let relDir of dirs){let absDir=relDir===""?absoluteRoot:path221.join(absoluteRoot,relDir);try{if(readdirSync31(absDir).some((name)=>MANIFEST_BASENAMES2.has(name)))manifestDirs.add(relDir)}catch{}}return(relDir)=>manifestDirs.has(relDir)}function validateFileUpdates(graph){for(let edge of graph.edges){let normalizedSource=normalizeGraphPath(edge.source);if(!graph.nodes[normalizedSource])return{validationFailed:!0,offendingEdge:edge,reason:"missing-source-node"};if(!isAssetEdge(edge)){let normalizedTarget=normalizeGraphPath(edge.target);if(!graph.nodes[normalizedTarget])return{validationFailed:!0,offendingEdge:edge,reason:"missing-target-node"}}}if(graph.symbolEdges&&graph.symbolEdges.length>0){let validSymbolEdges=[];for(let symbolEdge of graph.symbolEdges){let normalizedFromFile=normalizeGraphPath(symbolEdge.fromFile),normalizedToFile=normalizeGraphPath(symbolEdge.toFile);if(graph.nodes[normalizedFromFile]&&graph.nodes[normalizedToFile])validSymbolEdges.push(symbolEdge)}graph.symbolEdges=validSymbolEdges}return{validationFailed:!1}}function diagnosticName(filePath,absoluteRoot){return path221.relative(absoluteRoot,filePath).split(path221.sep).join("/")}function dedupeCapped2(entries,keyOf3,limit=MAX_DIAGNOSTIC_ENTRIES2){let seen=new Set,result=[];for(let entry of entries){let key=keyOf3(entry);if(seen.has(key))continue;if(seen.add(key),result.push(entry),result.length>=limit)break}return result}function replaceFileDiagnostics(graph,file3,replacement){let diagnostics={...graph.diagnostics??{}},replaceStrings=(current,incoming)=>dedupeCapped2([...(current??[]).filter((entry)=>entry!==file3),...incoming??[]],(entry)=>entry);diagnostics.extractionFailures=dedupeCapped2([...(diagnostics.extractionFailures??[]).filter((entry)=>entry.file!==file3),...replacement?.extractionFailures??[]],(entry)=>`${entry.file}\x00${entry.language}\x00${entry.reason}`),diagnostics.unresolvedImports=dedupeCapped2([...(diagnostics.unresolvedImports??[]).filter((entry)=>entry.file!==file3),...replacement?.unresolvedImports??[]],(entry)=>`${entry.file}\x00${entry.specifier}`),diagnostics.oversizedFiles=replaceStrings(diagnostics.oversizedFiles,replacement?.oversizedFiles),diagnostics.binaryFiles=replaceStrings(diagnostics.binaryFiles,replacement?.binaryFiles),diagnostics.unreadableFiles=replaceStrings(diagnostics.unreadableFiles,replacement?.unreadableFiles),diagnostics.validationSkippedFiles=replaceStrings(diagnostics.validationSkippedFiles,replacement?.validationSkippedFiles),diagnostics.extractorInputWitnesses=dedupeCapped2([...(diagnostics.extractorInputWitnesses??[]).filter((entry)=>entry.file!==file3),...replacement?.extractorInputWitnesses??[]],(entry)=>`${entry.kind}\x00${entry.file}`,MAX_EXTRACTOR_INPUT_WITNESSES),graph.diagnostics=diagnostics}function scanDiagnostics(diagnostics,inputWitness){if(!diagnostics&&!inputWitness)return;return{...diagnostics??{},extractorInputWitnesses:inputWitness?[inputWitness]:[]}}function isEnoent(error93){return error93 instanceof Error&&"code"in error93&&error93.code==="ENOENT"}function applyAuthorizedDeletion(graph,filePath,absoluteRoot){let normalizedPath2=normalizeGraphPath(filePath);if(delete graph.nodes[normalizedPath2],graph.edges=graph.edges.filter((edge)=>normalizeGraphPath(edge.source)!==normalizedPath2&&normalizeGraphPath(edge.target)!==normalizedPath2),graph.symbolEdges)graph.symbolEdges=graph.symbolEdges.filter((edge)=>normalizeGraphPath(edge.fromFile)!==normalizedPath2&&normalizeGraphPath(edge.toFile)!==normalizedPath2);replaceFileDiagnostics(graph,diagnosticName(filePath,absoluteRoot))}async function updateGraphForFiles(workspaceRoot,filePaths,options){if(options?.forceRebuild){let graph2=await _internals165.buildWorkspaceGraphAsync(workspaceRoot,options.buildOptions);return await persistGraph(workspaceRoot,graph2,options.buildOptions),graph2}let existingGraph=await loadGraph(workspaceRoot);if(!existingGraph){let graph2=await _internals165.buildWorkspaceGraphAsync(workspaceRoot,options?.buildOptions);return await persistGraph(workspaceRoot,graph2,options?.buildOptions),graph2}let graph=existingGraph,absoluteRoot=path221.resolve(workspaceRoot),maxFileSize=options?.buildOptions?.maxFileSizeBytes??1048576,hasManifest=buildManifestClosure(graph,absoluteRoot);await applyAsyncFileUpdates(graph,filePaths,absoluteRoot,maxFileSize,hasManifest);let firstCheck=validateFileUpdates(graph);if(firstCheck.validationFailed)return await fallBackToFullRebuild(workspaceRoot,firstCheck.offendingEdge,firstCheck.reason,options?.buildOptions);let normalizedWorkspace=path221.normalize(workspaceRoot),loadedMtime=getCachedMtime(normalizedWorkspace);if(loadedMtime!==void 0){let graphPath=getGraphPath(workspaceRoot),currentStats=null;try{if(existsSync111(graphPath))currentStats=await _internals165.stat(graphPath)}catch{}if(currentStats!==null&&currentStats.mtimeMs!==loadedMtime){clearCacheAndResetQuery(normalizedWorkspace);let freshGraph=await loadGraph(workspaceRoot);if(!freshGraph)return await fallBackToFullRebuild(workspaceRoot,void 0,void 0,options?.buildOptions);await applyAsyncFileUpdates(freshGraph,filePaths,absoluteRoot,maxFileSize,buildManifestClosure(freshGraph,absoluteRoot));let replayCheck=validateFileUpdates(freshGraph);if(replayCheck.validationFailed)return await fallBackToFullRebuild(workspaceRoot,replayCheck.offendingEdge,replayCheck.reason,options?.buildOptions);let postReplayMtime=getCachedMtime(normalizedWorkspace);try{let postReplayStats=await _internals165.stat(graphPath);if(postReplayMtime!==void 0&&postReplayStats.mtimeMs!==postReplayMtime)return warn("[repo-graph] Concurrent modification persisted during replay — falling back to full rebuild"),await fallBackToFullRebuild(workspaceRoot,void 0,void 0,options?.buildOptions)}catch{return warn("[repo-graph] Re-stat failed after concurrent-modification replay — falling back to full rebuild"),await fallBackToFullRebuild(workspaceRoot,void 0,void 0,options?.buildOptions)}return finalizeAndSave(workspaceRoot,freshGraph,options?.buildOptions)}}return finalizeAndSave(workspaceRoot,graph,options?.buildOptions)}async function applyAsyncFileUpdates(graph,filePaths,absoluteRoot,maxFileSize,hasManifest){for(let rawFilePath of filePaths){let normalizedPath2=normalizeGraphPath(rawFilePath);if(!isScannableSourcePath(rawFilePath))continue;let fileDiagnosticName=diagnosticName(rawFilePath,absoluteRoot);try{await _internals165.stat(rawFilePath)}catch(error93){if(isEnoent(error93))applyAuthorizedDeletion(graph,rawFilePath,absoluteRoot);else replaceFileDiagnostics(graph,fileDiagnosticName,{unreadableFiles:[fileDiagnosticName]});continue}let result=await _internals165.scanFileAsync(rawFilePath,absoluteRoot,maxFileSize,hasManifest);if(result.node){let sanitizedImports=result.node.imports.filter((imp)=>!containsControlChars(imp)),sanitizedNode={...result.node,imports:sanitizedImports};try{upsertNode(graph,sanitizedNode)}catch{let validationWitness=typeof sanitizedNode.sizeBytes==="number"&&typeof sanitizedNode.mtimeMs==="number"?{file:fileDiagnosticName,kind:"stable-skip",sizeBytes:sanitizedNode.sizeBytes,mtimeMs:sanitizedNode.mtimeMs}:void 0;replaceFileDiagnostics(graph,fileDiagnosticName,scanDiagnostics({...result.diagnostics,validationSkippedFiles:[fileDiagnosticName]},validationWitness));continue}if(graph.edges=graph.edges.filter((edge)=>normalizeGraphPath(edge.source)!==normalizedPath2),graph.symbolEdges)graph.symbolEdges=graph.symbolEdges.filter((edge)=>normalizeGraphPath(edge.fromFile)!==normalizedPath2);for(let edge of result.edges)if(!graph.edges.some((e)=>e.source===edge.source&&e.target===edge.target&&e.importSpecifier===edge.importSpecifier))try{addEdge(graph,edge)}catch{}if(result.symbolEdges.length>0){if(!graph.symbolEdges)graph.symbolEdges=[];let existingKeys=new Set(graph.symbolEdges.map((se)=>`${se.fromFile}\x00${se.fromSymbol}\x00${se.toFile}\x00${se.toSymbol}`));for(let symbolEdge of result.symbolEdges){let key=`${symbolEdge.fromFile}\x00${symbolEdge.fromSymbol}\x00${symbolEdge.toFile}\x00${symbolEdge.toSymbol}`;if(!existingKeys.has(key))graph.symbolEdges.push(symbolEdge),existingKeys.add(key)}}replaceFileDiagnostics(graph,fileDiagnosticName,scanDiagnostics(result.diagnostics,result.inputWitness))}else{if((result.diagnostics?.oversizedFiles?.length??0)>0||(result.diagnostics?.binaryFiles?.length??0)>0){if(graph.edges=graph.edges.filter((edge)=>normalizeGraphPath(edge.source)!==normalizedPath2),graph.symbolEdges)graph.symbolEdges=graph.symbolEdges.filter((edge)=>normalizeGraphPath(edge.fromFile)!==normalizedPath2);delete graph.nodes[normalizedPath2],replaceFileDiagnostics(graph,fileDiagnosticName,scanDiagnostics(result.diagnostics,result.inputWitness));continue}try{await _internals165.stat(rawFilePath),replaceFileDiagnostics(graph,fileDiagnosticName,{...result.diagnostics,unreadableFiles:[fileDiagnosticName]})}catch(error93){if(isEnoent(error93))applyAuthorizedDeletion(graph,rawFilePath,absoluteRoot);else replaceFileDiagnostics(graph,fileDiagnosticName,{...result.diagnostics,unreadableFiles:[fileDiagnosticName]})}}}}function clearCacheAndResetQuery(normalizedWorkspace){clearCache(normalizedWorkspace),resetQueryCache()}async function finalizeAndSave(workspaceRoot,graph,buildOptions){if(graph.symbolEdges&&graph.symbolEdges.length===0)delete graph.symbolEdges;return updateGraphMetadata(graph),resetQueryCache(),await persistGraph(workspaceRoot,graph,buildOptions),graph}async function persistGraph(workspaceRoot,graph,buildOptions){await _internals165.saveGraph(workspaceRoot,graph),await _internals165.writeFingerprint(workspaceRoot,graph,{maxFiles:buildOptions?.maxFiles,walkBudgetMs:buildOptions?.walkBudgetMs,followSymlinks:buildOptions?.followSymlinks,excludeDirs:buildOptions?.excludeDirs})}async function fallBackToFullRebuild(workspaceRoot,offendingEdge,reason,buildOptions){if(offendingEdge)warn(`[repo-graph] Incremental update failed, falling back to full rebuild (offending edge: source=${offendingEdge.source} target=${offendingEdge.target} importSpecifier=${offendingEdge.importSpecifier}`+(reason?`, reason=${reason}`:"")+")");else warn("[repo-graph] Concurrent modification detected — falling back to full rebuild");let rebuiltGraph=await _internals165.buildWorkspaceGraphAsync(workspaceRoot,buildOptions),prev=rebuiltGraph.diagnostics??{},prevFallbacks=typeof prev.incrementalFallbacks==="number"?prev.incrementalFallbacks:0;return rebuiltGraph.diagnostics={...prev,incrementalFallbacks:prevFallbacks+1},await persistGraph(workspaceRoot,rebuiltGraph,buildOptions),rebuiltGraph}init_logger();function extractFilePath(args2){if(!args2||typeof args2!=="object")return null;let a=args2,filePath=a.file_path??a.path??a.filePath;if(!filePath||typeof filePath!=="string")return null;for(let i=0;i<3;i++)try{let decoded=decodeURIComponent(filePath);if(decoded===filePath)break;filePath=decoded}catch{break}return filePath=filePath.replace(/./g,".").replace(///g,"/").replace(/․/g,"."),filePath}function isSupportedSourceFile(filePath){return isScannableSourcePath(filePath)}function rebaseOntoWorkspace(realFilePath,realWorkspace,workspaceRoot){let normRealFile=realFilePath.replace(/\\/g,"/"),normRealWs=realWorkspace.replace(/\\/g,"/");if(normRealFile!==normRealWs&&!normRealFile.startsWith(`${normRealWs}/`))return realFilePath;if(path222.resolve(workspaceRoot)===path222.resolve(realWorkspace))return realFilePath;let rel=normRealFile.slice(normRealWs.length+(normRealFile===normRealWs?0:1));return path222.join(workspaceRoot,rel)}function createRepoGraphBuilderHook(workspaceRoot,deps,options){let _buildWorkspaceGraph=deps?.buildWorkspaceGraph??buildWorkspaceGraphAsync,_saveGraph=deps?.saveGraph??saveGraph,_updateGraphForFiles=deps?.updateGraphForFiles??updateGraphForFiles,_loadGraph=deps?.loadGraph??loadGraph,_probeFreshness=deps?.probeFreshness??probeFreshness,_writeFingerprint=deps?.writeFingerprint??writeFingerprint,_isGraphWideInputPath=deps?.isGraphWideInputPath??isGraphWideInputPath,_safeRealpathSync=deps?.safeRealpathSync??safeRealpathSync,_enabled=options?.enabled??!0,_initRefresh=options?.initRefresh??!0,_refreshCap=options?.refreshCap??50,_maxFiles=options?.maxFiles??1e4,_walkBudgetMs=options?.walkBudgetMs??5000,_excludeDirs=(options?.excludeDirs??[]).filter((d)=>d.length>0),_excludeDirSet=new Set(_excludeDirs),_buildOptions={excludeDirs:_excludeDirs,...options?.maxFiles===void 0?{}:{maxFiles:_maxFiles},...options?.walkBudgetMs===void 0?{}:{walkBudgetMs:_walkBudgetMs}},_hasConfiguredBuildOptions=options?.maxFiles!==void 0||options?.walkBudgetMs!==void 0||options?.excludeDirs!==void 0,_freshnessOptions={maxFiles:_maxFiles,walkBudgetMs:_walkBudgetMs,excludeDirs:_excludeDirs},initStarted=!1,initPromise=Promise.resolve(),FAILURE_ADVISORY_THRESHOLD=3,FAILURE_DECAY_MS=300000,ADVISORY_COOLDOWN_MS=60000,MAX_TRACKED_SESSIONS5=100,failuresBySession=new Map;function recordSuccess(sessionID){failuresBySession.delete(sessionID)}function recordFailure(sessionID,now2){let state=failuresBySession.get(sessionID);if(state&&now2-state.lastFailureAt>FAILURE_DECAY_MS)failuresBySession.delete(sessionID),state=void 0;if(!state){if(failuresBySession.size>=MAX_TRACKED_SESSIONS5){let oldest=failuresBySession.keys().next().value;if(oldest!==void 0)failuresBySession.delete(oldest)}state={failures:0,lastFailureAt:0,lastAdvisoryAt:0},failuresBySession.set(sessionID,state)}state.failures+=1,state.lastFailureAt=now2;let advise=!1;if(state.failures>=FAILURE_ADVISORY_THRESHOLD&&now2-state.lastAdvisoryAt>=ADVISORY_COOLDOWN_MS)advise=!0,state.lastAdvisoryAt=now2;return{count:state.failures,advise}}async function rebuildGraph(reason){let graph=await _buildWorkspaceGraph(workspaceRoot,_buildOptions);await _saveGraph(workspaceRoot,graph);let fingerprintWritten=await _writeFingerprint(workspaceRoot,graph,_freshnessOptions);if(log(`[repo-graph] Built graph (${reason}): ${graph.metadata.nodeCount} nodes, ${graph.metadata.edgeCount} edges`),!fingerprintWritten)warn("[repo-graph] Graph saved, but its freshness fingerprint could not be certified; the next session will rebuild it safely.")}function uniqueDriftFiles(probe2){return[...new Set([...probe2.changed,...probe2.removed])]}function updateFiles(files){return _hasConfiguredBuildOptions?_updateGraphForFiles(workspaceRoot,files,{buildOptions:_buildOptions}):_updateGraphForFiles(workspaceRoot,files)}async function doInit(){await yieldToEventLoop();try{if(!_initRefresh){await rebuildGraph("configured legacy startup rebuild");return}let graph;try{graph=await _loadGraph(workspaceRoot)}catch(error93){if(error93 instanceof Error&&"code"in error93&&error93.code==="CORRUPTION"){await rebuildGraph("corrupt saved graph");return}throw error93}if(!graph){await rebuildGraph("no saved graph");return}let probe2=await _probeFreshness(workspaceRoot,_freshnessOptions);if(probe2.state==="clean"||probe2.state==="inconclusive"){log(`[repo-graph] Startup freshness probe: ${probe2.state}; no refresh`);return}if(probe2.state==="no-fingerprint"){await rebuildGraph("no compatible freshness fingerprint");return}let driftFiles=uniqueDriftFiles(probe2);if(driftFiles.length===0){log("[repo-graph] Startup freshness probe reported no drift files");return}let fullRebuildThreshold=Math.max(_refreshCap*4,graph.metadata.nodeCount*0.4),requiresGraphWideRebuild=driftFiles.some(_isGraphWideInputPath);if(requiresGraphWideRebuild||driftFiles.length>fullRebuildThreshold){await rebuildGraph(requiresGraphWideRebuild?"graph-wide input drift":`drift set exceeded ${fullRebuildThreshold} files`);return}let refreshed=await updateFiles(driftFiles);log(`[repo-graph] Incrementally refreshed ${driftFiles.length} startup drift files: ${refreshed.metadata.nodeCount} nodes`)}catch(error93){let message=error93 instanceof Error?error93.message:String(error93);if(message.includes("does not exist")||message.includes("Refusing to scan")){log(`[repo-graph] Skipping scan: ${message}`);return}error48(`[repo-graph] Failed to build graph: ${message}`)}}return{init(){if(!_enabled)return Promise.resolve();if(!initStarted)initStarted=!0,initPromise=doInit();return initPromise},async toolAfter(input,_output){if(!_enabled)return;if(await initPromise.catch(()=>{}),!WRITE_TOOL_NAMES.includes(input.tool))return;let filePath=extractFilePath(input.args);if(!filePath)return;if(filePath.includes("\x00"))return;if(!isSupportedSourceFile(filePath))return;if(_excludeDirSet.size>0&&filePath.split(/[/\\]/).some((segment)=>_excludeDirSet.has(segment)))return;let absoluteFilePath=path222.isAbsolute(filePath)?filePath:path222.resolve(workspaceRoot,filePath),realFilePath=_safeRealpathSync(absoluteFilePath,absoluteFilePath);if(realFilePath===null)return;let realWorkspace=_safeRealpathSync(workspaceRoot,workspaceRoot);if(realWorkspace===null)return;let normalizedAbsolute=realFilePath.replace(/\\/g,"/"),normalizedWorkspace=realWorkspace.replace(/\\/g,"/");if(!normalizedAbsolute.startsWith(`${normalizedWorkspace}/`)&&normalizedAbsolute!==normalizedWorkspace)return;try{let pathForUpdate=rebaseOntoWorkspace(realFilePath,realWorkspace,workspaceRoot);await updateFiles([pathForUpdate]),recordSuccess(input.sessionID),log(`[repo-graph] Incremental update for ${path222.basename(filePath)}`)}catch(error93){let message=error93 instanceof Error?error93.message:String(error93),{count,advise}=recordFailure(input.sessionID,Date.now());if(error48(`[repo-graph] Incremental update failed: ${message}`),advise)warn(`[repo-graph] ${count} consecutive incremental update failures. The dependency graph may be stale. Consider reloading the workspace.`)}}}}init_review_receipt();init_constants();init_schema();init_manager2();init_detector();init_manager();init_planning_profile();init_state2();init_swarm_artifact_cache();import*as fs126 from"node:fs";import*as path229 from"node:path";init_utils2();init_manager();init_utils();import*as fs121 from"node:fs";import*as path223 from"node:path";var DEFAULT_DRIFT_CONFIG={staleThresholdPhases:1,detectContradictions:!0,maxSignals:5};function extractDecisionsFromContext(contextContent){let decisions=[],lines=contextContent.split(`
6200
+ `)}function getPackageBoundaries(graph,topN=25){return summarizePackageBoundaries(Object.values(graph.nodes),graph.edges,topN)}function summarizePackageBoundaries(nodes,edges,topN){let groups=new Map,ensure=(node)=>{let name=node.ontology?.packageBoundary||inferBoundary(node.moduleName),group=groups.get(name);if(!group)group={name,root:name,fileCount:0,roles:{},dependsOn:[],dependedOnBy:[],routeCount:0,dataOperationCount:0,findingCount:0,publicFiles:[]},groups.set(name,group);return group},boundaryByPath=new Map;for(let node of nodes){let group=ensure(node);boundaryByPath.set(normalizeGraphPath(node.filePath),group.name),group.fileCount++;let ontology=node.ontology;for(let role of ontology?.roles??["source_module"])group.roles[role]=(group.roles[role]??0)+1;if(group.routeCount+=ontology?.routes.length??0,group.dataOperationCount+=ontology?.dataOperations.length??0,group.findingCount+=ontology?.findings.length??0,node.exports.length>0)group.publicFiles.push(node.moduleName)}let dependsOn=new Map,dependedOnBy=new Map;for(let edge of edges){if(isAssetEdge(edge))continue;let sourceBoundary=boundaryByPath.get(normalizeGraphPath(edge.source)),targetBoundary=boundaryByPath.get(normalizeGraphPath(edge.target));if(!sourceBoundary||!targetBoundary||sourceBoundary===targetBoundary)continue;if(!dependsOn.has(sourceBoundary))dependsOn.set(sourceBoundary,new Set);if(!dependedOnBy.has(targetBoundary))dependedOnBy.set(targetBoundary,new Set);dependsOn.get(sourceBoundary)?.add(targetBoundary),dependedOnBy.get(targetBoundary)?.add(sourceBoundary)}for(let group of groups.values())group.dependsOn=[...dependsOn.get(group.name)??[]].sort(),group.dependedOnBy=[...dependedOnBy.get(group.name)??[]].sort(),group.publicFiles.sort((a,b)=>a.localeCompare(b)),group.publicFiles=group.publicFiles.slice(0,20);return[...groups.values()].sort((a,b)=>{if(b.findingCount!==a.findingCount)return b.findingCount-a.findingCount;if(b.fileCount!==a.fileCount)return b.fileCount-a.fileCount;return a.name.localeCompare(b.name)}).slice(0,topN)}function summarizeSelectedPackageBoundaries(graph,nodes,topN=25){let summaries=summarizePackageBoundaries(nodes,[],topN),boundaryByModule=new Map;for(let node of nodes)boundaryByModule.set(normalizeLookupPath(node.moduleName),node.ontology?.packageBoundary??inferBoundary(node.moduleName));let byName=new Map(summaries.map((summary)=>[summary.name,summary])),dependsOn=new Map,dependedOnBy=new Map;for(let node of nodes){let sourceBoundary=boundaryByModule.get(normalizeLookupPath(node.moduleName));if(!sourceBoundary)continue;for(let dep of getDependencies(graph,node.moduleName)){let targetBoundary=boundaryByModule.get(normalizeLookupPath(dep.file));if(!targetBoundary||sourceBoundary===targetBoundary||!byName.has(sourceBoundary)||!byName.has(targetBoundary))continue;if(!dependsOn.has(sourceBoundary))dependsOn.set(sourceBoundary,new Set);if(!dependedOnBy.has(targetBoundary))dependedOnBy.set(targetBoundary,new Set);dependsOn.get(sourceBoundary)?.add(targetBoundary),dependedOnBy.get(targetBoundary)?.add(sourceBoundary)}}for(let summary of summaries)summary.dependsOn=[...dependsOn.get(summary.name)??[]].sort(),summary.dependedOnBy=[...dependedOnBy.get(summary.name)??[]].sort();return summaries}function inferBoundary(moduleName){return inferPackageBoundary(moduleName)}function buildOntologyPreflightPacket(graph,filePaths=[],options={}){let maxFiles=options.maxFiles??12,maxFindings=options.maxFindings??20,boundedNodes=(filePaths.length>0?filePaths.map((filePath)=>getGraphNode(graph,filePath)).filter((node)=>node!==void 0):getKeyFiles(graph,maxFiles)).slice(0,maxFiles),findings=boundedNodes.flatMap((node)=>(node.ontology?.findings??[]).map((finding)=>({file:node.moduleName,...finding}))).slice(0,maxFindings),routes=boundedNodes.flatMap((node)=>(node.ontology?.routes??[]).map((route)=>({file:node.moduleName,...route}))),dataOperations=boundedNodes.flatMap((node)=>(node.ontology?.dataOperations??[]).map((fact)=>({file:node.moduleName,...fact}))),security=boundedNodes.flatMap((node)=>(node.ontology?.security??[]).map((fact)=>({file:node.moduleName,...fact})));return{generatedAt:new Date().toISOString(),targets:boundedNodes.map((node)=>node.moduleName),summary:{fileCount:Object.keys(graph.nodes).length,edgeCount:graph.edges.length,targetCount:boundedNodes.length,findingCount:findings.length,routeCount:routes.length,dataOperationCount:dataOperations.length,securityFactCount:security.length},files:boundedNodes.map((node)=>({file:node.moduleName,roles:node.ontology?.roles??[],packageBoundary:node.ontology?.packageBoundary??inferBoundary(node.moduleName),importerCount:getImporters(graph,node.moduleName).length,dependencyCount:getDependencies(graph,node.moduleName).length,routeCount:node.ontology?.routes.length??0,dataOperationCount:node.ontology?.dataOperations.length??0,securityFactCount:node.ontology?.security.length??0,findingCount:node.ontology?.findings.length??0})),routes,dataOperations,security,findings,packageBoundaries:summarizeSelectedPackageBoundaries(graph,boundedNodes,options.maxBoundaries??10)}}init_utils2();init_logger();init_path_security();import{constants as constants5,existsSync as existsSync111,readFileSync as readFileSync88,statSync as statSync46}from"node:fs";import*as fsPromises8 from"node:fs/promises";import*as path220 from"node:path";var WINDOWS_RENAME_MAX_RETRIES5=5,WINDOWS_RENAME_RETRY_DELAY_MS3=100,_internals164={safeRealpathSync,fsRename:fsPromises8.rename.bind(fsPromises8),retryDelayMs:WINDOWS_RENAME_RETRY_DELAY_MS3,writeFingerprint};function validateLoadedGraph(parsed){if(!parsed.schema_version)throw Object.assign(Error("repo-graph.json missing schema_version"),{code:"CORRUPTION"});if(!parsed.nodes||typeof parsed.nodes!=="object")throw Object.assign(Error("repo-graph.json missing or invalid nodes"),{code:"CORRUPTION"});if(!Array.isArray(parsed.edges))throw Object.assign(Error("repo-graph.json missing or invalid edges"),{code:"CORRUPTION"});for(let[key,node]of Object.entries(parsed.nodes)){if(!key||typeof key!=="string")throw Object.assign(Error("repo-graph.json contains invalid node key"),{code:"CORRUPTION"});try{validateGraphNode(node)}catch(err){let msg=err instanceof Error?err.message:"Invalid node structure";throw Object.assign(Error(`repo-graph.json node validation failed: ${msg}`),{code:"CORRUPTION"})}}for(let edge of parsed.edges)try{validateGraphEdge(edge)}catch(err){let msg=err instanceof Error?err.message:"Invalid edge structure";throw Object.assign(Error(`repo-graph.json edge validation failed: ${msg}`),{code:"CORRUPTION"})}if(!parsed.metadata||typeof parsed.metadata!=="object"||typeof parsed.metadata.generatedAt!=="string"||typeof parsed.metadata.generator!=="string"||typeof parsed.metadata.nodeCount!=="number"||typeof parsed.metadata.edgeCount!=="number")throw Object.assign(Error("repo-graph.json missing or invalid metadata"),{code:"CORRUPTION"});if(parsed.symbolEdges!==void 0){if(!Array.isArray(parsed.symbolEdges))throw Object.assign(Error("repo-graph.json symbolEdges must be an array"),{code:"CORRUPTION"});for(let entry of parsed.symbolEdges)if(typeof entry!=="object"||entry===null||typeof entry.fromFile!=="string"||typeof entry.fromSymbol!=="string"||typeof entry.toFile!=="string"||typeof entry.toSymbol!=="string"||entry.fromFile===""||entry.fromSymbol===""||entry.toFile===""||entry.toSymbol===""||containsControlChars(entry.fromFile)||containsControlChars(entry.fromSymbol)||containsControlChars(entry.toFile)||containsControlChars(entry.toSymbol)||containsPathTraversal(entry.fromFile)||containsPathTraversal(entry.toFile))throw Object.assign(Error("repo-graph.json contains invalid symbolEdges entry"),{code:"CORRUPTION"})}}function getGraphPath(workspace){validateWorkspace(workspace);let basePath=validateSwarmPath(workspace,REPO_GRAPH_FILENAME);return validateSymlinkBoundary(basePath,workspace),basePath}async function loadGraph(workspace){validateWorkspace(workspace);let normalized=path220.normalize(workspace),cached3=getCachedGraph(normalized);if(cached3&&!isDirty(normalized))try{let graphPath=getGraphPath(workspace);if(existsSync111(graphPath)){let stats2=await fsPromises8.stat(graphPath),cachedMtime=getCachedMtime(normalized);if(cachedMtime!==void 0&&stats2.mtimeMs!==cachedMtime)clearCache(normalized);else return cached3}else clearCache(normalized)}catch{clearCache(normalized)}try{let graphPath=getGraphPath(workspace);if(!existsSync111(graphPath))return null;let stats2=await fsPromises8.stat(graphPath),content=await fsPromises8.readFile(graphPath,"utf-8");if(content.includes("\x00")||content.includes("�"))throw Object.assign(Error("repo-graph.json contains null bytes or invalid encoding"),{code:"CORRUPTION"});let parsed;try{parsed=JSON.parse(content)}catch{throw Object.assign(Error("repo-graph.json contains invalid JSON"),{code:"CORRUPTION"})}return validateLoadedGraph(parsed),setCachedGraph(normalized,parsed,stats2.mtimeMs),parsed}catch(error93){if(error93 instanceof Error&&"code"in error93&&error93.code==="CORRUPTION")throw error93;if(error93 instanceof Error&&"code"in error93&&error93.code==="ENOENT")return null;throw error93}}function loadGraphSync(workspace){validateWorkspace(workspace);let normalized=path220.normalize(workspace);try{let graphPath=getGraphPath(workspace);if(!existsSync111(graphPath))return null;let stats2=statSync46(graphPath),content=readFileSync88(graphPath,"utf-8");if(content.includes("\x00")||content.includes("�"))throw Object.assign(Error("repo-graph.json contains null bytes or invalid encoding"),{code:"CORRUPTION"});let parsed;try{parsed=JSON.parse(content)}catch{throw Object.assign(Error("repo-graph.json contains invalid JSON"),{code:"CORRUPTION"})}return validateLoadedGraph(parsed),setCachedGraph(normalized,parsed,stats2.mtimeMs),parsed}catch(error93){if(error93 instanceof Error&&"code"in error93&&error93.code==="ENOENT")return null;throw error93}}async function saveGraph(workspace,graph,options){if(validateWorkspace(workspace),!graph.schema_version)throw Error("Graph must have schema_version");if(!graph.nodes||typeof graph.nodes!=="object")throw Error("Graph must have nodes object");if(!Array.isArray(graph.edges))throw Error("Graph must have edges array");let normalizedWorkspace=path220.normalize(workspace),realWorkspace=_internals164.safeRealpathSync(workspace,normalizedWorkspace);if(realWorkspace===null)throw Error(`Workspace realpath security check failed (non-ENOENT): ${workspace}`);let normalizedGraphRoot=path220.normalize(graph.workspaceRoot),realGraphRoot=_internals164.safeRealpathSync(graph.workspaceRoot,normalizedGraphRoot);if(realGraphRoot===null)throw Error(`Graph workspaceRoot realpath security check failed (non-ENOENT): ${graph.workspaceRoot}`);if(path220.normalize(realWorkspace)!==path220.normalize(realGraphRoot))throw Error(`Graph workspaceRoot mismatch: graph was built for "${graph.workspaceRoot}" but save was called for "${workspace}"`);let normalized=normalizedWorkspace,graphPath=getGraphPath(workspace);updateGraphMetadata(graph);let tempPath=`${graphPath}.tmp.${Date.now()}.${Math.floor(Math.random()*1e9)}`;await fsPromises8.mkdir(path220.dirname(tempPath),{recursive:!0});let lastError=null;try{if(options?.createAtomic)try{let handle=await fsPromises8.open(tempPath,"wx",420);await handle.writeFile(JSON.stringify(graph,null,2),"utf-8"),await handle.close()}catch(error93){if(error93 instanceof Error&&"code"in error93&&error93.code==="EEXIST")throw Error("file already exists");throw error93}else await fsPromises8.writeFile(tempPath,JSON.stringify(graph,null,2),"utf-8");if(options?.createAtomic)try{await fsPromises8.copyFile(tempPath,graphPath,constants5.COPYFILE_EXCL)}catch(error93){throw lastError=error93 instanceof Error?error93:Error(String(error93)),lastError}else{for(let attempt=0;attempt<WINDOWS_RENAME_MAX_RETRIES5;attempt++)try{await _internals164.fsRename(tempPath,graphPath),lastError=null;break}catch(error93){lastError=error93 instanceof Error?error93:Error(String(error93));let code=lastError.code;if(code!=="EEXIST"&&code!=="EPERM"&&code!=="EBUSY")break;if(attempt<WINDOWS_RENAME_MAX_RETRIES5-1)await new Promise((resolve87)=>setTimeout(resolve87,_internals164.retryDelayMs))}if(lastError)throw lastError}}finally{try{await fsPromises8.unlink(tempPath)}catch(error93){if(error93 instanceof Error&&"code"in error93&&error93.code!=="ENOENT")error48(`Failed to clean up temp file ${tempPath}:`,error93)}}let stats2=await fsPromises8.stat(graphPath);setCachedGraph(normalized,graph,stats2.mtimeMs)}var _internals165={stat:(p)=>fsPromises9.stat(p),scanFileAsync,buildWorkspaceGraphAsync,saveGraph,writeFingerprint},MAX_DIAGNOSTIC_ENTRIES2=200,MANIFEST_BASENAMES2=new Set(["package.json","Cargo.toml","pyproject.toml","go.mod"]);function buildManifestClosure(graph,absoluteRoot){let dirs=new Set;for(let node of Object.values(graph.nodes)){let absDir=path221.dirname(node.filePath),rel=path221.relative(absoluteRoot,absDir).split(path221.sep).join("/");rel=rel.replace(/^(?:\.\/)+/,"");while(!0){dirs.add(rel);let idx=rel.lastIndexOf("/");if(idx<0){if(rel!=="")dirs.add("");break}rel=rel.slice(0,idx)}}let manifestDirs=new Set;for(let relDir of dirs){let absDir=relDir===""?absoluteRoot:path221.join(absoluteRoot,relDir);try{if(readdirSync31(absDir).some((name)=>MANIFEST_BASENAMES2.has(name)))manifestDirs.add(relDir)}catch{}}return(relDir)=>manifestDirs.has(relDir)}function validateFileUpdates(graph){for(let edge of graph.edges){let normalizedSource=normalizeGraphPath(edge.source);if(!graph.nodes[normalizedSource])return{validationFailed:!0,offendingEdge:edge,reason:"missing-source-node"};if(!isAssetEdge(edge)){let normalizedTarget=normalizeGraphPath(edge.target);if(!graph.nodes[normalizedTarget])return{validationFailed:!0,offendingEdge:edge,reason:"missing-target-node"}}}if(graph.symbolEdges&&graph.symbolEdges.length>0){let validSymbolEdges=[];for(let symbolEdge of graph.symbolEdges){let normalizedFromFile=normalizeGraphPath(symbolEdge.fromFile),normalizedToFile=normalizeGraphPath(symbolEdge.toFile);if(graph.nodes[normalizedFromFile]&&graph.nodes[normalizedToFile])validSymbolEdges.push(symbolEdge)}graph.symbolEdges=validSymbolEdges}return{validationFailed:!1}}function diagnosticName(filePath,absoluteRoot){return path221.relative(absoluteRoot,filePath).split(path221.sep).join("/")}function dedupeCapped2(entries,keyOf3,limit=MAX_DIAGNOSTIC_ENTRIES2){let seen=new Set,result=[];for(let entry of entries){let key=keyOf3(entry);if(seen.has(key))continue;if(seen.add(key),result.push(entry),result.length>=limit)break}return result}function replaceFileDiagnostics(graph,file3,replacement){let diagnostics={...graph.diagnostics??{}},replaceStrings=(current,incoming)=>dedupeCapped2([...(current??[]).filter((entry)=>entry!==file3),...incoming??[]],(entry)=>entry);diagnostics.extractionFailures=dedupeCapped2([...(diagnostics.extractionFailures??[]).filter((entry)=>entry.file!==file3),...replacement?.extractionFailures??[]],(entry)=>`${entry.file}\x00${entry.language}\x00${entry.reason}`),diagnostics.unresolvedImports=dedupeCapped2([...(diagnostics.unresolvedImports??[]).filter((entry)=>entry.file!==file3),...replacement?.unresolvedImports??[]],(entry)=>`${entry.file}\x00${entry.specifier}`),diagnostics.oversizedFiles=replaceStrings(diagnostics.oversizedFiles,replacement?.oversizedFiles),diagnostics.binaryFiles=replaceStrings(diagnostics.binaryFiles,replacement?.binaryFiles),diagnostics.unreadableFiles=replaceStrings(diagnostics.unreadableFiles,replacement?.unreadableFiles),diagnostics.validationSkippedFiles=replaceStrings(diagnostics.validationSkippedFiles,replacement?.validationSkippedFiles),diagnostics.extractorInputWitnesses=dedupeCapped2([...(diagnostics.extractorInputWitnesses??[]).filter((entry)=>entry.file!==file3),...replacement?.extractorInputWitnesses??[]],(entry)=>`${entry.kind}\x00${entry.file}`,MAX_EXTRACTOR_INPUT_WITNESSES),graph.diagnostics=diagnostics}function scanDiagnostics(diagnostics,inputWitness){if(!diagnostics&&!inputWitness)return;return{...diagnostics??{},extractorInputWitnesses:inputWitness?[inputWitness]:[]}}function isEnoent(error93){return error93 instanceof Error&&"code"in error93&&error93.code==="ENOENT"}function applyAuthorizedDeletion(graph,filePath,absoluteRoot){let normalizedPath2=normalizeGraphPath(filePath);if(delete graph.nodes[normalizedPath2],graph.edges=graph.edges.filter((edge)=>normalizeGraphPath(edge.source)!==normalizedPath2&&normalizeGraphPath(edge.target)!==normalizedPath2),graph.symbolEdges)graph.symbolEdges=graph.symbolEdges.filter((edge)=>normalizeGraphPath(edge.fromFile)!==normalizedPath2&&normalizeGraphPath(edge.toFile)!==normalizedPath2);replaceFileDiagnostics(graph,diagnosticName(filePath,absoluteRoot))}async function updateGraphForFiles(workspaceRoot,filePaths,options){if(options?.forceRebuild){let graph2=await _internals165.buildWorkspaceGraphAsync(workspaceRoot,options.buildOptions);return await persistGraph(workspaceRoot,graph2,options.buildOptions),graph2}let existingGraph=await loadGraph(workspaceRoot);if(!existingGraph){let graph2=await _internals165.buildWorkspaceGraphAsync(workspaceRoot,options?.buildOptions);return await persistGraph(workspaceRoot,graph2,options?.buildOptions),graph2}let graph=existingGraph,absoluteRoot=path221.resolve(workspaceRoot),maxFileSize=options?.buildOptions?.maxFileSizeBytes??1048576,hasManifest=buildManifestClosure(graph,absoluteRoot);await applyAsyncFileUpdates(graph,filePaths,absoluteRoot,maxFileSize,hasManifest);let firstCheck=validateFileUpdates(graph);if(firstCheck.validationFailed)return await fallBackToFullRebuild(workspaceRoot,firstCheck.offendingEdge,firstCheck.reason,options?.buildOptions);let normalizedWorkspace=path221.normalize(workspaceRoot),loadedMtime=getCachedMtime(normalizedWorkspace);if(loadedMtime!==void 0){let graphPath=getGraphPath(workspaceRoot),currentStats=null;try{if(existsSync112(graphPath))currentStats=await _internals165.stat(graphPath)}catch{}if(currentStats!==null&&currentStats.mtimeMs!==loadedMtime){clearCacheAndResetQuery(normalizedWorkspace);let freshGraph=await loadGraph(workspaceRoot);if(!freshGraph)return await fallBackToFullRebuild(workspaceRoot,void 0,void 0,options?.buildOptions);await applyAsyncFileUpdates(freshGraph,filePaths,absoluteRoot,maxFileSize,buildManifestClosure(freshGraph,absoluteRoot));let replayCheck=validateFileUpdates(freshGraph);if(replayCheck.validationFailed)return await fallBackToFullRebuild(workspaceRoot,replayCheck.offendingEdge,replayCheck.reason,options?.buildOptions);let postReplayMtime=getCachedMtime(normalizedWorkspace);try{let postReplayStats=await _internals165.stat(graphPath);if(postReplayMtime!==void 0&&postReplayStats.mtimeMs!==postReplayMtime)return warn("[repo-graph] Concurrent modification persisted during replay — falling back to full rebuild"),await fallBackToFullRebuild(workspaceRoot,void 0,void 0,options?.buildOptions)}catch{return warn("[repo-graph] Re-stat failed after concurrent-modification replay — falling back to full rebuild"),await fallBackToFullRebuild(workspaceRoot,void 0,void 0,options?.buildOptions)}return finalizeAndSave(workspaceRoot,freshGraph,options?.buildOptions)}}return finalizeAndSave(workspaceRoot,graph,options?.buildOptions)}async function applyAsyncFileUpdates(graph,filePaths,absoluteRoot,maxFileSize,hasManifest){for(let rawFilePath of filePaths){let normalizedPath2=normalizeGraphPath(rawFilePath);if(!isScannableSourcePath(rawFilePath))continue;let fileDiagnosticName=diagnosticName(rawFilePath,absoluteRoot);try{await _internals165.stat(rawFilePath)}catch(error93){if(isEnoent(error93))applyAuthorizedDeletion(graph,rawFilePath,absoluteRoot);else replaceFileDiagnostics(graph,fileDiagnosticName,{unreadableFiles:[fileDiagnosticName]});continue}let result=await _internals165.scanFileAsync(rawFilePath,absoluteRoot,maxFileSize,hasManifest);if(result.node){let sanitizedImports=result.node.imports.filter((imp)=>!containsControlChars(imp)),sanitizedNode={...result.node,imports:sanitizedImports};try{upsertNode(graph,sanitizedNode)}catch{let validationWitness=typeof sanitizedNode.sizeBytes==="number"&&typeof sanitizedNode.mtimeMs==="number"?{file:fileDiagnosticName,kind:"stable-skip",sizeBytes:sanitizedNode.sizeBytes,mtimeMs:sanitizedNode.mtimeMs}:void 0;replaceFileDiagnostics(graph,fileDiagnosticName,scanDiagnostics({...result.diagnostics,validationSkippedFiles:[fileDiagnosticName]},validationWitness));continue}if(graph.edges=graph.edges.filter((edge)=>normalizeGraphPath(edge.source)!==normalizedPath2),graph.symbolEdges)graph.symbolEdges=graph.symbolEdges.filter((edge)=>normalizeGraphPath(edge.fromFile)!==normalizedPath2);for(let edge of result.edges)if(!graph.edges.some((e)=>e.source===edge.source&&e.target===edge.target&&e.importSpecifier===edge.importSpecifier))try{addEdge(graph,edge)}catch{}if(result.symbolEdges.length>0){if(!graph.symbolEdges)graph.symbolEdges=[];let existingKeys=new Set(graph.symbolEdges.map((se)=>`${se.fromFile}\x00${se.fromSymbol}\x00${se.toFile}\x00${se.toSymbol}`));for(let symbolEdge of result.symbolEdges){let key=`${symbolEdge.fromFile}\x00${symbolEdge.fromSymbol}\x00${symbolEdge.toFile}\x00${symbolEdge.toSymbol}`;if(!existingKeys.has(key))graph.symbolEdges.push(symbolEdge),existingKeys.add(key)}}replaceFileDiagnostics(graph,fileDiagnosticName,scanDiagnostics(result.diagnostics,result.inputWitness))}else{if((result.diagnostics?.oversizedFiles?.length??0)>0||(result.diagnostics?.binaryFiles?.length??0)>0){if(graph.edges=graph.edges.filter((edge)=>normalizeGraphPath(edge.source)!==normalizedPath2),graph.symbolEdges)graph.symbolEdges=graph.symbolEdges.filter((edge)=>normalizeGraphPath(edge.fromFile)!==normalizedPath2);delete graph.nodes[normalizedPath2],replaceFileDiagnostics(graph,fileDiagnosticName,scanDiagnostics(result.diagnostics,result.inputWitness));continue}try{await _internals165.stat(rawFilePath),replaceFileDiagnostics(graph,fileDiagnosticName,{...result.diagnostics,unreadableFiles:[fileDiagnosticName]})}catch(error93){if(isEnoent(error93))applyAuthorizedDeletion(graph,rawFilePath,absoluteRoot);else replaceFileDiagnostics(graph,fileDiagnosticName,{...result.diagnostics,unreadableFiles:[fileDiagnosticName]})}}}}function clearCacheAndResetQuery(normalizedWorkspace){clearCache(normalizedWorkspace),resetQueryCache()}async function finalizeAndSave(workspaceRoot,graph,buildOptions){if(graph.symbolEdges&&graph.symbolEdges.length===0)delete graph.symbolEdges;return updateGraphMetadata(graph),resetQueryCache(),await persistGraph(workspaceRoot,graph,buildOptions),graph}async function persistGraph(workspaceRoot,graph,buildOptions){await _internals165.saveGraph(workspaceRoot,graph),await _internals165.writeFingerprint(workspaceRoot,graph,{maxFiles:buildOptions?.maxFiles,walkBudgetMs:buildOptions?.walkBudgetMs,followSymlinks:buildOptions?.followSymlinks,excludeDirs:buildOptions?.excludeDirs})}async function fallBackToFullRebuild(workspaceRoot,offendingEdge,reason,buildOptions){if(offendingEdge)warn(`[repo-graph] Incremental update failed, falling back to full rebuild (offending edge: source=${offendingEdge.source} target=${offendingEdge.target} importSpecifier=${offendingEdge.importSpecifier}`+(reason?`, reason=${reason}`:"")+")");else warn("[repo-graph] Concurrent modification detected — falling back to full rebuild");let rebuiltGraph=await _internals165.buildWorkspaceGraphAsync(workspaceRoot,buildOptions),prev=rebuiltGraph.diagnostics??{},prevFallbacks=typeof prev.incrementalFallbacks==="number"?prev.incrementalFallbacks:0;return rebuiltGraph.diagnostics={...prev,incrementalFallbacks:prevFallbacks+1},await persistGraph(workspaceRoot,rebuiltGraph,buildOptions),rebuiltGraph}init_logger();function extractFilePath(args2){if(!args2||typeof args2!=="object")return null;let a=args2,filePath=a.file_path??a.path??a.filePath;if(!filePath||typeof filePath!=="string")return null;for(let i=0;i<3;i++)try{let decoded=decodeURIComponent(filePath);if(decoded===filePath)break;filePath=decoded}catch{break}return filePath=filePath.replace(/./g,".").replace(///g,"/").replace(/․/g,"."),filePath}function isSupportedSourceFile(filePath){return isScannableSourcePath(filePath)}function rebaseOntoWorkspace(realFilePath,realWorkspace,workspaceRoot){let normRealFile=realFilePath.replace(/\\/g,"/"),normRealWs=realWorkspace.replace(/\\/g,"/");if(normRealFile!==normRealWs&&!normRealFile.startsWith(`${normRealWs}/`))return realFilePath;if(path222.resolve(workspaceRoot)===path222.resolve(realWorkspace))return realFilePath;let rel=normRealFile.slice(normRealWs.length+(normRealFile===normRealWs?0:1));return path222.join(workspaceRoot,rel)}function createRepoGraphBuilderHook(workspaceRoot,deps,options){let _buildWorkspaceGraph=deps?.buildWorkspaceGraph??buildWorkspaceGraphAsync,_saveGraph=deps?.saveGraph??saveGraph,_updateGraphForFiles=deps?.updateGraphForFiles??updateGraphForFiles,_loadGraph=deps?.loadGraph??loadGraph,_probeFreshness=deps?.probeFreshness??probeFreshness,_writeFingerprint=deps?.writeFingerprint??writeFingerprint,_isGraphWideInputPath=deps?.isGraphWideInputPath??isGraphWideInputPath,_safeRealpathSync=deps?.safeRealpathSync??safeRealpathSync,_enabled=options?.enabled??!0,_initRefresh=options?.initRefresh??!0,_refreshCap=options?.refreshCap??50,_maxFiles=options?.maxFiles??1e4,_walkBudgetMs=options?.walkBudgetMs??5000,_excludeDirs=(options?.excludeDirs??[]).filter((d)=>d.length>0),_excludeDirSet=new Set(_excludeDirs),_buildOptions={excludeDirs:_excludeDirs,...options?.maxFiles===void 0?{}:{maxFiles:_maxFiles},...options?.walkBudgetMs===void 0?{}:{walkBudgetMs:_walkBudgetMs}},_hasConfiguredBuildOptions=options?.maxFiles!==void 0||options?.walkBudgetMs!==void 0||options?.excludeDirs!==void 0,_freshnessOptions={maxFiles:_maxFiles,walkBudgetMs:_walkBudgetMs,excludeDirs:_excludeDirs},initStarted=!1,initPromise=Promise.resolve(),FAILURE_ADVISORY_THRESHOLD=3,FAILURE_DECAY_MS=300000,ADVISORY_COOLDOWN_MS=60000,MAX_TRACKED_SESSIONS5=100,failuresBySession=new Map;function recordSuccess(sessionID){failuresBySession.delete(sessionID)}function recordFailure(sessionID,now2){let state=failuresBySession.get(sessionID);if(state&&now2-state.lastFailureAt>FAILURE_DECAY_MS)failuresBySession.delete(sessionID),state=void 0;if(!state){if(failuresBySession.size>=MAX_TRACKED_SESSIONS5){let oldest=failuresBySession.keys().next().value;if(oldest!==void 0)failuresBySession.delete(oldest)}state={failures:0,lastFailureAt:0,lastAdvisoryAt:0},failuresBySession.set(sessionID,state)}state.failures+=1,state.lastFailureAt=now2;let advise=!1;if(state.failures>=FAILURE_ADVISORY_THRESHOLD&&now2-state.lastAdvisoryAt>=ADVISORY_COOLDOWN_MS)advise=!0,state.lastAdvisoryAt=now2;return{count:state.failures,advise}}async function rebuildGraph(reason){let graph=await _buildWorkspaceGraph(workspaceRoot,_buildOptions);await _saveGraph(workspaceRoot,graph);let fingerprintWritten=await _writeFingerprint(workspaceRoot,graph,_freshnessOptions);if(log(`[repo-graph] Built graph (${reason}): ${graph.metadata.nodeCount} nodes, ${graph.metadata.edgeCount} edges`),!fingerprintWritten)warn("[repo-graph] Graph saved, but its freshness fingerprint could not be certified; the next session will rebuild it safely.")}function uniqueDriftFiles(probe2){return[...new Set([...probe2.changed,...probe2.removed])]}function updateFiles(files){return _hasConfiguredBuildOptions?_updateGraphForFiles(workspaceRoot,files,{buildOptions:_buildOptions}):_updateGraphForFiles(workspaceRoot,files)}async function doInit(){await yieldToEventLoop();try{if(!_initRefresh){await rebuildGraph("configured legacy startup rebuild");return}let graph;try{graph=await _loadGraph(workspaceRoot)}catch(error93){if(error93 instanceof Error&&"code"in error93&&error93.code==="CORRUPTION"){await rebuildGraph("corrupt saved graph");return}throw error93}if(!graph){await rebuildGraph("no saved graph");return}let probe2=await _probeFreshness(workspaceRoot,_freshnessOptions);if(probe2.state==="clean"||probe2.state==="inconclusive"){log(`[repo-graph] Startup freshness probe: ${probe2.state}; no refresh`);return}if(probe2.state==="no-fingerprint"){await rebuildGraph("no compatible freshness fingerprint");return}let driftFiles=uniqueDriftFiles(probe2);if(driftFiles.length===0){log("[repo-graph] Startup freshness probe reported no drift files");return}let fullRebuildThreshold=Math.max(_refreshCap*4,graph.metadata.nodeCount*0.4),requiresGraphWideRebuild=driftFiles.some(_isGraphWideInputPath);if(requiresGraphWideRebuild||driftFiles.length>fullRebuildThreshold){await rebuildGraph(requiresGraphWideRebuild?"graph-wide input drift":`drift set exceeded ${fullRebuildThreshold} files`);return}let refreshed=await updateFiles(driftFiles);log(`[repo-graph] Incrementally refreshed ${driftFiles.length} startup drift files: ${refreshed.metadata.nodeCount} nodes`)}catch(error93){let message=error93 instanceof Error?error93.message:String(error93);if(message.includes("does not exist")||message.includes("Refusing to scan")){log(`[repo-graph] Skipping scan: ${message}`);return}error48(`[repo-graph] Failed to build graph: ${message}`)}}return{init(){if(!_enabled)return Promise.resolve();if(!initStarted)initStarted=!0,initPromise=doInit();return initPromise},async toolAfter(input,_output){if(!_enabled)return;if(await initPromise.catch(()=>{}),!WRITE_TOOL_NAMES.includes(input.tool))return;let filePath=extractFilePath(input.args);if(!filePath)return;if(filePath.includes("\x00"))return;if(!isSupportedSourceFile(filePath))return;if(_excludeDirSet.size>0&&filePath.split(/[/\\]/).some((segment)=>_excludeDirSet.has(segment)))return;let absoluteFilePath=path222.isAbsolute(filePath)?filePath:path222.resolve(workspaceRoot,filePath),realFilePath=_safeRealpathSync(absoluteFilePath,absoluteFilePath);if(realFilePath===null)return;let realWorkspace=_safeRealpathSync(workspaceRoot,workspaceRoot);if(realWorkspace===null)return;let normalizedAbsolute=realFilePath.replace(/\\/g,"/"),normalizedWorkspace=realWorkspace.replace(/\\/g,"/");if(!normalizedAbsolute.startsWith(`${normalizedWorkspace}/`)&&normalizedAbsolute!==normalizedWorkspace)return;try{let pathForUpdate=rebaseOntoWorkspace(realFilePath,realWorkspace,workspaceRoot);await updateFiles([pathForUpdate]),recordSuccess(input.sessionID),log(`[repo-graph] Incremental update for ${path222.basename(filePath)}`)}catch(error93){let message=error93 instanceof Error?error93.message:String(error93),{count,advise}=recordFailure(input.sessionID,Date.now());if(error48(`[repo-graph] Incremental update failed: ${message}`),advise)warn(`[repo-graph] ${count} consecutive incremental update failures. The dependency graph may be stale. Consider reloading the workspace.`)}}}}init_review_receipt();init_constants();init_schema();init_manager2();init_detector();init_manager();init_planning_profile();init_state2();init_swarm_artifact_cache();import*as fs126 from"node:fs";import*as path229 from"node:path";init_utils2();init_manager();init_utils();import*as fs121 from"node:fs";import*as path223 from"node:path";var DEFAULT_DRIFT_CONFIG={staleThresholdPhases:1,detectContradictions:!0,maxSignals:5};function extractDecisionsFromContext(contextContent){let decisions=[],lines=contextContent.split(`
6194
6201
  `),inDecisionsSection=!1,currentPhase=null,lineNumber=0;for(let i=0;i<lines.length;i++){let line=lines[i];lineNumber=i+1;let phaseMatch=line.match(/^## Phase (\d+)/);if(phaseMatch)currentPhase=parseInt(phaseMatch[1],10);if(line.trim()==="## Decisions"){inDecisionsSection=!0;continue}if(inDecisionsSection&&line.startsWith("## "))break;if(inDecisionsSection&&line.trim().startsWith("- ")){let text=line.trim().substring(2),confirmed=text.includes("✅")||text.includes("[confirmed]"),timestampMatch=text.match(/\[(\d{4}-\d{2}-\d{2}T[\d:.]+Z?)\]/),timestamp=timestampMatch?timestampMatch[1]:null,decisionPhaseMatch=text.match(/Phase (\d+)/),decisionPhase=decisionPhaseMatch?parseInt(decisionPhaseMatch[1],10):currentPhase;decisions.push({text:text.replace(/\s*\[.*?\]\s*/g,"").trim(),phase:decisionPhase,confirmed,timestamp,line:lineNumber})}}return decisions}function isDecisionStale(decision,currentPhase,threshold){if(decision.phase===null)return!decision.confirmed;let phaseDiff=currentPhase-decision.phase;if(phaseDiff>=threshold)return!0;if(phaseDiff===0&&!decision.confirmed)return!0;return!1}function classifyPolarity(textLower,positiveKeywords,negativeKeywords){if(negativeKeywords.some((k)=>textLower.includes(k)))return"negative";if(positiveKeywords.some((k)=>textLower.includes(k)))return"positive";return null}function findContradictions(decisions){let signals=[],contradictionPairs=[[["use","using","use ","adopt","implement","enable"],["not use","don't use","do not use","avoid","disable","remove"]],[["keep","retain","preserve"],["remove","delete","drop","eliminate"]],[["include","add","incorporate"],["exclude","skip","omit"]],[["require","mandatory","must"],["optional","skip","can skip"]],[["background","async"],["foreground","sync","synchronous"]]];for(let i=0;i<decisions.length;i++){let decisionA=decisions[i],textLower=decisionA.text.toLowerCase();for(let j=i+1;j<decisions.length;j++){let decisionB=decisions[j],textBLower=decisionB.text.toLowerCase();for(let[positiveKeywords,negativeKeywords]of contradictionPairs){let polarityA=classifyPolarity(textLower,positiveKeywords,negativeKeywords),polarityB=classifyPolarity(textBLower,positiveKeywords,negativeKeywords);if(polarityA==="positive"&&polarityB==="negative"||polarityA==="negative"&&polarityB==="positive"){let wordsA=textLower.split(/\s+/).slice(0,4).join(" "),wordsB=textBLower.split(/\s+/).slice(0,4).join(" ");if(wordsA.split(/\s+/).filter((w)=>w.length>2&&wordsB.includes(w)).length>0||wordsA.includes("file"))signals.push({id:`contradiction-${i}-${j}`,severity:"error",type:"contradiction",message:"Contradictory decisions detected",source:{file:"context.md",line:decisionA.line},relatedDecisions:[decisionA.text,decisionB.text],hint:"Review both decisions and clarify the intended approach."})}}}}return signals}function extractCurrentPhaseFromLegacy(planContent){if(!planContent)return null;let lines=planContent.split(`
6195
6202
  `);for(let i=0;i<Math.min(30,lines.length);i++){let progressMatch=lines[i].trim().match(/^## Phase (\d+):?\s*(.*?)\s*\[IN PROGRESS\]/i);if(progressMatch)return parseInt(progressMatch[1],10)}for(let i=0;i<Math.min(5,lines.length);i++){let phaseMatch=lines[i].trim().match(/Phase:\s*(\d+)/i);if(phaseMatch)return parseInt(phaseMatch[1],10)}return null}async function analyzeDecisionDrift(directory,config3={}){let effectiveConfig={...DEFAULT_DRIFT_CONFIG,...config3},signals=[],analyzedAt=new Date().toISOString();try{let plan=await loadPlan(directory),currentPhase=plan?.current_phase??1;if(!plan){let legacyPhase=extractCurrentPhaseFromLegacy(await readSwarmFileAsync(directory,"plan.md")??"");if(legacyPhase!==null)currentPhase=legacyPhase}let contextPath=path223.join(directory,".swarm","context.md"),contextContent="";try{if(fs121.existsSync(contextPath))contextContent=fs121.readFileSync(contextPath,"utf-8")}catch(error93){return log("[DecisionDriftAnalyzer] context file read failed",{error:error93 instanceof Error?error93.message:String(error93)}),{hasDrift:!1,signals:[],summary:"",analyzedAt}}if(!contextContent)return{hasDrift:!1,signals:[],summary:"",analyzedAt};let decisions=extractDecisionsFromContext(contextContent);if(decisions.length===0)return{hasDrift:!1,signals:[],summary:"",analyzedAt};for(let decision of decisions)if(isDecisionStale(decision,currentPhase,effectiveConfig.staleThresholdPhases)){let hint;if(decision.phase!==null&&decision.phase<currentPhase)hint=`Decision was from Phase ${decision.phase}, current is Phase ${currentPhase}.`;else if(!decision.confirmed)hint="Decision has not been confirmed. Consider confirming or revisiting.";signals.push({id:`stale-${decision.line}`,severity:decision.phase!==null&&decision.phase<currentPhase?"warning":"warning",type:"stale",message:`Stale decision: "${decision.text.substring(0,50)}${decision.text.length>50?"...":""}"`,source:{file:"context.md",line:decision.line},hint})}if(effectiveConfig.detectContradictions){let contradictions=findContradictions(decisions);signals.push(...contradictions)}let limitedSignals=signals.slice(0,effectiveConfig.maxSignals),summary=buildDriftSummary(limitedSignals);return{hasDrift:limitedSignals.length>0,signals:limitedSignals,summary,analyzedAt}}catch(error93){return log("[DecisionDriftAnalyzer] drift analysis failed",{error:error93 instanceof Error?error93.message:String(error93)}),{hasDrift:!1,signals:[],summary:"",analyzedAt}}}function buildDriftSummary(signals){if(signals.length===0)return"";let warnings=signals.filter((s)=>s.severity==="warning"),errors5=signals.filter((s)=>s.severity==="error"),lines=["[SWARM DECISION DRIFT]"];if(errors5.length>0){lines.push(`⚠️ ${errors5.length} contradiction(s) detected:`);for(let err of errors5.slice(0,2)){let related=err.relatedDecisions?` (${err.relatedDecisions[0].substring(0,30)}... vs ${err.relatedDecisions[1].substring(0,30)}...)`:"";lines.push(` - ${err.type}: ${err.message}${related}`)}}if(warnings.length>0){lines.push(`\uD83D\uDCA1 ${warnings.length} stale decision(s) found:`);for(let warn2 of warnings.slice(0,3)){let hint=warn2.hint?` - ${warn2.hint}`:"";lines.push(` - ${warn2.message.substring(0,60)}${hint}`)}}return lines.push("See .swarm/context.md for details."),lines.join(`
6196
6203
  `)}function formatDriftForContext(result){if(!result.hasDrift||!result.summary)return"";let maxLength=600,summary=result.summary;if(summary.length>maxLength)summary=`${summary.substring(0,maxLength-3)}...`;return summary}init_config_doctor();init_diagnose_service();init_evidence_service();init_evidence_summary_service();init_export_service();init_handoff_service();init_history_service();init_plan_service();init_preflight_integration();init_preflight_service();init_status_service();function charsToTokens(chars){if(chars<=0)return 0;return Math.ceil(chars*0.33)}function allocateInjectionBudget(systemEnhancerDemandTokens,knowledgeInjectorDemandChars,config3){let budget=config3.totalBudgetTokens,seDemand=Math.max(0,systemEnhancerDemandTokens),kiChars=Math.max(0,knowledgeInjectorDemandChars),ceiling=Math.max(0,budget),kiDemand=charsToTokens(kiChars);if(seDemand+kiDemand<=ceiling)return{systemEnhancerTokens:seDemand,knowledgeInjectorTokens:kiDemand,totalTokens:seDemand+kiDemand};if(seDemand>=ceiling)return{systemEnhancerTokens:ceiling,knowledgeInjectorTokens:0,totalTokens:ceiling};if(kiDemand>=ceiling)return{systemEnhancerTokens:0,knowledgeInjectorTokens:ceiling,totalTokens:ceiling};let totalDemand=seDemand+kiDemand,seShare=Math.floor(seDemand/totalDemand*ceiling),kiShare=ceiling-seShare;return{systemEnhancerTokens:seShare,knowledgeInjectorTokens:kiShare,totalTokens:ceiling}}var sessionBudgets=new Map,MAX_TRACKED_SESSIONS5=256;function evictSessionBudgets(){while(sessionBudgets.size>MAX_TRACKED_SESSIONS5){let firstKey=sessionBudgets.keys().next().value;if(firstKey===void 0)break;sessionBudgets.delete(firstKey)}}function resetUnifiedBudget(sessionID,totalBudget){sessionBudgets.set(sessionID,{total:totalBudget,used:0,seDemand:0}),evictSessionBudgets()}function setSystemEnhancerDemand(sessionID,demand){let budget=sessionBudgets.get(sessionID);if(!budget)return;budget.seDemand=demand}function getSystemEnhancerDemand(sessionID){return sessionBudgets.get(sessionID)?.seDemand??0}init_telemetry();init_co_change_analyzer();init_utils();init_agent_model();init_constants();init_schema();init_arg_hash();import*as fs122 from"node:fs/promises";import*as path224 from"node:path";function resolveAgentModel(agentName,config3){let baseAgentName=stripKnownSwarmPrefix(agentName).toLowerCase(),roleDefault=Object.hasOwn(DEFAULT_MODELS,baseAgentName)?DEFAULT_MODELS[baseAgentName]:void 0;return resolveRegisteredAgentModel(config3,agentName)??roleDefault??DEFAULT_MODELS.default}function detectAdversarialPair(agentA,agentB,config3){let modelA=resolveAgentModel(agentA,config3).toLowerCase(),modelB=resolveAgentModel(agentB,config3).toLowerCase();return modelA===modelB?modelA:null}function formatAdversarialWarning(agentA,agentB,sharedModel,policy){if(policy==="gate")return`⚠️ GATE POLICY: Same-model adversarial pair detected. Agent ${agentA} and checker ${agentB} both use model ${sharedModel}. This requires extra scrutiny — escalate if issues are found.`;return`⚠️ Same-model adversarial pair detected. Agent ${agentA} and checker ${agentB} both use model ${sharedModel}. Review may lack independence.`}var PRECEDENT_MANIPULATION_PATTERNS=[/we skipped .* in phase \d+/i,/consistent with how we handled/i,/going forward/i,/the reviewer didn't flag this pattern before/i,/this is consistent with/i,/we should continue/i],SELF_REVIEW_PATTERNS=[/I (verified|checked|reviewed|validated).*(myself|my own)/i,/I (think|believe) this (looks|is) correct/i,/this (looks|seems|appears) (good|correct|fine)/i],CONTENT_EXEMPTION_PATTERNS=[/documentation doesn't need/i,/config changes are trivial/i,/just a (rename|refactor|typo)/i,/test files don't need/i,/this is (just|only) a/i,/no need for (review|the full)/i],GATE_DELEGATION_BYPASS_PATTERNS=[/I verified the changes/i,/code looks correct to me/i,/the code looks (good|fine)/i,/task marked complete/i,/I (checked|reviewed).*myself/i,/edit tool on (src|tests|config)/i,/write tool on (src|tests|config)/i,/writeCount.*\d+.*source/i,/I'll just make this small fix directly/i,/It's faster if I do it myself/i,/edit tool on.*plan\.md/i,/write tool on.*plan\.md/i,/\[ \].*to \[x\].*in plan\.md/i,/status.*pending.*complete.*plan\.json/i,/I'll just mark this one as done/i,/mark it done directly/i,/SPEC_STALENESS_SKIP/i,/SWARM_SKIP_SPEC_GATE/i],GATE_MISCLASSIFICATION_PATTERNS=[/(?:src\/|source\/|source\s+code|source\s+file).*tier\s*[01]/i,/tier\s*[01].*(?:src\/|source\/|source\s+code|source\s+file)/i,/(?:security|auth|crypto|secret|credential|permission).*tier\s*[012]/i,/tier\s*[012].*(?:security|auth|crypto|secret|credential|permission)/i,/below\s+tier\s*3.*(?:security|auth|crypto|secret|credential|permission)/i,/classification[:\s-]*tier\s*[01]/i,/tier\s*[01][\s:]*classification/i,/(?:small|trivial|minor).*tier\s*[01]/i,/tier\s*[01].*(?:small|trivial|minor)/i,/(?:small|trivial|minor).*(?:classification|classified|assigned).*tier/i,/(?:classification|classified|assigned).*(?:small|trivial|minor).*tier/i,/pipeline\s+started.*(?:assigning|setting|classifying).*tier/i,/(?:assigning|setting|classifying).*tier.*after.*pipeline/i,/tier.*assigned.*(?:after|retroactive)/i,/retroactive.*(?:tier|classification)/i],VELOCITY_RATIONALIZATION_PATTERNS=[/to save time/i,/since we're behind/i,/quick fix/i,/review.*later/i,/in the interest of efficiency/i,/we can (review|check).*later/i,/for (speed|efficiency)/i],INTER_AGENT_MANIPULATION_PATTERNS=[/\b(5th|fifth|final|last)\s+(attempt|try|time)\b/i,/\bthis\s+is\s+(blocking|blocking\s+everything|critical|urgent)\b/i,/\bwe('re|\s+are)\s+(behind|late|running\s+out\s+of\s+time)\b/i,/\buser\s+is\s+waiting\b/i,/\bship\s+(this|it)\s+(now|today|immediately)\b/i,/\b(I'm|I\s+am)\s+(frustrated|disappointed|sad|upset)\b/i,/\bthis\s+is\s+(frustrating|disappointing)\b/i,/\b(I've|I\s+have)\s+been\s+working\s+on\s+this\b/i,/\bplease\s+(help|approve|pass)\b/i,/\bor\s+I('ll|\s+will)\s+(stop|halt|pause)\b/i,/\bor\s+all\s+work\s+stops\b/i,/\bI('ll|\s+will)\s+have\s+to\s+alert\s+the\s+user\b/i,/\bthis\s+will\s+(delay|block)\s+everything\b/i,/\bjust\s+approve\s+this\b/i,/\bI\s+(need|want)\s+you\s+to\s+(approve|pass)\b/i,/\boverride\s+(this|the)\s+(check|gate|review)\b/i],REJECTION_SPIRAL_PATTERNS=[/\b(?:rejected|failed\s+review|needs\s+revision)\b.*\b(?:again|third\s+time|4th\s+time|5th\s+time|for\s+the\s+\d+(?:st|nd|rd|th)\s+time)\b/i,/\b(?:same\s+feedback|same\s+issues?)\b.*\b(?:again|repeated|multiple\s+times?)\b/i,/\b(?:stuck|trapped|endless|repeating)\b.*\b(?:loop|cycle)\b/i];function detectAdversarialPatterns(text){if(typeof text!=="string")return[];let matches=[];for(let pattern of PRECEDENT_MANIPULATION_PATTERNS){let match=text.match(pattern);if(match)matches.push({pattern:"PRECEDENT_MANIPULATION",severity:"HIGHEST",matchedText:match[0],confidence:"HIGH"})}for(let pattern of SELF_REVIEW_PATTERNS){let match=text.match(pattern);if(match)matches.push({pattern:"SELF_REVIEW",severity:"HIGH",matchedText:match[0],confidence:"HIGH"})}for(let pattern of CONTENT_EXEMPTION_PATTERNS){let match=text.match(pattern);if(match)matches.push({pattern:"CONTENT_EXEMPTION",severity:"HIGH",matchedText:match[0],confidence:"HIGH"})}for(let pattern of GATE_DELEGATION_BYPASS_PATTERNS){let match=text.match(pattern);if(match)matches.push({pattern:"GATE_DELEGATION_BYPASS",severity:"HIGHEST",matchedText:match[0],confidence:"HIGH"})}for(let pattern of GATE_MISCLASSIFICATION_PATTERNS){let match=text.match(pattern);if(match)matches.push({pattern:"GATE_MISCLASSIFICATION",severity:"HIGH",matchedText:match[0],confidence:"HIGH"})}for(let pattern of VELOCITY_RATIONALIZATION_PATTERNS){let match=text.match(pattern);if(match)matches.push({pattern:"VELOCITY_RATIONALIZATION",severity:"HIGH",matchedText:match[0],confidence:"HIGH"})}for(let pattern of INTER_AGENT_MANIPULATION_PATTERNS){let match=text.match(pattern);if(match)matches.push({pattern:"INTER_AGENT_MANIPULATION",severity:"HIGH",matchedText:match[0],confidence:"HIGH"})}for(let pattern of REJECTION_SPIRAL_PATTERNS){let match=text.match(pattern);if(match)matches.push({pattern:"REJECTION_SPIRAL",severity:"HIGH",matchedText:match[0],confidence:"HIGH"})}return matches}function formatDebuggingSpiralEvent(match,taskId){return JSON.stringify({event:"debugging_spiral_detected",taskId,pattern:match.pattern,severity:match.severity,matchedText:match.matchedText,confidence:match.confidence,timestamp:new Date().toISOString()})}async function handleDebuggingSpiral(match,taskId,directory){let eventLogged=!1,checkpointCreated=!1;try{let swarmDir=path224.join(directory,".swarm");await fs122.mkdir(swarmDir,{recursive:!0});let eventsPath=path224.join(swarmDir,"events.jsonl");await fs122.appendFile(eventsPath,`${formatDebuggingSpiralEvent(match,taskId)}
@@ -6271,11 +6278,11 @@ ${activitySection}`;break}if(contextSummary.length>maxChars)return`${contextSumm
6271
6278
  ${preview}
6272
6279
  ${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;let exemptTools=config3.exempt_tools??[];if(SUMMARIZER_EXEMPT_TOOL_NAMES.includes(input.tool)||exemptTools.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_schema();init_engine2();init_runtime2();init_state2();init_logger();init_normalize_tool_name();init_utils2();import*as fs127 from"node:fs";var MAX_TRACKED_SESSIONS7=256,COOLDOWN_MS=60000;function injectAutoReviewAdvisory(injectAdvisory,sessionID,message){try{injectAdvisory(sessionID,message)}catch(error93){warn(`[auto-review] advisory injection failed: ${error93 instanceof Error?error93.message:String(error93)}`)}}function evictCooldownMap(lastDispatchBySession){while(lastDispatchBySession.size>MAX_TRACKED_SESSIONS7){let firstKey=lastDispatchBySession.keys().next().value;if(firstKey===void 0)break;lastDispatchBySession.delete(firstKey)}}function writeAutoReviewEvent(directory,event){try{let eventsPath=validateSwarmPath(directory,"events.jsonl");fs127.appendFileSync(eventsPath,`${JSON.stringify(event)}
6273
6280
  `,"utf8")}catch(error93){warn(`[auto-review] event write failed: ${error93 instanceof Error?error93.message:String(error93)}`)}}async function runAutoReview(input){if(!input.dispatcher){writeAutoReviewEvent(input.directory,{type:"auto_review",timestamp:new Date().toISOString(),session_id:input.sessionID,trigger:"task_completion",task_id:input.taskId,verdict:"error",detail:"review runtime unavailable",model_calls:0});return}try{let agents=resolveReviewAgentNames(input.generatedAgentNames??swarmState.generatedAgentNames,input.activeAgentName),result=await _internals171.runReviewEngine({directory:input.directory,sessionID:input.sessionID,trigger:"task_completion",selector:{kind:"working-tree"},config:input.config,dispatcher:input.dispatcher,reviewerAgent:agents.reviewer,validatorAgent:agents.validator,reviewerFallbackModels:resolveReviewFallbackModels(agents.reviewer,input.agentModelRegistry),validatorModel:optionalModelOverride(input.config.validation_model),validatorFallbackModels:resolveReviewFallbackModels(agents.validator,input.agentModelRegistry),injectAdvisory:input.injectAdvisory});return writeAutoReviewEvent(input.directory,{type:"auto_review",timestamp:new Date().toISOString(),session_id:input.sessionID,trigger:"task_completion",task_id:input.taskId,verdict:result.reviewVerdict??result.status,detail:result.message,receipt_path:result.receiptPath,evidence_path:result.evidencePath,scope_hash:result.scopeHash,model_calls:result.modelCalls}),result}catch(error93){warn(`[auto-review] run failed: ${error93 instanceof Error?error93.message:String(error93)}`),writeAutoReviewEvent(input.directory,{type:"auto_review",timestamp:new Date().toISOString(),session_id:input.sessionID,trigger:"task_completion",task_id:input.taskId,verdict:"error",detail:error93 instanceof Error?error93.message:String(error93),model_calls:0});return}}function createAutoReviewHook(options){let config3=AutoReviewConfigSchema.parse(options.config),inFlightSessions=new Set,lastDispatchBySession=new Map,resetTracking=()=>{inFlightSessions.clear(),lastDispatchBySession.clear()},generatedAgentNames=options.generatedAgentNames?Object.freeze([...options.generatedAgentNames]):void 0;if(!(config3.enabled&&(config3.trigger==="task_completion"||config3.trigger==="both")))return{toolAfter:async()=>{},resetTracking};return{resetTracking,toolAfter:async(input,context)=>{try{let tool3=(normalizeToolName(input.tool)??input.tool??"").toLowerCase(),args2=context.args??void 0;if(tool3!=="update_task_status"||args2?.status!=="completed"||!input.sessionID)return;let agentName=options.getActiveAgentName?.(input.sessionID)??swarmState.activeAgent.get(input.sessionID)??swarmState.agentSessions.get(input.sessionID)?.agentName??"";if(agentName&&stripKnownSwarmPrefix(agentName)!=="architect")return;if(inFlightSessions.has(input.sessionID))return;let now2=_internals171.now();if(now2-(lastDispatchBySession.get(input.sessionID)??0)<COOLDOWN_MS)return;let taskId=typeof args2.task_id==="string"?args2.task_id:void 0;if(inFlightSessions.size>=MAX_TRACKED_SESSIONS7){let detail=`active review capacity reached (${MAX_TRACKED_SESSIONS7}); task-completion review skipped`;writeAutoReviewEvent(options.directory,{type:"auto_review",timestamp:new Date().toISOString(),session_id:input.sessionID,trigger:"task_completion",task_id:taskId,verdict:"skipped",detail,model_calls:0}),injectAutoReviewAdvisory(options.injectAdvisory,input.sessionID,`[AUTO-REVIEW TASK_COMPLETION] ${detail}. Completion remains fail-open.`);return}inFlightSessions.add(input.sessionID),lastDispatchBySession.delete(input.sessionID),lastDispatchBySession.set(input.sessionID,now2),evictCooldownMap(lastDispatchBySession);let runInput={directory:options.directory,sessionID:input.sessionID,trigger:"task_completion",taskId,config:config3,dispatcher:options.dispatcher,generatedAgentNames,activeAgentName:agentName||void 0,agentModelRegistry:options.agentModelRegistry,injectAdvisory:options.injectAdvisory},pending;try{pending=Promise.resolve(_internals171.runAutoReview(runInput))}catch(error93){inFlightSessions.delete(input.sessionID);let detail=`unexpected review scheduler failure: ${error93 instanceof Error?error93.message:String(error93)}`;writeAutoReviewEvent(options.directory,{type:"auto_review",timestamp:new Date().toISOString(),session_id:input.sessionID,trigger:"task_completion",task_id:taskId,verdict:"error",detail,model_calls:0}),injectAutoReviewAdvisory(options.injectAdvisory,input.sessionID,`[AUTO-REVIEW TASK_COMPLETION] ${detail}. Completion remains fail-open.`);return}pending.catch((error93)=>{let detail=`unexpected review scheduler rejection: ${error93 instanceof Error?error93.message:String(error93)}`;writeAutoReviewEvent(options.directory,{type:"auto_review",timestamp:new Date().toISOString(),session_id:input.sessionID,trigger:"task_completion",task_id:taskId,verdict:"error",detail,model_calls:0}),injectAutoReviewAdvisory(options.injectAdvisory,input.sessionID,`[AUTO-REVIEW TASK_COMPLETION] ${detail}. Completion remains fail-open.`)}).finally(()=>{inFlightSessions.delete(input.sessionID)})}catch(error93){warn(`[auto-review] hook error: ${error93 instanceof Error?error93.message:String(error93)}`)}}}}var _internals171={runReviewEngine,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(`
6274
- `);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 appendFile24,mkdir as mkdir48}from"node:fs/promises";import*as path231 from"node:path";init_task_file();init_logger();init_knowledge_link();init_knowledge_store();var import_proper_lockfile13=__toESM(require_proper_lockfile(),1);import{existsSync as existsSync115}from"node:fs";import{appendFile as appendFile23,mkdir as mkdir47,readFile as readFile50}from"node:fs/promises";import*as path230 from"node:path";function resolveApplicationLogPath(directory){return path230.join(resolveKnowledgeStoreDir(directory),"knowledge-application.jsonl")}var MAX_LEGACY_APPLICATION_LOG_ENTRIES=5000,EXACT_ACK_PATTERN=/KNOWLEDGE_(APPLIED|IGNORED|CONTRADICTED|VIOLATED|N_A)\s*:\s*([^:\s]{1,512})\s*:\s*([^:\s]{1,512})(?:\s+reason\s*=\s*([^\n\r]+?)(?=$|[\n\r]|\s+KNOWLEDGE_))?/gi,LEGACY_ACK_PATTERN=/KNOWLEDGE_(APPLIED|IGNORED|CONTRADICTED|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-]|$)/gi;function decodeAckToken(token){try{let decoded=decodeURIComponent(token);return decoded.length>0&&decoded.length<=512?decoded:void 0}catch{return}}function parseAcknowledgments(text){if(!text||typeof text!=="string")return[];let indexed=[],parseResult=(verb)=>verb==="applied"?"applied":verb==="ignored"?"ignored":verb==="contradicted"?"contradicted":verb==="n_a"?"n_a":"violated";for(let m of text.matchAll(EXACT_ACK_PATTERN)){let verb=m[1].toLowerCase(),traceId=decodeAckToken(m[2]),id=decodeAckToken(m[3]);if(!id||!traceId)continue;let reason=m[4]?.trim().slice(0,280);indexed.push({index:m.index??0,ack:{id,trace_id:traceId,result:parseResult(verb),reason}})}for(let m of text.matchAll(LEGACY_ACK_PATTERN)){let end=(m.index??0)+m[0].length;if(text.slice(end).trimStart().startsWith(":"))continue;indexed.push({index:m.index??0,ack:{id:m[2],result:parseResult(m[1].toLowerCase()),reason:m[3]?.trim().slice(0,280)}})}return indexed.sort((a,b)=>a.index-b.index).map(({ack})=>ack)}async function appendAudit(directory,record3){let filePath=resolveApplicationLogPath(directory),dirPath=path230.dirname(filePath);await mkdir47(dirPath,{recursive:!0});let release;try{release=await import_proper_lockfile13.default.lock(dirPath,{retries:{retries:50,minTimeout:10,maxTimeout:100},stale:5000}),await appendFile23(filePath,`${JSON.stringify(record3)}
6281
+ `);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 appendFile24,mkdir as mkdir48}from"node:fs/promises";import*as path231 from"node:path";init_task_file();init_logger();init_knowledge_link();init_knowledge_store();var import_proper_lockfile13=__toESM(require_proper_lockfile(),1);import{existsSync as existsSync116}from"node:fs";import{appendFile as appendFile23,mkdir as mkdir47,readFile as readFile50}from"node:fs/promises";import*as path230 from"node:path";function resolveApplicationLogPath(directory){return path230.join(resolveKnowledgeStoreDir(directory),"knowledge-application.jsonl")}var MAX_LEGACY_APPLICATION_LOG_ENTRIES=5000,EXACT_ACK_PATTERN=/KNOWLEDGE_(APPLIED|IGNORED|CONTRADICTED|VIOLATED|N_A)\s*:\s*([^:\s]{1,512})\s*:\s*([^:\s]{1,512})(?:\s+reason\s*=\s*([^\n\r]+?)(?=$|[\n\r]|\s+KNOWLEDGE_))?/gi,LEGACY_ACK_PATTERN=/KNOWLEDGE_(APPLIED|IGNORED|CONTRADICTED|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-]|$)/gi;function decodeAckToken(token){try{let decoded=decodeURIComponent(token);return decoded.length>0&&decoded.length<=512?decoded:void 0}catch{return}}function parseAcknowledgments(text){if(!text||typeof text!=="string")return[];let indexed=[],parseResult=(verb)=>verb==="applied"?"applied":verb==="ignored"?"ignored":verb==="contradicted"?"contradicted":verb==="n_a"?"n_a":"violated";for(let m of text.matchAll(EXACT_ACK_PATTERN)){let verb=m[1].toLowerCase(),traceId=decodeAckToken(m[2]),id=decodeAckToken(m[3]);if(!id||!traceId)continue;let reason=m[4]?.trim().slice(0,280);indexed.push({index:m.index??0,ack:{id,trace_id:traceId,result:parseResult(verb),reason}})}for(let m of text.matchAll(LEGACY_ACK_PATTERN)){let end=(m.index??0)+m[0].length;if(text.slice(end).trimStart().startsWith(":"))continue;indexed.push({index:m.index??0,ack:{id:m[2],result:parseResult(m[1].toLowerCase()),reason:m[3]?.trim().slice(0,280)}})}return indexed.sort((a,b)=>a.index-b.index).map(({ack})=>ack)}async function appendAudit(directory,record3){let filePath=resolveApplicationLogPath(directory),dirPath=path230.dirname(filePath);await mkdir47(dirPath,{recursive:!0});let release;try{release=await import_proper_lockfile13.default.lock(dirPath,{retries:{retries:50,minTimeout:10,maxTimeout:100},stale:5000}),await appendFile23(filePath,`${JSON.stringify(record3)}
6275
6282
  `,"utf-8");try{let lines=(await readFile50(filePath,"utf-8")).split(`
6276
6283
  `).filter((line)=>line.trim().length>0);if(lines.length>MAX_LEGACY_APPLICATION_LOG_ENTRIES){let trimmed=lines.slice(-MAX_LEGACY_APPLICATION_LOG_ENTRIES);await atomicWriteFile(filePath,`${trimmed.join(`
6277
6284
  `)}
6278
- `)}}catch(err){warn(`[knowledge-application] appendAudit cap failed: ${err instanceof Error?err.message:String(err)}`)}}finally{if(release)await release().catch(()=>{})}}async function bumpCountersBatch(directory,bumps){let filteredBumps=bumps.filter((b)=>b.ids.length>0);if(filteredBumps.length===0)return;let idToFields=new Map;for(let b of filteredBumps)for(let id of b.ids){let list=idToFields.get(id);if(list)list.push(b.field);else idToFields.set(id,[b.field])}let now2=new Date().toISOString(),applyOne=(entries)=>{let updated=!1;for(let e of entries){let fields=idToFields.get(e.id);if(!fields)continue;let ro=e.retrieval_outcomes;for(let field of fields){if(ro[field]=(ro[field]??0)+1,field==="applied_explicit_count")e.last_applied_at=now2;if(field==="acknowledged_count")e.last_acknowledged_at=now2;updated=!0}}return updated?entries:null},swarmPath3=resolveSwarmKnowledgePath(directory);await transactKnowledge(swarmPath3,applyOne);let hivePath=resolveHiveKnowledgePath2();if(existsSync115(hivePath))await transactKnowledge(hivePath,applyOne)}async function bumpCounters(directory,ids,field){return bumpCountersBatch(directory,[{ids,field}])}async function recordKnowledgeShown(directory,ids,ctx){if(ids.length===0)return;try{let ts=new Date().toISOString();for(let id of ids)await appendAudit(directory,{timestamp:ts,phase:ctx.phase,taskId:ctx.taskId,action:ctx.action,tool:ctx.tool,targetAgent:ctx.targetAgent,sessionId:ctx.sessionId,knowledgeId:id,result:"shown"});await bumpCounters(directory,ids,"shown_count")}catch(err){warn(`[knowledge-application] recordKnowledgeShown failed: ${err instanceof Error?err.message:String(err)}`)}}async function recordAcknowledgment(directory,ack,ctx){try{let result=ack.result==="n_a"?"acknowledged":ack.result;await appendAudit(directory,{timestamp:new Date().toISOString(),phase:ctx.phase,taskId:ctx.taskId,action:ctx.action,tool:ctx.tool,targetAgent:ctx.targetAgent,sessionId:ctx.sessionId,knowledgeId:ack.id,result,reason:ack.reason});let bumps=[{ids:[ack.id],field:"acknowledged_count"}];if(ack.result==="applied")bumps.push({ids:[ack.id],field:"applied_explicit_count"});else if(ack.result==="ignored")bumps.push({ids:[ack.id],field:"ignored_count"});else if(ack.result==="contradicted")bumps.push({ids:[ack.id],field:"contradicted_count"});else if(ack.result==="violated")bumps.push({ids:[ack.id],field:"violated_count"});await bumpCountersBatch(directory,bumps)}catch(err){warn(`[knowledge-application] recordAcknowledgment failed: ${err instanceof Error?err.message:String(err)}`)}}function buildAckDedupKey(sessionId,id,result,_now=new Date){return`${sessionId}|${id}|${result}`}init_knowledge_escalator();init_knowledge_events();init_schema();init_manager();import{createHash as createHash49}from"node:crypto";init_run_memory();init_state2();init_logger();init_curator_drift();init_extractors();init_agent_names();init_schema();init_state2();init_logger();init_stored_input_args();function resolveAgent(sessionID){if(typeof sessionID==="string"&&sessionID.length>0){let mapped=swarmState.activeAgent.get(sessionID);if(mapped)return mapped}return log("[host-boundary] no activeAgent mapped; defaulting to orchestrator",{sessionID:sessionID??"<none>"}),ORCHESTRATOR_NAME}function isPlainObject7(v){return typeof v==="object"&&v!==null&&!Array.isArray(v)}function toArgs(v){return isPlainObject7(v)?v:null}function resolveToolBeforeContext(input,output){let agent=resolveAgent(input.sessionID),callerRole=stripKnownSwarmPrefix(agent).toLowerCase();return{tool:input.tool,sessionID:input.sessionID,callID:input.callID,agent,callerRole,args:toArgs(output?.args),isArchitect:callerRole===ORCHESTRATOR_NAME}}function resolveToolAfterContext(input){let agent=resolveAgent(input.sessionID),callerRole=stripKnownSwarmPrefix(agent).toLowerCase();return{tool:input.tool,sessionID:input.sessionID,callID:input.callID,agent,callerRole,args:toArgs(getStoredInputArgs(input.callID)),isArchitect:callerRole===ORCHESTRATOR_NAME}}function resolveMessageTransformContext(output){let messages=Array.isArray(output?.messages)?output.messages:[],sessionID;for(let m of messages){let sid=m?.info?.sessionID;if(typeof sid==="string"&&sid.length>0){sessionID=sid;break}}let agent=resolveAgentOptional(sessionID);if(!agent)for(let i=messages.length-1;i>=0;i--){let info=messages[i]?.info;if(info?.role==="user"&&typeof info.agent==="string"&&info.agent){agent=info.agent;break}}let callerRole=agent?stripKnownSwarmPrefix(agent).toLowerCase():void 0;return{sessionID,agent,callerRole,isArchitect:callerRole===ORCHESTRATOR_NAME,isDelegate:!!agent&&!!callerRole&&callerRole!==ORCHESTRATOR_NAME}}function resolveAgentOptional(sessionID){if(typeof sessionID==="string"&&sessionID.length>0){let mapped=swarmState.activeAgent.get(sessionID);if(mapped)return mapped}return}init_knowledge_escalator();init_knowledge_events();init_knowledge_link();init_knowledge_reader();init_knowledge_receipt_ledger();init_knowledge_store();init_knowledge_types();init_model_limits();init_search_knowledge();init_utils2();var INJECTION_SENTINEL=`${String.fromCharCode(8204)}[[KNOWLEDGE-INJECTED]]`,defaultSearchKnowledge=searchKnowledge;function phaseNumberOf(label){if(!label)return;let m=/^Phase\s+(\d+)/i.exec(label);return m?Number(m[1]):void 0}function recordInjectionSkip(directory,reason,detail){_internals172.recordKnowledgeEvent(directory,{type:"injection_skip",reason,agent:detail?.agent,session_id:detail?.sessionId,phase:detail?.phase,detail:detail?.extra}).catch(()=>{})}function buildKnowledgeBlock(entries,charBudget,cfg,currentProject){if(entries.length===0)return{block:null,renderedIds:[]};let maxDisplayChars=cfg.max_lesson_display_chars??120,rendered=entries.map((entry)=>{let tier=entry.tier==="hive"?"[H]":"[S]",confirmedBy=entry.confirmed_by?.length??0,confirm=confirmedBy>=3?" ✓✓":confirmedBy>=1?" ✓":"",lessonText=sanitizeLessonForContext(entry.lesson);if(lessonText.length>maxDisplayChars)lessonText=`${lessonText.slice(0,maxDisplayChars)}…`;let rawSource=entry.tier==="hive"&&"source_project"in entry?entry.source_project??null:null,source=rawSource!==null&&rawSource!==currentProject?` (from: ${sanitizeLessonForContext(rawSource)})`:"";return{id:entry.id,line:`${tier} ${lessonText}${source}${confirm}`}}),header=`\uD83D\uDCDA Lessons:
6285
+ `)}}catch(err){warn(`[knowledge-application] appendAudit cap failed: ${err instanceof Error?err.message:String(err)}`)}}finally{if(release)await release().catch(()=>{})}}async function bumpCountersBatch(directory,bumps){let filteredBumps=bumps.filter((b)=>b.ids.length>0);if(filteredBumps.length===0)return;let idToFields=new Map;for(let b of filteredBumps)for(let id of b.ids){let list=idToFields.get(id);if(list)list.push(b.field);else idToFields.set(id,[b.field])}let now2=new Date().toISOString(),applyOne=(entries)=>{let updated=!1;for(let e of entries){let fields=idToFields.get(e.id);if(!fields)continue;let ro=e.retrieval_outcomes;for(let field of fields){if(ro[field]=(ro[field]??0)+1,field==="applied_explicit_count")e.last_applied_at=now2;if(field==="acknowledged_count")e.last_acknowledged_at=now2;updated=!0}}return updated?entries:null},swarmPath3=resolveSwarmKnowledgePath(directory);await transactKnowledge(swarmPath3,applyOne);let hivePath=resolveHiveKnowledgePath2();if(existsSync116(hivePath))await transactKnowledge(hivePath,applyOne)}async function bumpCounters(directory,ids,field){return bumpCountersBatch(directory,[{ids,field}])}async function recordKnowledgeShown(directory,ids,ctx){if(ids.length===0)return;try{let ts=new Date().toISOString();for(let id of ids)await appendAudit(directory,{timestamp:ts,phase:ctx.phase,taskId:ctx.taskId,action:ctx.action,tool:ctx.tool,targetAgent:ctx.targetAgent,sessionId:ctx.sessionId,knowledgeId:id,result:"shown"});await bumpCounters(directory,ids,"shown_count")}catch(err){warn(`[knowledge-application] recordKnowledgeShown failed: ${err instanceof Error?err.message:String(err)}`)}}async function recordAcknowledgment(directory,ack,ctx){try{let result=ack.result==="n_a"?"acknowledged":ack.result;await appendAudit(directory,{timestamp:new Date().toISOString(),phase:ctx.phase,taskId:ctx.taskId,action:ctx.action,tool:ctx.tool,targetAgent:ctx.targetAgent,sessionId:ctx.sessionId,knowledgeId:ack.id,result,reason:ack.reason});let bumps=[{ids:[ack.id],field:"acknowledged_count"}];if(ack.result==="applied")bumps.push({ids:[ack.id],field:"applied_explicit_count"});else if(ack.result==="ignored")bumps.push({ids:[ack.id],field:"ignored_count"});else if(ack.result==="contradicted")bumps.push({ids:[ack.id],field:"contradicted_count"});else if(ack.result==="violated")bumps.push({ids:[ack.id],field:"violated_count"});await bumpCountersBatch(directory,bumps)}catch(err){warn(`[knowledge-application] recordAcknowledgment failed: ${err instanceof Error?err.message:String(err)}`)}}function buildAckDedupKey(sessionId,id,result,_now=new Date){return`${sessionId}|${id}|${result}`}init_knowledge_escalator();init_knowledge_events();init_schema();init_manager();import{createHash as createHash49}from"node:crypto";init_run_memory();init_state2();init_logger();init_curator_drift();init_extractors();init_agent_names();init_schema();init_state2();init_logger();init_stored_input_args();function resolveAgent(sessionID){if(typeof sessionID==="string"&&sessionID.length>0){let mapped=swarmState.activeAgent.get(sessionID);if(mapped)return mapped}return log("[host-boundary] no activeAgent mapped; defaulting to orchestrator",{sessionID:sessionID??"<none>"}),ORCHESTRATOR_NAME}function isPlainObject7(v){return typeof v==="object"&&v!==null&&!Array.isArray(v)}function toArgs(v){return isPlainObject7(v)?v:null}function resolveToolBeforeContext(input,output){let agent=resolveAgent(input.sessionID),callerRole=stripKnownSwarmPrefix(agent).toLowerCase();return{tool:input.tool,sessionID:input.sessionID,callID:input.callID,agent,callerRole,args:toArgs(output?.args),isArchitect:callerRole===ORCHESTRATOR_NAME}}function resolveToolAfterContext(input){let agent=resolveAgent(input.sessionID),callerRole=stripKnownSwarmPrefix(agent).toLowerCase();return{tool:input.tool,sessionID:input.sessionID,callID:input.callID,agent,callerRole,args:toArgs(getStoredInputArgs(input.callID)),isArchitect:callerRole===ORCHESTRATOR_NAME}}function resolveMessageTransformContext(output){let messages=Array.isArray(output?.messages)?output.messages:[],sessionID;for(let m of messages){let sid=m?.info?.sessionID;if(typeof sid==="string"&&sid.length>0){sessionID=sid;break}}let agent=resolveAgentOptional(sessionID);if(!agent)for(let i=messages.length-1;i>=0;i--){let info=messages[i]?.info;if(info?.role==="user"&&typeof info.agent==="string"&&info.agent){agent=info.agent;break}}let callerRole=agent?stripKnownSwarmPrefix(agent).toLowerCase():void 0;return{sessionID,agent,callerRole,isArchitect:callerRole===ORCHESTRATOR_NAME,isDelegate:!!agent&&!!callerRole&&callerRole!==ORCHESTRATOR_NAME}}function resolveAgentOptional(sessionID){if(typeof sessionID==="string"&&sessionID.length>0){let mapped=swarmState.activeAgent.get(sessionID);if(mapped)return mapped}return}init_knowledge_escalator();init_knowledge_events();init_knowledge_link();init_knowledge_reader();init_knowledge_receipt_ledger();init_knowledge_store();init_knowledge_types();init_model_limits();init_search_knowledge();init_utils2();var INJECTION_SENTINEL=`${String.fromCharCode(8204)}[[KNOWLEDGE-INJECTED]]`,defaultSearchKnowledge=searchKnowledge;function phaseNumberOf(label){if(!label)return;let m=/^Phase\s+(\d+)/i.exec(label);return m?Number(m[1]):void 0}function recordInjectionSkip(directory,reason,detail){_internals172.recordKnowledgeEvent(directory,{type:"injection_skip",reason,agent:detail?.agent,session_id:detail?.sessionId,phase:detail?.phase,detail:detail?.extra}).catch(()=>{})}function buildKnowledgeBlock(entries,charBudget,cfg,currentProject){if(entries.length===0)return{block:null,renderedIds:[]};let maxDisplayChars=cfg.max_lesson_display_chars??120,rendered=entries.map((entry)=>{let tier=entry.tier==="hive"?"[H]":"[S]",confirmedBy=entry.confirmed_by?.length??0,confirm=confirmedBy>=3?" ✓✓":confirmedBy>=1?" ✓":"",lessonText=sanitizeLessonForContext(entry.lesson);if(lessonText.length>maxDisplayChars)lessonText=`${lessonText.slice(0,maxDisplayChars)}…`;let rawSource=entry.tier==="hive"&&"source_project"in entry?entry.source_project??null:null,source=rawSource!==null&&rawSource!==currentProject?` (from: ${sanitizeLessonForContext(rawSource)})`:"";return{id:entry.id,line:`${tier} ${lessonText}${source}${confirm}`}}),header=`\uD83D\uDCDA Lessons:
6279
6286
  `,block=`${header}
6280
6287
  ${rendered.map((r)=>r.line).join(`
6281
6288
  `)}`;while(block.length>charBudget&&rendered.length>0)rendered.pop(),block=`${header}
@@ -6292,7 +6299,7 @@ ${freshPreamble}`:`<curator_briefing>${truncatedBriefing}</curator_briefing>`}}c
6292
6299
  `);if(rejectedBlock.length<=remaining)parts.push(rejectedBlock)}}catch(err){warn(`[knowledge-injector] rejected pattern warnings unavailable: ${err instanceof Error?err.message:String(err)}`)}cachedInjectionText=parts.join(`
6293
6300
 
6294
6301
  `);let criticalIds=filteredEntries.filter((e)=>renderedDirectiveIdSet.has(e.id)).filter((e)=>e.directive_priority==="critical"&&isActiveStatus(e.status)).map((e)=>e.id);if(cachedShownIds.length>0){let byId=new Map(filteredEntries.map((entry)=>[entry.id,entry])),cohortId=await _internals172.ensureCohortIdCached(directory,sessionId),sourceLinkId=_internals172.readLinkPointer(directory)?.linkId,membership=await _internals172.commitDisplayedMembership(directory,{trace_id:search.trace_id,session_id:sessionId,exposure_kind:"architect_directive",phase:retrievalCtx.currentPhase,task_id:retrievalCtx.taskId,agent:"architect",cohort_id:cohortId,source_link_id:sourceLinkId,grace_days:config3.receipt_close_grace_days,entries:cachedShownIds.map((id,index)=>({entry_id:id,critical:criticalIds.includes(id),rank:index+1,score:byId.get(id)?.finalScore}))});if(!membership.ok||membership.memberships.some((item)=>item.terminal)){if(cachedInjectionText="",cachedShownIds=[],cachedCriticalIds=[],sessionId)clearCriticalShownIds(sessionId);recordInjectionSkip(directory,membership.ok?"terminal_trace_reuse":membership.code,{agent:agentName,sessionId,phase:currentPhase,extra:{trace_id:search.trace_id}});return}}injectKnowledgeMessage(output,cachedInjectionText);let sessionID=sessionId;if(sessionID)if(cachedCriticalIds=criticalIds,criticalIds.length>0)setCriticalShownIds(sessionID,{ids:criticalIds,phase:`Phase ${currentPhase}`,generatedAt:Date.now()});else clearCriticalShownIds(sessionID);if(cachedShownIds.length>0){let phaseLabel=`Phase ${currentPhase}`,scoreById=new Map(filteredEntries.map((e)=>[e.id,e.finalScore])),ranks={},scores={};cachedShownIds.forEach((id,idx)=>{ranks[id]=idx+1,scores[id]=scoreById.get(id)??0}),await _internals172.recordKnowledgeEvent(directory,{type:"retrieved",trace_id:search.trace_id,session_id:sessionId,phase:retrievalCtx.currentPhase,task_id:retrievalCtx.taskId,agent:"architect",query:retrievalCtx.lastUserMessage??retrievalCtx.currentPhase??"",retrieval_mode:"auto_injection",result_ids:cachedShownIds,ranks,scores}),_internals172.recordKnowledgeShown(directory,cachedShownIds,{phase:phaseLabel,tool:retrievalCtx.currentTool,action:retrievalCtx.currentAction,targetAgent:retrievalCtx.targetAgent,taskId:retrievalCtx.taskId}).catch(()=>{}),_internals172.recordLessonsShown(directory,cachedShownIds,phaseLabel).catch(()=>{}),_internals172.confirmEntriesPhase(directory,cachedShownIds,currentPhase,projectName).catch(()=>{})}})}var _internals172={searchKnowledge,recordKnowledgeEvent,recordKnowledgeShown,readRecentEscalations,buildEscalationBriefing,recordLessonsShown,confirmEntriesPhase,commitDisplayedMembership,commitEmptyRetrieval,queryLiveMemberships,ensureCohortIdCached,readLinkPointer};init_knowledge_link();init_knowledge_receipt_ledger();init_knowledge_receipt_ledger();var NO_TRACE_SENTINEL="none",VALID_OUTCOMES=RECEIPT_TERMINAL_OUTCOMES;function reject(reason,detail,rejected_items){return{ok:!1,rejected:!0,reason,detail,rejected_items}}async function validateReceipt(ctx){let{items,no_relevant_knowledge:noRelevant}=ctx;if(items.length===0&&!noRelevant)return reject("empty_receipt","no items and no_relevant_knowledge is false");if(noRelevant&&items.length>0)return reject("invalid_outcome","no_relevant_knowledge cannot be combined with items");for(let item of items)if(!VALID_OUTCOMES.has(item.outcome))return reject("invalid_outcome",`item ${item.id}: outcome ${item.outcome}`);let traceId=ctx.trace_id||NO_TRACE_SENTINEL;if(traceId===NO_TRACE_SENTINEL){if(items.length>0)return reject("trace_not_found","items filed against the none sentinel trace");let empty=await commitEmptyRetrieval(ctx.directory,{trace_id:traceId,session_id:ctx.session_id,phase:ctx.phase,task_id:ctx.task_id,agent:ctx.agent,grace_days:ctx.grace_days});if(!empty.ok)return reject(empty.code,empty.detail);return{ok:!0,accepted:[],idempotent_skips:[],trace:null,closes_no_relevant:!0,authoritative_event_ids:{},no_relevant_event_id:empty.terminal_event_id}}let committed=await validateAndCommitTerminalBatch(ctx.directory,{trace_id:traceId,session_id:ctx.session_id,phase:ctx.phase,task_id:ctx.task_id,agent:ctx.agent,cohort_id:ctx.cohort_id,source_link_id:ctx.source_link_id,grace_days:ctx.grace_days,items:items.map((item)=>({entry_id:item.id,outcome:item.outcome,reason:item.reason,source:ctx.source.trim()||"unknown"})),no_relevant_knowledge:noRelevant});if(!committed.ok)return reject(committed.code,committed.detail);let remainingItems=[...items],takeItem=(id,outcome)=>{let index=remainingItems.findIndex((item)=>item.id===id&&(outcome===void 0||item.outcome===outcome));if(index<0)return;return remainingItems.splice(index,1)[0]},accepted=committed.accepted.map((item)=>takeItem(item.entry_id,item.outcome)).filter((item)=>item!==void 0),idempotent_skips=committed.idempotent.map((id)=>takeItem(id)).filter((item)=>item!==void 0),rejected_items=committed.rejected.map((item)=>({item:takeItem(item.entry_id)??{id:item.entry_id,outcome:"ignored"},reason:item.reason}));if(rejected_items.length&&accepted.length===0&&idempotent_skips.length===0)return reject(rejected_items[0].reason,`${rejected_items[0].reason} for id ${rejected_items[0].item.id}`,rejected_items);let queried=await queryLiveMemberships(ctx.directory,{session_id:ctx.session_id,include_terminal:!0,grace_days:ctx.grace_days}),memberships=queried.ok?queried.memberships.filter((membership)=>membership.trace_id===traceId):[],trace=memberships.length?{type:"retrieved",event_id:memberships[0].membership_event_id,trace_id:traceId,timestamp:memberships[0].committed_at,session_id:ctx.session_id,phase:memberships[0].phase,task_id:memberships[0].task_id,agent:memberships[0].agent??ctx.agent,query:"",retrieval_mode:"manual",result_ids:memberships.map((membership)=>membership.entry_id),ranks:Object.fromEntries(memberships.map((membership,index)=>[membership.entry_id,membership.rank??index+1])),scores:Object.fromEntries(memberships.map((membership)=>[membership.entry_id,membership.score??0]))}:null;return{ok:!0,accepted,idempotent_skips,trace,closes_no_relevant:committed.closes_no_relevant,authoritative_event_ids:Object.fromEntries(committed.accepted.map((item)=>[item.entry_id,item.event_id])),...committed.terminal_event_id?{no_relevant_event_id:committed.terminal_event_id}:{},...rejected_items.length?{rejected_items}:{}}}init_promotion_evidence_store();init_skill_propagation_gate();init_utils2();function isTaskTool3(tool3){return tool3==="Task"||tool3==="task"}function extractTaskId2(prompt){let m=/\btask[_-]?id\s*[:=]\s*([A-Za-z0-9._-]{1,80})/i.exec(prompt);return m?m[1]:void 0}async function appendUnacknowledgedCritical(directory,record3){let filePath=validateSwarmPath(directory,"unacknowledged-criticals.jsonl");await mkdir48(path231.dirname(filePath),{recursive:!0}),await appendFile24(filePath,`${JSON.stringify(record3)}
6295
- `,"utf-8")}async function collectDelegateAcks(params){let result={emitted:[],unacknowledgedCriticals:[],unacknowledgedNonCritical:[]};try{let shown=parseDelegateDirectiveBlock(params.prompt);if(shown.length===0)return result;let shownById=new Map(shown.map((d)=>[d.id,d])),criticalIds=shown.filter((d)=>d.priority==="critical").map((d)=>d.id),acks=parseAcknowledgments(params.transcript),ackedIds=new Set,violatedIds=new Set,sessionId=params.sessionId;if(!sessionId)return result.unverifiable={code:"missing_session_id",detail:"Delegate acknowledgments require a real host session id"},result;let taskId=params.taskId??extractTaskId2(params.prompt),recoveredTraceId=parseDelegateDirectiveTraceId(params.prompt),traceId=recoveredTraceId??"legacy-unverifiable",isLegacyPrompt=recoveredTraceId===void 0,cohortId,linkId;try{cohortId=await ensureCohortIdCached(params.directory,sessionId),linkId=readLinkPointer(params.directory)?.linkId}catch{}let ackItems=[],ackByItemId=new Map;for(let ack of acks){if(!shownById.has(ack.id))continue;if(ackedIds.add(ack.id),!isLegacyPrompt&&ack.trace_id!==traceId)continue;if(ack.result==="applied"||ack.result==="ignored"||ack.result==="violated"||ack.result==="n_a"||ack.result==="contradicted")ackItems.push({id:ack.id,outcome:ack.result,reason:ack.reason}),ackByItemId.set(ack.id,ack)}let eventIdByKnowledgeId=new Map;if(isLegacyPrompt)for(let ack of acks){if(!shownById.has(ack.id))continue;if(!ackByItemId.has(ack.id))continue;ackedIds.add(ack.id)}else{let validation2=await validateReceipt({directory:params.directory,trace_id:traceId,session_id:sessionId,task_id:taskId,agent:params.agent,source:"delegate",cohort_id:cohortId,source_link_id:linkId,items:ackItems,no_relevant_knowledge:!1});if(validation2.ok){for(let item of validation2.accepted){let ack=ackByItemId.get(item.id);if(!ack)continue;ackedIds.add(item.id),await recordKnowledgeEvent(params.directory,{type:item.outcome,trace_id:traceId,knowledge_id:item.id,session_id:sessionId,task_id:taskId,agent:params.agent,source:"delegate",reason:ack.reason});let authoritativeEventId=validation2.authoritative_event_ids[item.id];if(authoritativeEventId)eventIdByKnowledgeId.set(item.id,authoritativeEventId);if(item.outcome==="violated")violatedIds.add(item.id);result.emitted.push({id:item.id,type:item.outcome})}for(let item of validation2.idempotent_skips)ackedIds.add(item.id);for(let rejected of validation2.rejected_items??[])ackedIds.add(rejected.item.id)}if(!validation2.ok)for(let id of ackByItemId.keys())ackedIds.add(id)}try{let now2=new Date().toISOString(),evidenceRecords=[];for(let[kid,eid]of eventIdByKnowledgeId){let ack=ackByItemId.get(kid);if(!ack||!cohortId)continue;let outcome=ack.result;if(outcome!=="applied"&&outcome!=="violated"&&outcome!=="contradicted")continue;evidenceRecords.push({cohort_id:cohortId,source_link_id:linkId,entry_id:kid,retrieval_trace_id:traceId,receipt_outcome:outcome,receipt_source:"delegate",receipt_event_id:eid,phase:void 0,timestamp:now2})}await appendPromotionEvidence(params.directory,evidenceRecords)}catch{}let missingCriticalIds=criticalIds.filter((id)=>!ackedIds.has(id)),committedMissingCriticalIds=new Set;if(!isLegacyPrompt&&missingCriticalIds.length>0){let committed=await validateAndCommitTerminalBatch(params.directory,{trace_id:traceId,session_id:sessionId,task_id:taskId,agent:params.agent,cohort_id:cohortId,source_link_id:linkId,items:missingCriticalIds.map((entry_id)=>({entry_id,outcome:"violated",source:"delegate",reason:"unacknowledged"}))});if(committed.ok)committedMissingCriticalIds=new Set(committed.committed.map((item)=>item.entry_id))}for(let id of missingCriticalIds){if(!committedMissingCriticalIds.has(id))continue;result.unacknowledgedCriticals.push(id),await recordKnowledgeEvent(params.directory,{type:"violated",trace_id:traceId,knowledge_id:id,session_id:sessionId,task_id:taskId,agent:params.agent,source:"delegate",reason:"unacknowledged"}),violatedIds.add(id),result.emitted.push({id,type:"violated"});try{await appendUnacknowledgedCritical(params.directory,{timestamp:new Date().toISOString(),knowledge_id:id,agent:params.agent,session_id:sessionId,task_id:taskId,reason:"unacknowledged"})}catch{}}let silentEvents=[];for(let[id,directive]of shownById){if(directive.priority==="critical")continue;if(ackedIds.has(id))continue;result.unacknowledgedNonCritical.push(id),silentEvents.push({type:"unacknowledged",trace_id:traceId,knowledge_id:id,session_id:sessionId,task_id:taskId,agent:params.agent,source:"delegate",reason:"no_ack_marker"}),result.emitted.push({id,type:"unacknowledged"})}if(silentEvents.length>0)await recordKnowledgeEventsBatch(params.directory,silentEvents);if(violatedIds.size>0)await escalateViolatedEntries(params.directory,[...violatedIds])}catch{}return result}async function collectDelegateAcksAfter(directory,input,output){if(!isTaskTool3(input.tool))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 agent=parseDelegationArgs(input.args)?.targetAgent??"unknown",sessionId=typeof input.sessionID==="string"?input.sessionID:void 0;await collectDelegateAcks({directory,prompt,transcript,agent,sessionId})}init_reviewer_directive_compliance();init_schema();init_manager();init_logger();init_extractors();init_knowledge_events();init_knowledge_receipt_ledger();init_knowledge_store();init_knowledge_types();import{existsSync as existsSync116}from"node:fs";async function readEntriesById(directory){let map3=new Map,swarm=await readKnowledge(resolveSwarmKnowledgePath(directory));for(let e of swarm)map3.set(e.id,e);let hivePath=resolveHiveKnowledgePath2();if(existsSync116(hivePath)){let hive=await readKnowledge(hivePath);for(let e of hive)if(!map3.has(e.id))map3.set(e.id,e)}return map3}async function readPhaseDirectivesToVerify(directory,phaseLabel){try{let result=await queryLiveMemberships(directory,{phase:phaseLabel||void 0,include_terminal:!0,include_phase_closed:!1});if(!result.ok||result.memberships.length===0)return[];let entries=await readEntriesById(directory),out=[];for(let membership of result.memberships){if(membership.terminal&&membership.terminal.outcome!=="violated")continue;let e=entries.get(membership.entry_id);if(!e)continue;if(!isActiveStatus(e.status))continue;out.push({trace_id:membership.trace_id,entry_id:membership.entry_id,session_id:membership.session_id,cohort_id:membership.cohort_id,source_link_id:membership.source_link_id,prior_terminal_outcome:membership.terminal?.outcome==="violated"?"violated":void 0,prior_terminal_event_id:membership.terminal?.outcome==="violated"?membership.terminal.event_id:void 0,priority:membership.critical?"critical":e.directive_priority??"medium",lesson:e.lesson,verification_predicate:e.verification_predicate})}return out}catch{return[]}}init_skill_propagation_gate();function recordDelegateInjectionSkip(directory,reason,options){recordKnowledgeEvent(directory,{type:"injection_skip",reason,agent:options?.agent,session_id:options?.sessionId,detail:options?.detail}).catch(()=>{})}function isTaskTool4(tool3){return tool3==="Task"||tool3==="task"}function hasDelegateDirectiveBlock(text){return parseDelegateDirectiveBlock(text).length>0}function hasDirectiveComplianceBlock(text){return parseDirectivesToVerifyBlock(text).length>0}async function injectDelegateDirectivesBefore(directory,input,config3){let sessionId;try{sessionId=typeof input.sessionID==="string"?input.sessionID:void 0;let debugSkip=(reason,data)=>{return log("[delegate-directive-injection] skipped",{reason,caller_agent:typeof input.agent==="string"?input.agent:void 0,tool:input.tool,...data}),0};if(config3.enabled===!1)return debugSkip("knowledge_disabled");if(!isTaskTool4(input.tool))return debugSkip("not_task_tool");let callerAgent=typeof input.agent==="string"?input.agent:"",callerRole=stripKnownSwarmPrefix(callerAgent).toLowerCase();if(!callerAgent||callerRole!=="architect")return recordDelegateInjectionSkip(directory,"delegate_caller_not_allowed",{agent:callerAgent||void 0,sessionId,detail:{caller_role:callerRole}}),debugSkip("caller_not_allowed",{caller_role:callerRole});let argsRecord=input.args&&typeof input.args==="object"?input.args:null;if(!argsRecord)return recordDelegateInjectionSkip(directory,"delegate_missing_args",{agent:callerAgent,sessionId}),debugSkip("missing_args");let promptRaw=argsRecord.prompt;if(typeof promptRaw!=="string")return recordDelegateInjectionSkip(directory,"delegate_missing_prompt",{agent:callerAgent,sessionId}),debugSkip("missing_prompt");let parsed=parseDelegationArgs(input.args);if(!parsed)return recordDelegateInjectionSkip(directory,"delegate_unparseable_delegation_args",{agent:callerAgent,sessionId}),debugSkip("unparseable_delegation_args");let targetAgent=parsed.targetAgent;if(!isDelegatedAgent(targetAgent))return recordDelegateInjectionSkip(directory,"delegate_target_not_delegated_agent",{agent:targetAgent,sessionId,detail:{target_agent:targetAgent}}),debugSkip("target_not_delegated_agent",{target_agent:targetAgent});if(hasDelegateDirectiveBlock(promptRaw)||hasDirectiveComplianceBlock(promptRaw))return recordDelegateInjectionSkip(directory,"delegate_already_injected",{agent:targetAgent,sessionId}),debugSkip("already_injected",{target_agent:targetAgent});let plan=await loadPlan(directory).catch(()=>null),phaseLabel=plan?extractCurrentPhaseFromPlan(plan)??`Phase ${plan.current_phase??1}`:void 0,taskId=/\btask[_-]?id\s*[:=]\s*([A-Za-z0-9._-]{1,80})/i.exec(promptRaw)?.[1],{entries,trace_id}=await injectForDelegate({directory,agent:targetAgent,expectedTools:defaultExpectedToolsForAgent(targetAgent),taskTitle:promptRaw.slice(0,800),taskId,sessionId,phase:phaseLabel,config:config3}),prefixParts=[],delegateBlock=buildDelegateDirectiveBlock(entries,config3,trace_id);if(delegateBlock)prefixParts.push(delegateBlock);if(stripKnownSwarmPrefix(targetAgent).toLowerCase()==="reviewer"){let toVerify=await readPhaseDirectivesToVerify(directory,phaseLabel),complianceBlock=buildDirectiveComplianceBlock(toVerify);if(complianceBlock)prefixParts.push(complianceBlock)}if(prefixParts.length===0)return recordDelegateInjectionSkip(directory,"delegate_no_directives_to_inject",{agent:targetAgent,sessionId}),debugSkip("no_directives_to_inject",{target_agent:targetAgent});return argsRecord.prompt=`${prefixParts.join(`
6302
+ `,"utf-8")}async function collectDelegateAcks(params){let result={emitted:[],unacknowledgedCriticals:[],unacknowledgedNonCritical:[]};try{let shown=parseDelegateDirectiveBlock(params.prompt);if(shown.length===0)return result;let shownById=new Map(shown.map((d)=>[d.id,d])),criticalIds=shown.filter((d)=>d.priority==="critical").map((d)=>d.id),acks=parseAcknowledgments(params.transcript),ackedIds=new Set,violatedIds=new Set,sessionId=params.sessionId;if(!sessionId)return result.unverifiable={code:"missing_session_id",detail:"Delegate acknowledgments require a real host session id"},result;let taskId=params.taskId??extractTaskId2(params.prompt),recoveredTraceId=parseDelegateDirectiveTraceId(params.prompt),traceId=recoveredTraceId??"legacy-unverifiable",isLegacyPrompt=recoveredTraceId===void 0,cohortId,linkId;try{cohortId=await ensureCohortIdCached(params.directory,sessionId),linkId=readLinkPointer(params.directory)?.linkId}catch{}let ackItems=[],ackByItemId=new Map;for(let ack of acks){if(!shownById.has(ack.id))continue;if(ackedIds.add(ack.id),!isLegacyPrompt&&ack.trace_id!==traceId)continue;if(ack.result==="applied"||ack.result==="ignored"||ack.result==="violated"||ack.result==="n_a"||ack.result==="contradicted")ackItems.push({id:ack.id,outcome:ack.result,reason:ack.reason}),ackByItemId.set(ack.id,ack)}let eventIdByKnowledgeId=new Map;if(isLegacyPrompt)for(let ack of acks){if(!shownById.has(ack.id))continue;if(!ackByItemId.has(ack.id))continue;ackedIds.add(ack.id)}else{let validation2=await validateReceipt({directory:params.directory,trace_id:traceId,session_id:sessionId,task_id:taskId,agent:params.agent,source:"delegate",cohort_id:cohortId,source_link_id:linkId,items:ackItems,no_relevant_knowledge:!1});if(validation2.ok){for(let item of validation2.accepted){let ack=ackByItemId.get(item.id);if(!ack)continue;ackedIds.add(item.id),await recordKnowledgeEvent(params.directory,{type:item.outcome,trace_id:traceId,knowledge_id:item.id,session_id:sessionId,task_id:taskId,agent:params.agent,source:"delegate",reason:ack.reason});let authoritativeEventId=validation2.authoritative_event_ids[item.id];if(authoritativeEventId)eventIdByKnowledgeId.set(item.id,authoritativeEventId);if(item.outcome==="violated")violatedIds.add(item.id);result.emitted.push({id:item.id,type:item.outcome})}for(let item of validation2.idempotent_skips)ackedIds.add(item.id);for(let rejected of validation2.rejected_items??[])ackedIds.add(rejected.item.id)}if(!validation2.ok)for(let id of ackByItemId.keys())ackedIds.add(id)}try{let now2=new Date().toISOString(),evidenceRecords=[];for(let[kid,eid]of eventIdByKnowledgeId){let ack=ackByItemId.get(kid);if(!ack||!cohortId)continue;let outcome=ack.result;if(outcome!=="applied"&&outcome!=="violated"&&outcome!=="contradicted")continue;evidenceRecords.push({cohort_id:cohortId,source_link_id:linkId,entry_id:kid,retrieval_trace_id:traceId,receipt_outcome:outcome,receipt_source:"delegate",receipt_event_id:eid,phase:void 0,timestamp:now2})}await appendPromotionEvidence(params.directory,evidenceRecords)}catch{}let missingCriticalIds=criticalIds.filter((id)=>!ackedIds.has(id)),committedMissingCriticalIds=new Set;if(!isLegacyPrompt&&missingCriticalIds.length>0){let committed=await validateAndCommitTerminalBatch(params.directory,{trace_id:traceId,session_id:sessionId,task_id:taskId,agent:params.agent,cohort_id:cohortId,source_link_id:linkId,items:missingCriticalIds.map((entry_id)=>({entry_id,outcome:"violated",source:"delegate",reason:"unacknowledged"}))});if(committed.ok)committedMissingCriticalIds=new Set(committed.committed.map((item)=>item.entry_id))}for(let id of missingCriticalIds){if(!committedMissingCriticalIds.has(id))continue;result.unacknowledgedCriticals.push(id),await recordKnowledgeEvent(params.directory,{type:"violated",trace_id:traceId,knowledge_id:id,session_id:sessionId,task_id:taskId,agent:params.agent,source:"delegate",reason:"unacknowledged"}),violatedIds.add(id),result.emitted.push({id,type:"violated"});try{await appendUnacknowledgedCritical(params.directory,{timestamp:new Date().toISOString(),knowledge_id:id,agent:params.agent,session_id:sessionId,task_id:taskId,reason:"unacknowledged"})}catch{}}let silentEvents=[];for(let[id,directive]of shownById){if(directive.priority==="critical")continue;if(ackedIds.has(id))continue;result.unacknowledgedNonCritical.push(id),silentEvents.push({type:"unacknowledged",trace_id:traceId,knowledge_id:id,session_id:sessionId,task_id:taskId,agent:params.agent,source:"delegate",reason:"no_ack_marker"}),result.emitted.push({id,type:"unacknowledged"})}if(silentEvents.length>0)await recordKnowledgeEventsBatch(params.directory,silentEvents);if(violatedIds.size>0)await escalateViolatedEntries(params.directory,[...violatedIds])}catch{}return result}async function collectDelegateAcksAfter(directory,input,output){if(!isTaskTool3(input.tool))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 agent=parseDelegationArgs(input.args)?.targetAgent??"unknown",sessionId=typeof input.sessionID==="string"?input.sessionID:void 0;await collectDelegateAcks({directory,prompt,transcript,agent,sessionId})}init_reviewer_directive_compliance();init_schema();init_manager();init_logger();init_extractors();init_knowledge_events();init_knowledge_receipt_ledger();init_knowledge_store();init_knowledge_types();import{existsSync as existsSync117}from"node:fs";async function readEntriesById(directory){let map3=new Map,swarm=await readKnowledge(resolveSwarmKnowledgePath(directory));for(let e of swarm)map3.set(e.id,e);let hivePath=resolveHiveKnowledgePath2();if(existsSync117(hivePath)){let hive=await readKnowledge(hivePath);for(let e of hive)if(!map3.has(e.id))map3.set(e.id,e)}return map3}async function readPhaseDirectivesToVerify(directory,phaseLabel){try{let result=await queryLiveMemberships(directory,{phase:phaseLabel||void 0,include_terminal:!0,include_phase_closed:!1});if(!result.ok||result.memberships.length===0)return[];let entries=await readEntriesById(directory),out=[];for(let membership of result.memberships){if(membership.terminal&&membership.terminal.outcome!=="violated")continue;let e=entries.get(membership.entry_id);if(!e)continue;if(!isActiveStatus(e.status))continue;out.push({trace_id:membership.trace_id,entry_id:membership.entry_id,session_id:membership.session_id,cohort_id:membership.cohort_id,source_link_id:membership.source_link_id,prior_terminal_outcome:membership.terminal?.outcome==="violated"?"violated":void 0,prior_terminal_event_id:membership.terminal?.outcome==="violated"?membership.terminal.event_id:void 0,priority:membership.critical?"critical":e.directive_priority??"medium",lesson:e.lesson,verification_predicate:e.verification_predicate})}return out}catch{return[]}}init_skill_propagation_gate();function recordDelegateInjectionSkip(directory,reason,options){recordKnowledgeEvent(directory,{type:"injection_skip",reason,agent:options?.agent,session_id:options?.sessionId,detail:options?.detail}).catch(()=>{})}function isTaskTool4(tool3){return tool3==="Task"||tool3==="task"}function hasDelegateDirectiveBlock(text){return parseDelegateDirectiveBlock(text).length>0}function hasDirectiveComplianceBlock(text){return parseDirectivesToVerifyBlock(text).length>0}async function injectDelegateDirectivesBefore(directory,input,config3){let sessionId;try{sessionId=typeof input.sessionID==="string"?input.sessionID:void 0;let debugSkip=(reason,data)=>{return log("[delegate-directive-injection] skipped",{reason,caller_agent:typeof input.agent==="string"?input.agent:void 0,tool:input.tool,...data}),0};if(config3.enabled===!1)return debugSkip("knowledge_disabled");if(!isTaskTool4(input.tool))return debugSkip("not_task_tool");let callerAgent=typeof input.agent==="string"?input.agent:"",callerRole=stripKnownSwarmPrefix(callerAgent).toLowerCase();if(!callerAgent||callerRole!=="architect")return recordDelegateInjectionSkip(directory,"delegate_caller_not_allowed",{agent:callerAgent||void 0,sessionId,detail:{caller_role:callerRole}}),debugSkip("caller_not_allowed",{caller_role:callerRole});let argsRecord=input.args&&typeof input.args==="object"?input.args:null;if(!argsRecord)return recordDelegateInjectionSkip(directory,"delegate_missing_args",{agent:callerAgent,sessionId}),debugSkip("missing_args");let promptRaw=argsRecord.prompt;if(typeof promptRaw!=="string")return recordDelegateInjectionSkip(directory,"delegate_missing_prompt",{agent:callerAgent,sessionId}),debugSkip("missing_prompt");let parsed=parseDelegationArgs(input.args);if(!parsed)return recordDelegateInjectionSkip(directory,"delegate_unparseable_delegation_args",{agent:callerAgent,sessionId}),debugSkip("unparseable_delegation_args");let targetAgent=parsed.targetAgent;if(!isDelegatedAgent(targetAgent))return recordDelegateInjectionSkip(directory,"delegate_target_not_delegated_agent",{agent:targetAgent,sessionId,detail:{target_agent:targetAgent}}),debugSkip("target_not_delegated_agent",{target_agent:targetAgent});if(hasDelegateDirectiveBlock(promptRaw)||hasDirectiveComplianceBlock(promptRaw))return recordDelegateInjectionSkip(directory,"delegate_already_injected",{agent:targetAgent,sessionId}),debugSkip("already_injected",{target_agent:targetAgent});let plan=await loadPlan(directory).catch(()=>null),phaseLabel=plan?extractCurrentPhaseFromPlan(plan)??`Phase ${plan.current_phase??1}`:void 0,taskId=/\btask[_-]?id\s*[:=]\s*([A-Za-z0-9._-]{1,80})/i.exec(promptRaw)?.[1],{entries,trace_id}=await injectForDelegate({directory,agent:targetAgent,expectedTools:defaultExpectedToolsForAgent(targetAgent),taskTitle:promptRaw.slice(0,800),taskId,sessionId,phase:phaseLabel,config:config3}),prefixParts=[],delegateBlock=buildDelegateDirectiveBlock(entries,config3,trace_id);if(delegateBlock)prefixParts.push(delegateBlock);if(stripKnownSwarmPrefix(targetAgent).toLowerCase()==="reviewer"){let toVerify=await readPhaseDirectivesToVerify(directory,phaseLabel),complianceBlock=buildDirectiveComplianceBlock(toVerify);if(complianceBlock)prefixParts.push(complianceBlock)}if(prefixParts.length===0)return recordDelegateInjectionSkip(directory,"delegate_no_directives_to_inject",{agent:targetAgent,sessionId}),debugSkip("no_directives_to_inject",{target_agent:targetAgent});return argsRecord.prompt=`${prefixParts.join(`
6296
6303
 
6297
6304
  `)}
6298
6305
 
@@ -6300,7 +6307,7 @@ ${promptRaw}`,log("[delegate-directive-injection] injected",{caller_agent:caller
6300
6307
  `);try{injectAdvisory(architectSessionId,summary)}catch{}}}}var WRITE_TOOL_PATTERNS=["write","edit","patch","create","insert","replace","append","prepend"];function isWriteTool3(toolName){let normalized=normalizeToolNameLowerCase(toolName);return WRITE_TOOL_PATTERNS.some((p)=>normalized.includes(p))}var READ_TOOL_PATTERNS=["read","cat","view","fetch","get"];function isReadTool(toolName){let normalized=normalizeToolNameLowerCase(toolName);return READ_TOOL_PATTERNS.some((p)=>normalized.includes(p))}init_constants();init_schema();init_policy();init_state3();init_file_locks();init_state2();init_logger();init_normalize_tool_name();init_utils2();import*as fs128 from"node:fs";var RETURN_WARNING_PATTERNS=[{category:"skipped_tests",regex:/\b(?:skipped (?:the )?tests?|tests? (?:were |was )?skipped|did(?:n['']t)? run tests?|tests? not run|bypass(?:ed)? (?:the )?tests?|test (?:step|phase) (?:was )?bypass|tests? (?:are )?failing|tests? (?:are )?broken)\b/i},{category:"tool_timeout",regex:/\b(?:tool|process|command|test|build|lint)\s+(?:timed out|timeout|hung|killed|aborted|terminated|did not (?:complete|finish))/i},{category:"scope_changed",regex:/\b(?:expanded|changed|widened|exceeded|broke|extended|enlarged|grew|altered|adjusted) (?:the )?(?:declared |working |task |allowed )?(?:scope|file ?list|file ?set|working set|set of files)\b|\bscope (?:expansion|creep|drift|change)\b/i},{category:"external_instructions",regex:/\b(?:followed |received |applied |honored |obeyed )?(?:instructions|directives|guidance|orders|commands|hints) (?:from|in|per|according to) (?:the )?(?:tool output|web|search|fetched|fetch|external|untrusted|upstream|page|site|doc|documentation|response|prompt)\b|\bper (?:the )?(?:upstream|external|fetched|web|tool) (?:doc|documentation|page|response|content|guidance)\b/i},{category:"unable_to_verify",regex:/\b(?:unable|could ?n['']t|cannot|can ?not|wasn['']?t able) (?:to )?(?:verify|confirm|reproduce|test|check|validate|prove)\b|\bverification (?:deferred|skipped|postponed|incomplete|pending|impossible)\b/i},{category:"missing_evidence",regex:/\b(?:no |missing |without |lacking )(?:evidence|proof|verification|tests? passing|test results|coverage)\b|\bevidence (?:is )?(?:missing|absent|unavailable)\b/i},{category:"out_of_scope_files",regex:/\b(?:created|generated|wrote|modified|added|edited|patched|touched) (?:files? |code )?(?:outside|beyond|past|not in|that (?:are|were) outside) (?:the )?(?:declared |task |coder |allowed )?(?:scope|file ?list|file ?set|allowed (?:paths|files))\b/i}],SEVERE_CATEGORIES=new Set(["external_instructions","out_of_scope_files"]),CANONICAL_ROLES_LOWER=new Set(ALL_AGENT_NAMES.map((s)=>s.toLowerCase()));function isExactCanonicalRole(name){return CANONICAL_ROLES_LOWER.has(name.toLowerCase())}function isTaskTool5(toolName){let lower=toolName?.toLowerCase()??"";return lower==="task"||lower==="agent"||lower==="delegate"}function extractText(value){if(typeof value==="string")return value;if(value&&typeof value==="object"){let o=value;if(typeof o.output==="string")return o.output;if(typeof o.text==="string")return o.text;if(typeof o.summary==="string")return o.summary;try{return JSON.stringify(o)}catch{return""}}return""}function detectReturnWarnings(text){let warnings=[];if(!text)return warnings;let seen=new Set;for(let{category,regex}of RETURN_WARNING_PATTERNS){let m=text.match(regex);if(!m)continue;let key=`${category}:${m[0].toLowerCase()}`;if(seen.has(key))continue;seen.add(key),warnings.push({category,matched:m[0]})}return warnings}async function writeDelegationEvent(directory,event){let lockTaskId=`full-auto-delegation-${Date.now()}`,lockResult;try{lockResult=await tryAcquireLock(directory,"events.jsonl","full-auto-delegation",lockTaskId)}catch(error93){warn(`[full-auto/delegation] failed to acquire lock: ${error93 instanceof Error?error93.message:String(error93)}`)}try{let eventsPath=validateSwarmPath(directory,"events.jsonl");fs128.appendFileSync(eventsPath,`${JSON.stringify(event)}
6301
6308
  `,"utf-8")}catch(error93){throw error48(`[full-auto/delegation] failed to write event: ${error93 instanceof Error?error93.message:String(error93)}`),error93}finally{if(lockResult?.acquired&&lockResult.lock._release)try{await lockResult.lock._release()}catch(releaseError){error48("[full-auto/delegation] lock release failed:",releaseError)}}}function createFullAutoDelegationHook(options){let{config:config3,directory}=options;return{toolBefore:async(input,output)=>{let tool3=(normalizeToolName(input.tool)??input.tool??"").toLowerCase();if(!isTaskTool5(tool3))return;let sessionID=input.sessionID;if(!sessionID)return;let runState=loadFullAutoRunState(directory,sessionID);if(!runState||runState.status!=="running")return;let args2=output.args??{},subagentRaw=typeof args2.subagent_type==="string"&&args2.subagent_type||typeof args2.agent==="string"&&args2.agent||"",generatedAgentRegistry=swarmState.generatedAgentNames,canonicalRole=generatedAgentRegistry.length>0?resolveGeneratedAgentRole(subagentRaw,generatedAgentRegistry):getCanonicalAgentRole(subagentRaw);if(subagentRaw&&canonicalRole!==subagentRaw&&!isExactCanonicalRole(subagentRaw)){if(!subagentRaw.slice(0,subagentRaw.length-canonicalRole.length-1))throw Error(`FULL_AUTO_DELEGATION_DENY: subagent name '${subagentRaw}' has no valid prefix before the canonical role '${canonicalRole}'. Generated agent names must include a non-empty swarm prefix.`)}let promptText=typeof args2.prompt==="string"&&args2.prompt||typeof args2.message==="string"&&args2.message||typeof args2.task==="string"&&args2.task||"";if(incrementFullAutoCounter(directory,sessionID,"coderDelegations"),!subagentRaw||!isKnownCanonicalRole(canonicalRole))throw Error(`FULL_AUTO_DELEGATION_DENY: unknown subagent '${subagentRaw}' (canonical role '${canonicalRole}' is not a registered plugin role). Choose a generated agent whose suffix matches one of the canonical roles.`);if(promptText&&typeof promptText==="string"){let candidatePaths=promptText.match(/\b[A-Za-z0-9._/-]+\.(?:ts|tsx|js|jsx|json|md|yml|yaml|toml|lock|sh|env)\b/g);if(candidatePaths){for(let p of candidatePaths)if(isProtectedPath2(p,config3.full_auto))await writeDelegationEvent(directory,{type:"full_auto_subagent_warning",timestamp:new Date().toISOString(),session_id:sessionID,subagent:subagentRaw,canonical_role:canonicalRole,phase:"outbound",category:"protected_path_in_prompt",matched:p})}}},toolAfter:async(input,output)=>{let tool3=(normalizeToolName(input.tool)??input.tool??"").toLowerCase();if(!isTaskTool5(tool3))return;let sessionID=input.sessionID;if(!sessionID)return;let runState=loadFullAutoRunState(directory,sessionID);if(!runState||runState.status!=="running")return;let text=extractText(output.output),warnings=detectReturnWarnings(text);if(warnings.length===0)return;let severe=warnings.some((w)=>SEVERE_CATEGORIES.has(w.category));if(await writeDelegationEvent(directory,{type:"full_auto_subagent_warning",timestamp:new Date().toISOString(),session_id:sessionID,phase:"return",warnings,severe}),runState.counters.consecutiveNoProgressTurns=severe?runState.counters.consecutiveNoProgressTurns+1:runState.counters.consecutiveNoProgressTurns,saveFullAutoRunState(directory,runState),severe){let updated=loadFullAutoRunState(directory,sessionID);if(updated&&updated.status==="running")updated.status="paused",updated.pauseReason=`severe subagent return warning: ${warnings.filter((w)=>SEVERE_CATEGORIES.has(w.category)).map((w)=>w.category).join(",")}`,saveFullAutoRunState(directory,updated)}}}}import*as fs129 from"node:fs";var PATTERNS=[{category:"instruction_override",regex:/\bignore (?:all |any |the )?(?:previous|prior|earlier|above) (?:instructions|prompts|rules|directives)\b/i},{category:"instruction_override",regex:/\bdisregard (?:all |any |the )?(?:previous|prior|earlier|above) (?:instructions|prompts|rules)\b/i},{category:"instruction_override",regex:/\bforget (?:all |any |everything|the )?(?:previous|above|prior) (?:instructions|prompts|rules)\b/i},{category:"system_role_override",regex:/\b(?:you are now|act as|pretend to be|from now on you are)\s+(?:a |an |the )?(?:system|developer|root|admin|superuser)\b/i},{category:"system_role_override",regex:/\b<\|?(?:system|developer|im_start|imstart)\|?>/i},{category:"credential_request",regex:/\b(?:please |kindly |)(?:paste|share|reveal|send|provide|leak|print|echo|cat) (?:your |the |my )?(?:api[_ -]?key|password|token|secret|credentials|\.env)\b/i},{category:"credential_request",regex:/\b(?:show|dump|export) (?:env(?:ironment)?|secrets|credentials|keys?)\b/i},{category:"exfiltration_request",regex:/\b(?:upload|exfiltrate|send) (?:contents of |files? from |the )?(?:home|repo|workspace|project|secrets?|env(?:ironment)?)\b/i},{category:"exfiltration_request",regex:/\bcurl\s+-d\s+@/i},{category:"guardrail_disable_request",regex:/\bdisable (?:full[- ]auto|guardrails?|safety|policy|oversight|critic)\b/i},{category:"guardrail_disable_request",regex:/\bturn (?:off|disable) (?:full[- ]auto|guardrails?|safety|policy)\b/i},{category:"curl_pipe_shell",regex:/\bcurl\b[^|\n]*\|\s*(?:sh|bash|zsh|fish)\b/i},{category:"untrusted_run_command",regex:/\b(?:run|execute|paste) (?:this|the following) (?:command|script|bash|shell)\b/i}];function buildExcerpt(text,match){let idx=match.index??0,start=Math.max(0,idx-120),end=Math.min(text.length,idx+match[0].length+120),slice=text.slice(start,end).replace(/\s+/g," ").trim();return slice.length>280?`${slice.slice(0,280)}…`:slice}function probeFullAutoInput(text){let warnings=[];if(!text||typeof text!=="string")return{hasWarning:!1,warnings};let seen=new Set;for(let{category,regex}of PATTERNS){let m=text.match(regex);if(!m)continue;let key=`${category}:${m[0].toLowerCase()}`;if(seen.has(key))continue;seen.add(key),warnings.push({category,matched:m[0],excerpt:buildExcerpt(text,m)})}return{hasWarning:warnings.length>0,warnings}}var RISKY_FOLLOWUP_TOOLS=new Set(["bash","shell","exec","web_search","webfetch","web_fetch","fetch","http","request"]),SECRET_TOOL_PATTERNS=[/\b(?:cat|head|tail|less|more)\s+[^\n]*\.env/i,/\bprintenv\b.*(?:SECRET|TOKEN|KEY|PASSWORD)/i];function shouldEscalateAfterWarning(toolName,commandOrUrl){let lower=toolName?.toLowerCase()??"";if(RISKY_FOLLOWUP_TOOLS.has(lower))return!0;if(typeof commandOrUrl==="string"){for(let re of SECRET_TOOL_PATTERNS)if(re.test(commandOrUrl))return!0}return!1}init_state3();init_file_locks();init_logger();init_normalize_tool_name();init_utils2();var PROBED_TOOLS=new Set(["web_search","webfetch","web_fetch","fetch","http","request","doc_extract","doc_scan","gitingest","extract_code_blocks","retrieve_summary","retrieve_lane_output","search","read","view"]);async function writeWarningEvent(directory,sessionID,tool3,probe2){let event={type:"full_auto_input_warning",timestamp:new Date().toISOString(),session_id:sessionID,tool:tool3,warnings:probe2.warnings},lockTaskId=`full-auto-input-warning-${Date.now()}`,lockResult;try{lockResult=await tryAcquireLock(directory,"events.jsonl","full-auto-input-warning",lockTaskId)}catch(error93){warn(`[full-auto/input-probe] failed to acquire lock: ${error93 instanceof Error?error93.message:String(error93)}`)}try{let eventsPath=validateSwarmPath(directory,"events.jsonl");fs129.appendFileSync(eventsPath,`${JSON.stringify(event)}
6302
6309
  `,"utf-8")}catch(error93){error48(`[full-auto/input-probe] failed to write event: ${error93 instanceof Error?error93.message:String(error93)}`)}finally{if(lockResult?.acquired&&lockResult.lock._release)try{await lockResult.lock._release()}catch(releaseError){error48("[full-auto/input-probe] lock release failed:",releaseError)}}}function extractText2(out){if(typeof out==="string")return out;if(out&&typeof out==="object"){let candidate2=out;if(typeof candidate2.output==="string")return candidate2.output;if(typeof candidate2.text==="string")return candidate2.text;if(typeof candidate2.body==="string")return candidate2.body;try{return JSON.stringify(candidate2)}catch{return""}}return""}var MAX_TRACKED_SESSIONS9=256,WARNING_TTL_MS=300000,fullAutoInputWarningStash=new Map;function isExpired2(w,nowMs=Date.now()){let at=Date.parse(w.at);if(!Number.isFinite(at))return!0;return nowMs-at>WARNING_TTL_MS}function evictExpired(){let now2=Date.now();for(let[sid,w]of fullAutoInputWarningStash)if(isExpired2(w,now2))fullAutoInputWarningStash.delete(sid);while(fullAutoInputWarningStash.size>MAX_TRACKED_SESSIONS9){let firstKey=fullAutoInputWarningStash.keys().next().value;if(firstKey===void 0)break;fullAutoInputWarningStash.delete(firstKey)}}function setPendingInputWarning(sessionID,warning){fullAutoInputWarningStash.delete(sessionID),fullAutoInputWarningStash.set(sessionID,warning),evictExpired()}function consumePendingInputWarning(sessionID){let warning=fullAutoInputWarningStash.get(sessionID);if(warning)fullAutoInputWarningStash.delete(sessionID);if(warning&&isExpired2(warning))return;return warning}function peekPendingInputWarning(sessionID){let w=fullAutoInputWarningStash.get(sessionID);if(!w)return;if(isExpired2(w)){fullAutoInputWarningStash.delete(sessionID);return}return w}function createFullAutoInputProbeHook(options){let{directory}=options;return{toolAfter:async(input,output)=>{let tool3=(normalizeToolName(input.tool)??input.tool??"").toLowerCase();if(!PROBED_TOOLS.has(tool3))return;let sessionID=input.sessionID;if(!sessionID)return;let runState=loadFullAutoRunState(directory,sessionID);if(!runState||runState.status!=="running")return;let text=extractText2(output.output);if(!text)return;let probe2=probeFullAutoInput(text);if(!probe2.hasWarning)return;setPendingInputWarning(sessionID,{tool:tool3,at:new Date().toISOString(),categories:probe2.warnings.map((w)=>w.category)}),await writeWarningEvent(directory,sessionID,tool3,probe2)}}}init_constants();init_schema();init_policy();init_state3();init_scope_persistence();init_state2();init_normalize_tool_name();function createFullAutoPermissionHook(options){let{config:config3,directory}=options,fullAutoConfig=config3.full_auto;return{toolBefore:async(input,output)=>{let toolName=normalizeToolName(input.tool)??input.tool,sessionID=input.sessionID;if(!sessionID)return;let stateHealth=isFullAutoStateUnreadable();if(stateHealth.unreadable){if(isReadOnlyTool(toolName))return;throw Error(`FULL_AUTO_STATE_UNREADABLE: tool '${toolName}' blocked because the Full-Auto durable state file is unreadable (${stateHealth.reason}). Restore .swarm/full-auto-state.json (or .bak) and re-run /swarm full-auto on.`)}let runState=loadFullAutoRunState(directory,sessionID);if(!runState||runState.status==="idle")return;if(runState.status==="paused"||runState.status==="terminated"){if(isReadOnlyTool(toolName))return;let rawReason=runState.pauseReason??runState.terminateReason??"no reason recorded",statusPrefix=rawReason.includes("infrastructure failure")&&runState.status==="paused"?"FULL_AUTO_PAUSED:OVERSIGHT_INFRASTRUCTURE_FAILURE":`FULL_AUTO_${runState.status.toUpperCase()}`;throw Error(`${statusPrefix}: tool '${toolName}' blocked because Full-Auto run is ${runState.status} (${rawReason}). Re-enable with /swarm full-auto on after the underlying issue is resolved.`)}let session=swarmState.agentSessions.get(sessionID),activeAgent=swarmState.activeAgent.get(sessionID)??session?.agentName??ORCHESTRATOR_NAME,normalizedAgentName=stripKnownSwarmPrefix(activeAgent),taskId=session?.currentTaskId??null,binding=taskId?resolveAuthorizedScopeBinding({directory,taskId,activeSessionId:sessionID}):resolveAuthorizedScopeBindingForSession({directory,activeSessionId:sessionID});if(!taskId&&binding&&session)taskId=binding.taskId,session.currentTaskId=binding.taskId,session.declaredCoderScope=[...binding.files];let declaredScope=binding?.files??null,argsObj=output.args??void 0,lowerTool=toolName?.toLowerCase()??"",phaseFromArgs;if(lowerTool==="phase_complete"){if(phaseFromArgs=parsePhaseArg(argsObj),phaseFromArgs===void 0)throw Error("FULL_AUTO_DENY [phase_complete_invalid_phase]: phase_complete called without a valid 'phase' argument. Provide a positive integer phase before calling phase_complete.")}let effectivePhase=phaseFromArgs??runState.currentPhase,safeMode=["assisted","supervised","strict"].includes(runState.mode)?runState.mode:"strict",effectiveFullAutoConfig=fullAutoConfig?{...fullAutoConfig,mode:safeMode}:{mode:safeMode},classifierInput={sessionID,agentName:activeAgent,normalizedAgentName,toolName,args:argsObj,directory,declaredScope,currentTaskID:taskId,currentPhase:effectivePhase,planSummary:void 0,changedFiles:session&&taskId?getModifiedFilesForTask(session,taskId):void 0,fullAutoConfig:effectiveFullAutoConfig},decision=classifyFullAutoToolAction(classifierInput),pendingWarning=peekPendingInputWarning(sessionID);if(pendingWarning){let commandOrUrl=typeof argsObj?.command==="string"&&argsObj.command||typeof argsObj?.url==="string"&&argsObj.url||void 0;if(shouldEscalateAfterWarning(toolName,commandOrUrl))decision={action:"escalate_critic",reason:`risky follow-up after prompt-injection warning (${pendingWarning.categories.join(",")})`,risk:"high",context:{tool:toolName,priorWarningTool:pendingWarning.tool,categories:pendingWarning.categories}},consumePendingInputWarning(sessionID)}if(decision.action==="allow"){tickAndMaybeDispatchCadence(directory,sessionID,"toolCalls",config3,{activeAgent}),resetFullAutoDenials(directory,sessionID);return}if(decision.action==="deny"){let denial=buildStructuredDenial(decision,toolName);recordFullAutoDenial(directory,sessionID,{tool:toolName,code:decision.code,reason:decision.reason});let updated2=loadFullAutoRunState(directory,sessionID);if(updated2){let pauseDecision=shouldPauseForDenials(updated2,fullAutoConfig);if(pauseDecision.pause)if(pauseDecision.mode==="terminate")terminateFullAutoRun(directory,sessionID,pauseDecision.reason??"denial-limit");else pauseFullAutoRun(directory,sessionID,pauseDecision.reason??"denial-limit")}throw Error(`FULL_AUTO_DENY [${decision.code}]: ${decision.reason}. ${JSON.stringify(denial)}`)}if(decision.action==="pause")throw pauseFullAutoRun(directory,sessionID,decision.reason),Error(`FULL_AUTO_PAUSE [${decision.code}]: ${decision.reason}`);if(decision.action==="escalate_human")throw terminateFullAutoRun(directory,sessionID,decision.reason),Error(`FULL_AUTO_ESCALATE_HUMAN [${decision.code}]: ${decision.reason}`);let triggerSource=mapTriggerSource(decision,toolName),criticModel=fullAutoConfig?.critic_model??config3.agents?.critic?.model??"opencode/big-pickle",oversightAgentName=resolveOversightAgentNameFromActive(activeAgent);if(lowerTool==="phase_complete"&&effectivePhase!==void 0){let stateForPhase=loadFullAutoRunState(directory,sessionID);if(stateForPhase&&stateForPhase.currentPhase!==effectivePhase){stateForPhase.currentPhase=effectivePhase;try{saveFullAutoRunState(directory,stateForPhase)}catch(persistErr){let msg=persistErr instanceof Error?persistErr.message:String(persistErr);throw Error(`FULL_AUTO_BLOCKED: failed to persist phase ${effectivePhase} to durable run state — ${msg}`)}}}let outcome;try{outcome=await dispatchFullAutoOversight({directory,sessionID,trigger:decision.reason,triggerSource,phase:effectivePhase,taskID:taskId??void 0,planID:runState.planID,architectOutput:output.args?JSON.stringify(output.args):void 0,actionContext:{tool:toolName,...decision.context??{}},criticModel,oversightAgentName,fullAutoConfig:{fail_closed:fullAutoConfig?.fail_closed!==!1,max_dispatch_retries:fullAutoConfig?.oversight?.max_dispatch_retries??2,max_consecutive_dispatch_failures:fullAutoConfig?.oversight?.max_consecutive_dispatch_failures??3}})}catch(error93){let reason=error93 instanceof Error?error93.message:String(error93);throw pauseFullAutoRun(directory,sessionID,`oversight dispatcher exception: ${reason}`),Error(`FULL_AUTO_BLOCKED: oversight dispatch threw — ${reason}`)}if(outcome.decision==="allow"){tickAndMaybeDispatchCadence(directory,sessionID,"toolCalls",config3,{activeAgent}),resetFullAutoDenials(directory,sessionID);return}if(outcome.decision==="pause")throw Error(`FULL_AUTO_BLOCKED: critic verdict ${outcome.verdict} — ${outcome.reasoning}`);if(outcome.decision==="escalate_human")throw Error(`FULL_AUTO_ESCALATE_HUMAN: critic verdict ${outcome.verdict} — ${outcome.reasoning}`);recordFullAutoDenial(directory,sessionID,{tool:toolName,code:`critic_${outcome.verdict}`.toLowerCase(),reason:outcome.reasoning||`critic verdict ${outcome.verdict}`});let updated=loadFullAutoRunState(directory,sessionID);if(updated){let pauseDecision=shouldPauseForDenials(updated,fullAutoConfig);if(pauseDecision.pause)if(pauseDecision.mode==="terminate")terminateFullAutoRun(directory,sessionID,pauseDecision.reason??"denial-limit");else pauseFullAutoRun(directory,sessionID,pauseDecision.reason??"denial-limit")}throw Error(`FULL_AUTO_CRITIC_DENY: ${outcome.verdict} — ${outcome.reasoning}`)}}}function parsePhaseArg(args2){if(!args2)return;let raw=args2.phase,n;if(typeof raw==="number")n=raw;else if(typeof raw==="string"&&raw.trim()){let trimmed=raw.trim();if(!/^[1-9][0-9]*$/.test(trimmed))return;n=Number.parseInt(trimmed,10)}else return;if(!Number.isFinite(n)||!Number.isInteger(n)||n<1)return;if(n>Number.MAX_SAFE_INTEGER)return;return n}function mapTriggerSource(decision,toolName){if(decision.action!=="escalate_critic")return"tool_action";let lower=toolName?.toLowerCase()??"";if(lower==="phase_complete")return"phase_boundary";if(lower==="update_task_status")return"task_completion";if(decision.risk==="high")return"risk";return"tool_action"}function resolveOversightAgentNameFromActive(activeAgent){if(!activeAgent)return"critic_oversight";if(stripKnownSwarmPrefix(activeAgent)===ORCHESTRATOR_NAME){let lastIdx=activeAgent.toLowerCase().lastIndexOf("architect");if(lastIdx>0)return`${activeAgent.slice(0,lastIdx)}critic_oversight`}return"critic_oversight"}init_gate_denial_tracker();init_guardrails2();init_hive_promoter();init_stored_input_args();init_spawn_helper();import*as fs130 from"node:fs";import*as path232 from"node:path";var emittedSkipAdvisories=new Set;function detectPackageManager(projectDir){if(fs130.existsSync(path232.join(projectDir,"bun.lockb")))return"bun";if(fs130.existsSync(path232.join(projectDir,"pnpm-lock.yaml")))return"pnpm";if(fs130.existsSync(path232.join(projectDir,"yarn.lock")))return"yarn";if(fs130.existsSync(path232.join(projectDir,"package-lock.json")))return"npm";return"bun"}function detectTypecheckCommand(projectDir){let pkgPath=path232.join(projectDir,"package.json");if(fs130.existsSync(pkgPath))try{let pkg=JSON.parse(fs130.readFileSync(pkgPath,"utf8")),scripts=pkg.scripts;if(scripts?.typecheck)return{command:[detectPackageManager(projectDir),"run","typecheck"],language:"typescript"};if(scripts?.["type-check"])return{command:[detectPackageManager(projectDir),"run","type-check"],language:"typescript"};let deps={...pkg.dependencies,...pkg.devDependencies};if(!deps?.typescript&&!fs130.existsSync(path232.join(projectDir,"tsconfig.json")));if(deps?.typescript||fs130.existsSync(path232.join(projectDir,"tsconfig.json")))return{command:["npx","tsc","--noEmit"],language:"typescript"}}catch{return null}if(fs130.existsSync(path232.join(projectDir,"go.mod")))return{command:["go","vet","./..."],language:"go"};if(fs130.existsSync(path232.join(projectDir,"Cargo.toml")))return{command:["cargo","check"],language:"rust"};if(fs130.existsSync(path232.join(projectDir,"pyproject.toml"))||fs130.existsSync(path232.join(projectDir,"requirements.txt"))||fs130.existsSync(path232.join(projectDir,"setup.py")))return{command:null,language:"python"};try{if(fs130.readdirSync(projectDir).some((f)=>f.endsWith(".csproj")||f.endsWith(".sln")))return{command:["dotnet","build","--no-restore"],language:"csharp"}}catch{}return null}async function runWithTimeout(command,cwd,timeoutMs){let result=await spawnAsync(command,cwd,timeoutMs);if(result===null)return null;return{exitCode:result.exitCode,stderr:result.stderr}}function createIncrementalVerifyHook(config3,projectDir,injectMessage){return{toolAfter:async(input,output)=>{if(!config3.enabled)return;if(input.tool!=="Task")return;let args2=(typeof input.callID==="string"?getStoredInputArgs(input.callID):void 0)??input.args??output.args,subagentType=typeof args2?.subagent_type==="string"?args2.subagent_type:"",agentName=subagentType.replace(/^[^_]+_/,"");if(!config3.triggerAgents.includes(agentName)&&!config3.triggerAgents.includes(subagentType))return;let commandToRun=null;if(config3.command!=null)if(Array.isArray(config3.command))commandToRun=config3.command;else commandToRun=config3.command.split(" ");else{let detected=detectTypecheckCommand(projectDir);if(detected===null)return;if(detected.command===null){let dedupKey=`${input.sessionID}:${detected.language}`;if(!emittedSkipAdvisories.has(dedupKey))emittedSkipAdvisories.add(dedupKey),injectMessage(input.sessionID,`POST-CODER CHECK SKIPPED: ${detected.language} project detected but no default checker available. Set incremental_verify.command in .swarm/config.json to enable.`);return}commandToRun=detected.command}if(commandToRun===null)return;let result=await runWithTimeout(commandToRun,projectDir,config3.timeoutMs);if(result===null)return;if(result.exitCode===0)injectMessage(input.sessionID,"POST-CODER CHECK PASSED: No type errors.");else{let errorSummary=result.stderr.slice(0,800);injectMessage(input.sessionID,`POST-CODER CHECK FAILED: Type errors detected after coder delegation. Address these before proceeding.
6303
- ${errorSummary}`)}}}}init_pending_delegations();init_constants();init_file_locks();init_state2();init_recovery();init_utils();init_core3();init_merge();init_worktree_merge_status();init_worktree_ownership_tag();init_worktree_provisioning_owner();import*as fs131 from"node:fs";import*as fsPromises10 from"node:fs/promises";import*as path233 from"node:path";var INIT_ORPHAN_RECOVERY_TIMEOUT_MS=1e4,OWNERSHIP_TAG_SCAN_TIMEOUT_MS2=2000;async function listOwnershipTagSessionIds(directory){let scan=await scanBackgroundWorktreeOwnershipTagsForRecovery(directory);if(scan.status==="uncertain")return scan;return{status:"ok",sessionIds:[...new Set(scan.owners.map((owner)=>owner.sessionId))]}}var ORPHAN_RECOVERY_LOCK_FILE=WORKTREE_LIFECYCLE_LOCK_FILE,_internals173={rmSync:fs131.rmSync,removeWorktree,isLocked,listActiveLocks,tryAcquireLock,listOwnershipTagSessionIds,scanDelegationsForRecovery,scanDelegationFallbacksForRecovery,scanWorktreeMergeFailuresForRecovery,scanWorktreeProvisioningOwnersForRecovery,scanRegisteredWorktreeLiveness,removeWorktreeProvisioningOwner};async function writeAdvisoryFile(directory,cleanupResult,warnings,attempted,removedWorktrees=[]){let advisoryPath=path233.join(directory,".swarm","advisories","init-orphan-recovery.json"),advisory={initTimestamp:new Date().toISOString(),warnings,errors:cleanupResult.errors,reclaimed:{removedBranches:cleanupResult.removed,removedWorktrees,prunedWorktrees:attempted},...cleanupResult.skippedRecoveryBranches&&cleanupResult.skippedRecoveryBranches.length>0?{preservedRecoveryBranches:cleanupResult.skippedRecoveryBranches}:{},...cleanupResult.recoveryReadError?{recoveryReadError:!0,note:"skipped all lane-branch deletions this pass because .swarm/recovery/ was unreadable (fail-safe)"}:{}};try{await fsPromises10.mkdir(path233.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,protectedWorktreePaths=new Set){let orphanedDirs=[],worktreeRoot=path233.resolve(path233.dirname(directory),SWARM_WORKTREE_DIR_NAME),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(path233.join(worktreeRoot,sessionId),{withFileTypes:!0})}catch{continue}for(let laneEntry of sessionEntries){if(!laneEntry.isDirectory())continue;let worktreePath=path233.join(worktreeRoot,sessionId,laneEntry.name);if(protectedWorktreePaths.has(path233.resolve(worktreePath)))continue;orphanedDirs.push(worktreePath)}}return orphanedDirs}async function isCrossProcessLockHeld(directory){if(_internals173.isLocked(directory,ORPHAN_RECOVERY_LOCK_FILE))return!0;if(_internals173.listActiveLocks(directory).length>0)return!0;return!1}async function removeOrphanedWorktreeDir(worktreePath,projectRoot){if(!fs131.existsSync(path233.join(worktreePath,".git")))try{_internals173.rmSync(worktreePath,{recursive:!0,force:!0});return}catch(error93){return error93 instanceof Error?error93.message:String(error93)}let removeResult=await _internals173.removeWorktree(worktreePath,projectRoot);if(!("error"in removeResult))return;try{_internals173.rmSync(worktreePath,{recursive:!0,force:!0});return}catch{return removeResult.error}}async function crossProcessAdvisoryResult(directory,warning){let result={attempted:!0,crossProcessLockHeld:!0,warnings:[warning],orphanedBranches:[],removedWorktrees:[],prunedWorktrees:!1};return await writeAdvisoryFile(directory,{removed:[],skipped:[],errors:[]},result.warnings,!1,[]),result}function worktreePathKey(worktreePath,directory){let absolutePath2=path233.isAbsolute(worktreePath)?worktreePath:path233.resolve(directory,worktreePath),normalized=path233.normalize(absolutePath2);return process.platform==="win32"?normalized.toLowerCase():normalized}async function runInitOrphanRecovery(directory){let result,recoveryLockRelease;try{if(await isCrossProcessLockHeld(directory))return crossProcessAdvisoryResult(directory,"Cross-process lock held — another opencode process may be active. "+"Skipping destructive cleanup to preserve its worktrees/branches. Run '/swarm status' or check '.swarm/locks/' to identify active processes.");let lockAcquireResult=await _internals173.tryAcquireLock(directory,ORPHAN_RECOVERY_LOCK_FILE,"init-orphan-recovery","init");if(!lockAcquireResult.acquired)return crossProcessAdvisoryResult(directory,"Cross-process lifecycle lock was acquired by another process during init; skipping destructive cleanup to preserve its worktrees/branches.");recoveryLockRelease=lockAcquireResult.lock._release;let activeSessionIds=Array.from(swarmState.agentSessions.keys()),provisioningOwnerScan=await withTimeout(Promise.resolve(_internals173.scanWorktreeProvisioningOwnersForRecovery(directory)),INIT_ORPHAN_RECOVERY_TIMEOUT_MS,Error("worktree provisioning ownership scan exceeded its bounded init budget"));if(provisioningOwnerScan.status==="uncertain")throw Error(`worktree provisioning ownership state is uncertain; destructive orphan cleanup skipped: ${provisioningOwnerScan.reason}`);let registeredWorktrees=provisioningOwnerScan.owners.length===0?{status:"ok",liveBranches:[]}:await withTimeout(_internals173.scanRegisteredWorktreeLiveness(directory),OWNERSHIP_TAG_SCAN_TIMEOUT_MS2,Error("registered worktree liveness scan exceeded its bounded init budget"));if(registeredWorktrees.status==="uncertain")throw Error(`registered worktree liveness is uncertain; destructive orphan cleanup skipped: ${registeredWorktrees.reason}`);let liveBranches=new Set(registeredWorktrees.liveBranches),now2=Date.now();for(let owner of provisioningOwnerScan.owners){let leaseIsLive=now2-owner.createdAt<=WORKTREE_PROVISIONING_OWNER_LEASE_MS,sessionIds=new Set([owner.parentSessionId,owner.worktreeSessionId]),branchIsLive=owner.schemaVersion===2?[...sessionIds].some((sessionId)=>liveBranches.has(`swarm/lane/${sessionId}/${owner.taskId}`)||liveBranches.has(`swarm-lane/${sessionId}/${owner.taskId}`)):[...liveBranches].some((branch)=>{let segments=branch.split("/"),sessionId=segments[0]==="swarm"&&segments.length>=4?segments[2]:segments[0]==="swarm-lane"&&segments.length>=3?segments[1]:void 0;return sessionId!==void 0&&sessionIds.has(sessionId)});if(!leaseIsLive&&!branchIsLive){if(!_internals173.removeWorktreeProvisioningOwner(directory,owner.callID))throw Error(`expired worktree provisioning owner ${owner.callID} could not be removed; destructive orphan cleanup skipped`);continue}if(!activeSessionIds.includes(owner.worktreeSessionId))activeSessionIds.push(owner.worktreeSessionId);if(!activeSessionIds.includes(owner.parentSessionId))activeSessionIds.push(owner.parentSessionId)}let ownershipTagScan=await withTimeout(_internals173.listOwnershipTagSessionIds(directory),OWNERSHIP_TAG_SCAN_TIMEOUT_MS2,Error("background ownership tag scan exceeded its bounded init budget"));if(ownershipTagScan.status==="uncertain")throw Error(`background ownership tag state is uncertain; destructive orphan cleanup skipped: ${ownershipTagScan.reason}`);for(let sessionId of ownershipTagScan.sessionIds)if(!activeSessionIds.includes(sessionId))activeSessionIds.push(sessionId);let fallbackOwnerScan=await withTimeout(_internals173.scanDelegationFallbacksForRecovery(directory),INIT_ORPHAN_RECOVERY_TIMEOUT_MS,Error("background delegation fallback ownership scan exceeded its bounded init budget"));if(fallbackOwnerScan.status==="uncertain")throw Error(`background fallback ownership state is uncertain; destructive orphan cleanup skipped: ${fallbackOwnerScan.reason}`);let primaryOwnerScan=await withTimeout(Promise.resolve(_internals173.scanDelegationsForRecovery(directory)),INIT_ORPHAN_RECOVERY_TIMEOUT_MS,Error("background primary ownership scan exceeded its bounded init budget"));if(primaryOwnerScan.status==="uncertain")throw Error(`background primary ownership state is uncertain; destructive orphan cleanup skipped: ${primaryOwnerScan.reason}`);let isUnsettledWorktreeOwner=(record3)=>Boolean(record3.worktree)&&!(record3.coderSettlement?.state==="settled"&&record3.coderSettlement.outcome?.kind==="standard-worktree"&&(record3.coderSettlement.outcome.result==="merged"||record3.coderSettlement.outcome.result==="unchanged")),durableWorktreeOwners=primaryOwnerScan.owners.filter(isUnsettledWorktreeOwner),mergeOwnerScan=await withTimeout(Promise.resolve(_internals173.scanWorktreeMergeFailuresForRecovery(directory)),INIT_ORPHAN_RECOVERY_TIMEOUT_MS,Error("worktree merge ownership scan exceeded its bounded init budget"));if(mergeOwnerScan.status==="uncertain")throw Error(`worktree merge ownership state is uncertain; destructive orphan cleanup skipped: ${mergeOwnerScan.reason}`);let allDurableOwners=[...durableWorktreeOwners,...fallbackOwnerScan.owners.map((artifact)=>artifact.record).filter(isUnsettledWorktreeOwner)],preservedMergeFailures=mergeOwnerScan.failures.map(([,failure])=>failure).filter((failure)=>typeof failure.worktreePath==="string"),protectedWorktreePaths=new Set([...allDurableOwners.map((record3)=>record3.worktree?.worktreePath),...preservedMergeFailures.map((failure)=>failure.worktreePath)].filter((value)=>typeof value==="string").map((value)=>path233.resolve(value)));for(let owner of allDurableOwners){let worktreeSessionId=owner.worktree?.worktreeSessionId;if(worktreeSessionId&&!activeSessionIds.includes(worktreeSessionId))activeSessionIds.push(worktreeSessionId);if(!activeSessionIds.includes(owner.parentSessionId))activeSessionIds.push(owner.parentSessionId)}for(let failure of preservedMergeFailures){let segments=failure.branch?.split("/")??[],worktreeSessionId=segments[0]==="swarm"&&segments.length>=4?segments[2]:segments[0]==="swarm-lane"&&segments.length>=3?segments[1]:void 0;if(worktreeSessionId&&!activeSessionIds.includes(worktreeSessionId))activeSessionIds.push(worktreeSessionId)}let orphanedWorktreeDirs=await withTimeout(enumerateOrphanedWorktreeDirs(directory,activeSessionIds,protectedWorktreePaths),INIT_ORPHAN_RECOVERY_TIMEOUT_MS,Error(`runInitOrphanRecovery exceeded ${INIT_ORPHAN_RECOVERY_TIMEOUT_MS}ms budget during worktree enumeration; continuing without orphan reclamation`)),removedWorktrees=[],worktreeWarnings=[],recoveryRecords=listRecoveryRecords(directory),recoveryReadError=recoveryReadErrored(directory),recoveryWorktreePaths=new Set(recoveryRecords.map((record3)=>worktreePathKey(record3.worktreePath,directory)));if(recoveryReadError)worktreeWarnings.push("Recovery records are unreadable or fail schema validation; skipped all orphaned worktree deletion this pass (fail-safe).");else for(let worktreePath of orphanedWorktreeDirs){if(recoveryWorktreePaths.has(worktreePathKey(worktreePath,directory))){worktreeWarnings.push(`Preserved recovery worktree "${worktreePath}"; an unresolved recovery record still references it.`);continue}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,{preserveUnmerged:!0}),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:cleanupResult.recoveryReadError!==!0},await writeAdvisoryFile(directory,cleanupResult,allWarnings,!0,removedWorktrees)}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:[],skippedRecoveryBranches:[],errors:[]},result.warnings,!1,[])}finally{try{await recoveryLockRelease?.()}catch{}}return result}init_state2();import*as fs132 from"node:fs/promises";import*as path234 from"node:path";var ADVISORY_FILENAME="init-orphan-recovery.json";function createInitOrphanRecoveryAdvisoryHook(directory){let consumedBySession=new Set;async function readAdvisoryFile(){let advisoryPath=path234.join(directory,".swarm","advisories",ADVISORY_FILENAME);try{let content=await fs132.readFile(advisoryPath,"utf-8");return JSON.parse(content)}catch{return null}}async function deleteAdvisoryFile(){let advisoryPath=path234.join(directory,".swarm","advisories",ADVISORY_FILENAME);try{await fs132.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 reclaimedForGate=advisory.reclaimed;if(!((advisory.warnings?.length??0)>0||(advisory.errors?.length??0)>0||(reclaimedForGate?.removedBranches?.length??0)>0||(reclaimedForGate?.removedWorktrees?.length??0)>0))return;let targetSession=ensureAgentSession(sessionId),timestamp=advisory.initTimestamp?new Date(advisory.initTimestamp).toLocaleString():"unknown";pushAdvisory(targetSession,`[INIT ORPHAN RECOVERY] Plugin init detected the following at ${timestamp}:`);for(let warning of advisory.warnings??[])pushAdvisory(targetSession,` WARNING: ${warning}`);for(let err of advisory.errors??[])pushAdvisory(targetSession,` ERROR: ${formatError3(err)}`);let reclaimed=advisory.reclaimed;if((reclaimed?.removedBranches?.length??0)>0)pushAdvisory(targetSession,` Reclaimed ${reclaimed.removedBranches.length} orphaned branch(es): ${reclaimed.removedBranches.join(", ")}`);if(reclaimed?.removedWorktrees&&reclaimed.removedWorktrees.length>0)pushAdvisory(targetSession,` Reclaimed ${reclaimed.removedWorktrees.length} orphaned worktree directory(ies): ${reclaimed.removedWorktrees.join(", ")}`);if(reclaimed?.prunedWorktrees)pushAdvisory(targetSession," Stale worktree metadata pruned.")}return{messagesTransform}}init_logger();init_delegation_gate();import*as fs133 from"node:fs";import*as path236 from"node:path";function computeNextMode(params){let{issueReference,traceState,workflowArtifacts}=params,noop={nextMode:null,directive:null,nextLastTransition:traceState.lastTransition,nextStatus:traceState.status};if(!issueReference||issueReference.flags.trace!==!0)return noop;if(traceState.status==="published")return noop;if(traceState.status==="publication_handoff"){if(workflowArtifacts.publicationObserved&&traceState.lastTransition!=="PUBLISHED")return{nextMode:null,directive:"Publication confirmed. The issue-trace workflow is complete.",nextLastTransition:"PUBLISHED",nextStatus:"published"};return noop}if(workflowArtifacts.specIssueNumber===null||workflowArtifacts.specIssueNumber!==issueReference.number||traceState.issueNumber!==issueReference.number)return noop;if(!workflowArtifacts.specExists)return noop;if(!workflowArtifacts.planExists){if(!workflowArtifacts.reproductionPermitted){if(traceState.lastTransition===null)return{nextMode:"ISSUE_INGEST",directive:"Reproduction evidence (or a typed --no-repro waiver) is required before this trace can transition to PLAN. Attempt a minimal reproduction and call record_issue_reproduction (performed: true, commands, output_summary), or restart with /swarm issue --no-repro.",nextLastTransition:"REPRO_GATE",nextStatus:"in_progress"};return noop}if(traceState.lastTransition===null||traceState.lastTransition==="ISSUE_INGEST_TO_PLAN"||traceState.lastTransition==="REPRO_GATE"){if(traceState.lastTransition==="ISSUE_INGEST_TO_PLAN")return noop;return{nextMode:"PLAN",directive:null,nextLastTransition:"ISSUE_INGEST_TO_PLAN",nextStatus:"in_progress"}}return noop}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",nextStatus:"in_progress"}}if(!workflowArtifacts.planExists)return noop;if(!workflowArtifacts.implementationReviewVerified&&traceState.lastTransition!=="REVIEW_GATE"&&traceState.lastTransition!=="RECURRENCE_GATE"&&traceState.lastTransition!=="EXECUTE_TO_COMMIT")return{nextMode:"EXECUTE",directive:"All implementation phases are complete, but the independent implementation review is not yet recorded. Dispatch a FRESH-context reviewer and then a FRESH-context critic over the implementation diff (separate contexts from the implementer); when both approve, call record_implementation_review (issueNumber, reviewerVerdict APPROVE, criticVerdict APPROVE, the reviewed diff base/head, and notes). The trace will not hand off to commit-pr until this receipt exists.",nextLastTransition:"REVIEW_GATE",nextStatus:"in_progress"};if(workflowArtifacts.implementationReviewVerified&&!workflowArtifacts.recurrenceSweepVerified&&traceState.lastTransition!=="RECURRENCE_GATE"&&traceState.lastTransition!=="EXECUTE_TO_COMMIT")return{nextMode:"EXECUTE",directive:'The implementation review is approved, but the recurrence sweep is not yet recorded. Characterize the defect class, search the repository with explicit predicates, disposition every hit (FIX / FALSE_POSITIVE / OUT_OF_CLASS / DEFERRED_WITH_USER_APPROVAL), and install a guardrail that provably catches the original defect — or record the "no defect class" fast path with a one-line justification. Then call record_recurrence_sweep. The trace will not hand off to commit-pr until this receipt exists.',nextLastTransition:"RECURRENCE_GATE",nextStatus:"in_progress"};if(!workflowArtifacts.implementationReviewVerified||!workflowArtifacts.recurrenceSweepVerified)return noop;if(traceState.lastTransition==="EXECUTE_TO_COMMIT")return noop;return{nextMode:null,directive:"All implementation phases are complete. Compose commit-pr to publish the PR. Read .swarm/issue-reference.json for Closes #N. After the PR is created/updated, call record_issue_publication (with the issue number, PR number, URL, and HEAD sha) so this trace reaches its terminal published state — the trace is NOT complete until publication is confirmed.",nextLastTransition:"EXECUTE_TO_COMMIT",nextStatus:"publication_handoff"}}init_manager();import{existsSync as existsSync119,mkdirSync as mkdirSync61,readFileSync as readFileSync92,renameSync as renameSync37,unlinkSync as unlinkSync37,writeFileSync as writeFileSync42}from"node:fs";import*as path235 from"node:path";async function _defaultLoadPlanFromLedger(directory){return loadPlan(directory)}async function _defaultReproductionReceiptExists(directory,issueNumber){try{let filePath=path235.join(directory,".swarm","reproduction.json"),raw=_internals174.readFileSync(filePath,"utf-8"),parsed=JSON.parse(raw);if(typeof parsed!=="object"||parsed===null)return!1;let o=parsed;return o.performed===!0&&typeof o.issueNumber==="number"&&o.issueNumber===issueNumber}catch{return!1}}async function _defaultPublicationReceiptExists(directory,issueNumber){try{let filePath=path235.join(directory,".swarm","issue-publication.json"),raw=_internals174.readFileSync(filePath,"utf-8"),parsed=JSON.parse(raw);if(typeof parsed!=="object"||parsed===null)return!1;let o=parsed;return o.published===!0&&typeof o.issueNumber==="number"&&o.issueNumber===issueNumber}catch{return!1}}async function _defaultRecurrenceSweepReceiptExists(directory,issueNumber){try{let filePath=path235.join(directory,".swarm","recurrence-sweep.json"),raw=_internals174.readFileSync(filePath,"utf-8"),parsed=JSON.parse(raw);if(typeof parsed!=="object"||parsed===null)return!1;let o=parsed;if(o.issueNumber!==issueNumber||typeof o.defectClass!=="string"||o.defectClass.trim().length===0)return!1;if(o.defectClass!=="no defect class"){let{predicates,dispositions,guardrail}=o,validPredicates=Array.isArray(predicates)&&predicates.length>0&&predicates.every((p)=>typeof p==="string"&&p.trim().length>0),validDispositions=Array.isArray(dispositions)&&dispositions.every((d)=>typeof d==="object"&&d!==null&&typeof d.ref==="string"&&["FIX","FALSE_POSITIVE","OUT_OF_CLASS","DEFERRED_WITH_USER_APPROVAL"].includes(String(d.disposition))),validGuardrail=typeof guardrail==="object"&&guardrail!==null&&typeof guardrail.kind==="string"&&typeof guardrail.proof==="string";if(!validPredicates||!validDispositions||!validGuardrail)return!1}else if(typeof o.justification!=="string"||o.justification.trim().length===0)return!1;return!0}catch{return!1}}async function _defaultImplementationReviewReceiptExists(directory,issueNumber){try{let filePath=path235.join(directory,".swarm","implementation-review.json"),raw=_internals174.readFileSync(filePath,"utf-8"),parsed=JSON.parse(raw);if(typeof parsed!=="object"||parsed===null)return!1;let o=parsed;return o.issueNumber===issueNumber&&o.reviewerVerdict==="APPROVE"&&o.criticVerdict==="APPROVE"}catch{return!1}}var _internals174={readFileSync:readFileSync92,writeFileSync:writeFileSync42,existsSync:existsSync119,renameSync:renameSync37,mkdirSync:mkdirSync61,unlinkSync:unlinkSync37,loadPlanFromLedger:_defaultLoadPlanFromLedger,reproductionReceiptExists:_defaultReproductionReceiptExists,publicationReceiptExists:_defaultPublicationReceiptExists,recurrenceSweepReceiptExists:_defaultRecurrenceSweepReceiptExists,implementationReviewReceiptExists:_defaultImplementationReviewReceiptExists},TRACE_STATUSES=["in_progress","publication_handoff","published"];function isTraceStatus(value){return typeof value==="string"&&TRACE_STATUSES.includes(value)}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 isValidTraceStateShape(obj){if(typeof obj!=="object"||obj===null)return!1;let o=obj;return typeof o.issueNumber==="number"&&(o.lastTransition===null||typeof o.lastTransition==="string")}function normalizeTraceState(obj){let status;if(isTraceStatus(obj.status))status=obj.status;else if(obj.status===void 0&&typeof obj.completed==="boolean")status=obj.completed?"publication_handoff":"in_progress";else status="in_progress";return{issueNumber:obj.issueNumber,lastTransition:obj.lastTransition===null||typeof obj.lastTransition==="string"?obj.lastTransition:null,status}}function readIssueReference(directory){try{let filePath=path235.join(directory,".swarm","issue-reference.json"),raw=_internals174.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,status:"in_progress"};try{let filePath=path235.join(directory,".swarm","issue-trace-state.json"),raw=_internals174.readFileSync(filePath,"utf-8"),parsed=JSON.parse(raw);if(!isValidTraceStateShape(parsed))return defaultState;return normalizeTraceState(parsed)}catch{return defaultState}}function writeTraceState(directory,state){let swarmDir=path235.join(directory,".swarm");_internals174.mkdirSync(swarmDir,{recursive:!0});let finalPath=path235.join(swarmDir,"issue-trace-state.json"),tmpPath=path235.join(swarmDir,`issue-trace-state.tmp.${process.pid}.${Date.now()}.json`);_internals174.writeFileSync(tmpPath,JSON.stringify(state,null,2),"utf-8");try{_internals174.renameSync(tmpPath,finalPath)}catch{try{_internals174.unlinkSync(finalPath)}catch{}try{_internals174.renameSync(tmpPath,finalPath)}catch(retryErr){try{_internals174.unlinkSync(tmpPath)}catch{}throw retryErr}}}function readSpecIssueNumber(directory){try{let filePath=path235.join(directory,".swarm","spec.md"),raw=_internals174.readFileSync(filePath,"utf-8"),sectionStart=raw.indexOf("## Source Issue");if(sectionStart===-1)return null;let nextHeading=raw.indexOf(`
6310
+ ${errorSummary}`)}}}}init_pending_delegations();init_constants();init_file_locks();init_state2();init_recovery();init_utils();init_core3();init_merge();init_worktree_merge_status();init_worktree_ownership_tag();init_worktree_provisioning_owner();import*as fs131 from"node:fs";import*as fsPromises10 from"node:fs/promises";import*as path233 from"node:path";var INIT_ORPHAN_RECOVERY_TIMEOUT_MS=1e4,OWNERSHIP_TAG_SCAN_TIMEOUT_MS2=2000;async function listOwnershipTagSessionIds(directory){let scan=await scanBackgroundWorktreeOwnershipTagsForRecovery(directory);if(scan.status==="uncertain")return scan;return{status:"ok",sessionIds:[...new Set(scan.owners.map((owner)=>owner.sessionId))]}}var ORPHAN_RECOVERY_LOCK_FILE=WORKTREE_LIFECYCLE_LOCK_FILE,_internals173={rmSync:fs131.rmSync,removeWorktree,isLocked,listActiveLocks,tryAcquireLock,listOwnershipTagSessionIds,scanDelegationsForRecovery,scanDelegationFallbacksForRecovery,scanWorktreeMergeFailuresForRecovery,scanWorktreeProvisioningOwnersForRecovery,scanRegisteredWorktreeLiveness,removeWorktreeProvisioningOwner};async function writeAdvisoryFile(directory,cleanupResult,warnings,attempted,removedWorktrees=[]){let advisoryPath=path233.join(directory,".swarm","advisories","init-orphan-recovery.json"),advisory={initTimestamp:new Date().toISOString(),warnings,errors:cleanupResult.errors,reclaimed:{removedBranches:cleanupResult.removed,removedWorktrees,prunedWorktrees:attempted},...cleanupResult.skippedRecoveryBranches&&cleanupResult.skippedRecoveryBranches.length>0?{preservedRecoveryBranches:cleanupResult.skippedRecoveryBranches}:{},...cleanupResult.recoveryReadError?{recoveryReadError:!0,note:"skipped all lane-branch deletions this pass because .swarm/recovery/ was unreadable (fail-safe)"}:{}};try{await fsPromises10.mkdir(path233.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,protectedWorktreePaths=new Set){let orphanedDirs=[],worktreeRoot=path233.resolve(path233.dirname(directory),SWARM_WORKTREE_DIR_NAME),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(path233.join(worktreeRoot,sessionId),{withFileTypes:!0})}catch{continue}for(let laneEntry of sessionEntries){if(!laneEntry.isDirectory())continue;let worktreePath=path233.join(worktreeRoot,sessionId,laneEntry.name);if(protectedWorktreePaths.has(path233.resolve(worktreePath)))continue;orphanedDirs.push(worktreePath)}}return orphanedDirs}async function isCrossProcessLockHeld(directory){if(_internals173.isLocked(directory,ORPHAN_RECOVERY_LOCK_FILE))return!0;if(_internals173.listActiveLocks(directory).length>0)return!0;return!1}async function removeOrphanedWorktreeDir(worktreePath,projectRoot){if(!fs131.existsSync(path233.join(worktreePath,".git")))try{_internals173.rmSync(worktreePath,{recursive:!0,force:!0});return}catch(error93){return error93 instanceof Error?error93.message:String(error93)}let removeResult=await _internals173.removeWorktree(worktreePath,projectRoot);if(!("error"in removeResult))return;try{_internals173.rmSync(worktreePath,{recursive:!0,force:!0});return}catch{return removeResult.error}}async function crossProcessAdvisoryResult(directory,warning){let result={attempted:!0,crossProcessLockHeld:!0,warnings:[warning],orphanedBranches:[],removedWorktrees:[],prunedWorktrees:!1};return await writeAdvisoryFile(directory,{removed:[],skipped:[],errors:[]},result.warnings,!1,[]),result}function worktreePathKey(worktreePath,directory){let absolutePath2=path233.isAbsolute(worktreePath)?worktreePath:path233.resolve(directory,worktreePath),normalized=path233.normalize(absolutePath2);return process.platform==="win32"?normalized.toLowerCase():normalized}async function runInitOrphanRecovery(directory){let result,recoveryLockRelease;try{if(await isCrossProcessLockHeld(directory))return crossProcessAdvisoryResult(directory,"Cross-process lock held — another opencode process may be active. "+"Skipping destructive cleanup to preserve its worktrees/branches. Run '/swarm status' or check '.swarm/locks/' to identify active processes.");let lockAcquireResult=await _internals173.tryAcquireLock(directory,ORPHAN_RECOVERY_LOCK_FILE,"init-orphan-recovery","init");if(!lockAcquireResult.acquired)return crossProcessAdvisoryResult(directory,"Cross-process lifecycle lock was acquired by another process during init; skipping destructive cleanup to preserve its worktrees/branches.");recoveryLockRelease=lockAcquireResult.lock._release;let activeSessionIds=Array.from(swarmState.agentSessions.keys()),provisioningOwnerScan=await withTimeout(Promise.resolve(_internals173.scanWorktreeProvisioningOwnersForRecovery(directory)),INIT_ORPHAN_RECOVERY_TIMEOUT_MS,Error("worktree provisioning ownership scan exceeded its bounded init budget"));if(provisioningOwnerScan.status==="uncertain")throw Error(`worktree provisioning ownership state is uncertain; destructive orphan cleanup skipped: ${provisioningOwnerScan.reason}`);let registeredWorktrees=provisioningOwnerScan.owners.length===0?{status:"ok",liveBranches:[]}:await withTimeout(_internals173.scanRegisteredWorktreeLiveness(directory),OWNERSHIP_TAG_SCAN_TIMEOUT_MS2,Error("registered worktree liveness scan exceeded its bounded init budget"));if(registeredWorktrees.status==="uncertain")throw Error(`registered worktree liveness is uncertain; destructive orphan cleanup skipped: ${registeredWorktrees.reason}`);let liveBranches=new Set(registeredWorktrees.liveBranches),now2=Date.now();for(let owner of provisioningOwnerScan.owners){let leaseIsLive=now2-owner.createdAt<=WORKTREE_PROVISIONING_OWNER_LEASE_MS,sessionIds=new Set([owner.parentSessionId,owner.worktreeSessionId]),branchIsLive=owner.schemaVersion===2?[...sessionIds].some((sessionId)=>liveBranches.has(`swarm/lane/${sessionId}/${owner.taskId}`)||liveBranches.has(`swarm-lane/${sessionId}/${owner.taskId}`)):[...liveBranches].some((branch)=>{let segments=branch.split("/"),sessionId=segments[0]==="swarm"&&segments.length>=4?segments[2]:segments[0]==="swarm-lane"&&segments.length>=3?segments[1]:void 0;return sessionId!==void 0&&sessionIds.has(sessionId)});if(!leaseIsLive&&!branchIsLive){if(!_internals173.removeWorktreeProvisioningOwner(directory,owner.callID))throw Error(`expired worktree provisioning owner ${owner.callID} could not be removed; destructive orphan cleanup skipped`);continue}if(!activeSessionIds.includes(owner.worktreeSessionId))activeSessionIds.push(owner.worktreeSessionId);if(!activeSessionIds.includes(owner.parentSessionId))activeSessionIds.push(owner.parentSessionId)}let ownershipTagScan=await withTimeout(_internals173.listOwnershipTagSessionIds(directory),OWNERSHIP_TAG_SCAN_TIMEOUT_MS2,Error("background ownership tag scan exceeded its bounded init budget"));if(ownershipTagScan.status==="uncertain")throw Error(`background ownership tag state is uncertain; destructive orphan cleanup skipped: ${ownershipTagScan.reason}`);for(let sessionId of ownershipTagScan.sessionIds)if(!activeSessionIds.includes(sessionId))activeSessionIds.push(sessionId);let fallbackOwnerScan=await withTimeout(_internals173.scanDelegationFallbacksForRecovery(directory),INIT_ORPHAN_RECOVERY_TIMEOUT_MS,Error("background delegation fallback ownership scan exceeded its bounded init budget"));if(fallbackOwnerScan.status==="uncertain")throw Error(`background fallback ownership state is uncertain; destructive orphan cleanup skipped: ${fallbackOwnerScan.reason}`);let primaryOwnerScan=await withTimeout(Promise.resolve(_internals173.scanDelegationsForRecovery(directory)),INIT_ORPHAN_RECOVERY_TIMEOUT_MS,Error("background primary ownership scan exceeded its bounded init budget"));if(primaryOwnerScan.status==="uncertain")throw Error(`background primary ownership state is uncertain; destructive orphan cleanup skipped: ${primaryOwnerScan.reason}`);let isUnsettledWorktreeOwner=(record3)=>Boolean(record3.worktree)&&!(record3.coderSettlement?.state==="settled"&&record3.coderSettlement.outcome?.kind==="standard-worktree"&&(record3.coderSettlement.outcome.result==="merged"||record3.coderSettlement.outcome.result==="unchanged")),durableWorktreeOwners=primaryOwnerScan.owners.filter(isUnsettledWorktreeOwner),mergeOwnerScan=await withTimeout(Promise.resolve(_internals173.scanWorktreeMergeFailuresForRecovery(directory)),INIT_ORPHAN_RECOVERY_TIMEOUT_MS,Error("worktree merge ownership scan exceeded its bounded init budget"));if(mergeOwnerScan.status==="uncertain")throw Error(`worktree merge ownership state is uncertain; destructive orphan cleanup skipped: ${mergeOwnerScan.reason}`);let allDurableOwners=[...durableWorktreeOwners,...fallbackOwnerScan.owners.map((artifact)=>artifact.record).filter(isUnsettledWorktreeOwner)],preservedMergeFailures=mergeOwnerScan.failures.map(([,failure])=>failure).filter((failure)=>typeof failure.worktreePath==="string"),protectedWorktreePaths=new Set([...allDurableOwners.map((record3)=>record3.worktree?.worktreePath),...preservedMergeFailures.map((failure)=>failure.worktreePath)].filter((value)=>typeof value==="string").map((value)=>path233.resolve(value)));for(let owner of allDurableOwners){let worktreeSessionId=owner.worktree?.worktreeSessionId;if(worktreeSessionId&&!activeSessionIds.includes(worktreeSessionId))activeSessionIds.push(worktreeSessionId);if(!activeSessionIds.includes(owner.parentSessionId))activeSessionIds.push(owner.parentSessionId)}for(let failure of preservedMergeFailures){let segments=failure.branch?.split("/")??[],worktreeSessionId=segments[0]==="swarm"&&segments.length>=4?segments[2]:segments[0]==="swarm-lane"&&segments.length>=3?segments[1]:void 0;if(worktreeSessionId&&!activeSessionIds.includes(worktreeSessionId))activeSessionIds.push(worktreeSessionId)}let orphanedWorktreeDirs=await withTimeout(enumerateOrphanedWorktreeDirs(directory,activeSessionIds,protectedWorktreePaths),INIT_ORPHAN_RECOVERY_TIMEOUT_MS,Error(`runInitOrphanRecovery exceeded ${INIT_ORPHAN_RECOVERY_TIMEOUT_MS}ms budget during worktree enumeration; continuing without orphan reclamation`)),removedWorktrees=[],worktreeWarnings=[],recoveryRecords=listRecoveryRecords(directory),recoveryReadError=recoveryReadErrored(directory),recoveryWorktreePaths=new Set(recoveryRecords.map((record3)=>worktreePathKey(record3.worktreePath,directory)));if(recoveryReadError)worktreeWarnings.push("Recovery records are unreadable or fail schema validation; skipped all orphaned worktree deletion this pass (fail-safe).");else for(let worktreePath of orphanedWorktreeDirs){if(recoveryWorktreePaths.has(worktreePathKey(worktreePath,directory))){worktreeWarnings.push(`Preserved recovery worktree "${worktreePath}"; an unresolved recovery record still references it.`);continue}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,{preserveUnmerged:!0}),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:cleanupResult.recoveryReadError!==!0},await writeAdvisoryFile(directory,cleanupResult,allWarnings,!0,removedWorktrees)}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:[],skippedRecoveryBranches:[],errors:[]},result.warnings,!1,[])}finally{try{await recoveryLockRelease?.()}catch{}}return result}init_state2();import*as fs132 from"node:fs/promises";import*as path234 from"node:path";var ADVISORY_FILENAME="init-orphan-recovery.json";function createInitOrphanRecoveryAdvisoryHook(directory){let consumedBySession=new Set;async function readAdvisoryFile(){let advisoryPath=path234.join(directory,".swarm","advisories",ADVISORY_FILENAME);try{let content=await fs132.readFile(advisoryPath,"utf-8");return JSON.parse(content)}catch{return null}}async function deleteAdvisoryFile(){let advisoryPath=path234.join(directory,".swarm","advisories",ADVISORY_FILENAME);try{await fs132.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 reclaimedForGate=advisory.reclaimed;if(!((advisory.warnings?.length??0)>0||(advisory.errors?.length??0)>0||(reclaimedForGate?.removedBranches?.length??0)>0||(reclaimedForGate?.removedWorktrees?.length??0)>0))return;let targetSession=ensureAgentSession(sessionId),timestamp=advisory.initTimestamp?new Date(advisory.initTimestamp).toLocaleString():"unknown";pushAdvisory(targetSession,`[INIT ORPHAN RECOVERY] Plugin init detected the following at ${timestamp}:`);for(let warning of advisory.warnings??[])pushAdvisory(targetSession,` WARNING: ${warning}`);for(let err of advisory.errors??[])pushAdvisory(targetSession,` ERROR: ${formatError3(err)}`);let reclaimed=advisory.reclaimed;if((reclaimed?.removedBranches?.length??0)>0)pushAdvisory(targetSession,` Reclaimed ${reclaimed.removedBranches.length} orphaned branch(es): ${reclaimed.removedBranches.join(", ")}`);if(reclaimed?.removedWorktrees&&reclaimed.removedWorktrees.length>0)pushAdvisory(targetSession,` Reclaimed ${reclaimed.removedWorktrees.length} orphaned worktree directory(ies): ${reclaimed.removedWorktrees.join(", ")}`);if(reclaimed?.prunedWorktrees)pushAdvisory(targetSession," Stale worktree metadata pruned.")}return{messagesTransform}}init_logger();init_delegation_gate();import*as fs133 from"node:fs";import*as path236 from"node:path";function computeNextMode(params){let{issueReference,traceState,workflowArtifacts}=params,noop={nextMode:null,directive:null,nextLastTransition:traceState.lastTransition,nextStatus:traceState.status};if(!issueReference||issueReference.flags.trace!==!0)return noop;if(traceState.status==="published")return noop;if(traceState.status==="publication_handoff"){if(workflowArtifacts.publicationObserved&&traceState.lastTransition!=="PUBLISHED")return{nextMode:null,directive:"Publication confirmed. The issue-trace workflow is complete.",nextLastTransition:"PUBLISHED",nextStatus:"published"};return noop}if(workflowArtifacts.specIssueNumber===null||workflowArtifacts.specIssueNumber!==issueReference.number||traceState.issueNumber!==issueReference.number)return noop;if(!workflowArtifacts.specExists)return noop;if(!workflowArtifacts.planExists){if(!workflowArtifacts.reproductionPermitted){if(traceState.lastTransition===null)return{nextMode:"ISSUE_INGEST",directive:"Reproduction evidence (or a typed --no-repro waiver) is required before this trace can transition to PLAN. Attempt a minimal reproduction and call record_issue_reproduction (performed: true, commands, output_summary), or restart with /swarm issue --no-repro.",nextLastTransition:"REPRO_GATE",nextStatus:"in_progress"};return noop}if(traceState.lastTransition===null||traceState.lastTransition==="ISSUE_INGEST_TO_PLAN"||traceState.lastTransition==="REPRO_GATE"){if(traceState.lastTransition==="ISSUE_INGEST_TO_PLAN")return noop;return{nextMode:"PLAN",directive:null,nextLastTransition:"ISSUE_INGEST_TO_PLAN",nextStatus:"in_progress"}}return noop}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",nextStatus:"in_progress"}}if(!workflowArtifacts.planExists)return noop;if(!workflowArtifacts.implementationReviewVerified&&traceState.lastTransition!=="REVIEW_GATE"&&traceState.lastTransition!=="RECURRENCE_GATE"&&traceState.lastTransition!=="EXECUTE_TO_COMMIT")return{nextMode:"EXECUTE",directive:"All implementation phases are complete, but the independent implementation review is not yet recorded. Dispatch a FRESH-context reviewer and then a FRESH-context critic over the implementation diff (separate contexts from the implementer); when both approve, call record_implementation_review (issueNumber, reviewerVerdict APPROVE, criticVerdict APPROVE, the reviewed diff base/head, and notes). The trace will not hand off to commit-pr until this receipt exists.",nextLastTransition:"REVIEW_GATE",nextStatus:"in_progress"};if(workflowArtifacts.implementationReviewVerified&&!workflowArtifacts.recurrenceSweepVerified&&traceState.lastTransition!=="RECURRENCE_GATE"&&traceState.lastTransition!=="EXECUTE_TO_COMMIT")return{nextMode:"EXECUTE",directive:'The implementation review is approved, but the recurrence sweep is not yet recorded. Characterize the defect class, search the repository with explicit predicates, disposition every hit (FIX / FALSE_POSITIVE / OUT_OF_CLASS / DEFERRED_WITH_USER_APPROVAL), and install a guardrail that provably catches the original defect — or record the "no defect class" fast path with a one-line justification. Then call record_recurrence_sweep. The trace will not hand off to commit-pr until this receipt exists.',nextLastTransition:"RECURRENCE_GATE",nextStatus:"in_progress"};if(!workflowArtifacts.implementationReviewVerified||!workflowArtifacts.recurrenceSweepVerified)return noop;if(traceState.lastTransition==="EXECUTE_TO_COMMIT")return noop;return{nextMode:null,directive:"All implementation phases are complete. Compose commit-pr to publish the PR. Read .swarm/issue-reference.json for Closes #N. After the PR is created/updated, call record_issue_publication (with the issue number, PR number, URL, and HEAD sha) so this trace reaches its terminal published state — the trace is NOT complete until publication is confirmed.",nextLastTransition:"EXECUTE_TO_COMMIT",nextStatus:"publication_handoff"}}init_manager();import{existsSync as existsSync120,mkdirSync as mkdirSync61,readFileSync as readFileSync92,renameSync as renameSync36,unlinkSync as unlinkSync38,writeFileSync as writeFileSync42}from"node:fs";import*as path235 from"node:path";async function _defaultLoadPlanFromLedger(directory){return loadPlan(directory)}async function _defaultReproductionReceiptExists(directory,issueNumber){try{let filePath=path235.join(directory,".swarm","reproduction.json"),raw=_internals174.readFileSync(filePath,"utf-8"),parsed=JSON.parse(raw);if(typeof parsed!=="object"||parsed===null)return!1;let o=parsed;return o.performed===!0&&typeof o.issueNumber==="number"&&o.issueNumber===issueNumber}catch{return!1}}async function _defaultPublicationReceiptExists(directory,issueNumber){try{let filePath=path235.join(directory,".swarm","issue-publication.json"),raw=_internals174.readFileSync(filePath,"utf-8"),parsed=JSON.parse(raw);if(typeof parsed!=="object"||parsed===null)return!1;let o=parsed;return o.published===!0&&typeof o.issueNumber==="number"&&o.issueNumber===issueNumber}catch{return!1}}async function _defaultRecurrenceSweepReceiptExists(directory,issueNumber){try{let filePath=path235.join(directory,".swarm","recurrence-sweep.json"),raw=_internals174.readFileSync(filePath,"utf-8"),parsed=JSON.parse(raw);if(typeof parsed!=="object"||parsed===null)return!1;let o=parsed;if(o.issueNumber!==issueNumber||typeof o.defectClass!=="string"||o.defectClass.trim().length===0)return!1;if(o.defectClass!=="no defect class"){let{predicates,dispositions,guardrail}=o,validPredicates=Array.isArray(predicates)&&predicates.length>0&&predicates.every((p)=>typeof p==="string"&&p.trim().length>0),validDispositions=Array.isArray(dispositions)&&dispositions.every((d)=>typeof d==="object"&&d!==null&&typeof d.ref==="string"&&["FIX","FALSE_POSITIVE","OUT_OF_CLASS","DEFERRED_WITH_USER_APPROVAL"].includes(String(d.disposition))),validGuardrail=typeof guardrail==="object"&&guardrail!==null&&typeof guardrail.kind==="string"&&typeof guardrail.proof==="string";if(!validPredicates||!validDispositions||!validGuardrail)return!1}else if(typeof o.justification!=="string"||o.justification.trim().length===0)return!1;return!0}catch{return!1}}async function _defaultImplementationReviewReceiptExists(directory,issueNumber){try{let filePath=path235.join(directory,".swarm","implementation-review.json"),raw=_internals174.readFileSync(filePath,"utf-8"),parsed=JSON.parse(raw);if(typeof parsed!=="object"||parsed===null)return!1;let o=parsed;return o.issueNumber===issueNumber&&o.reviewerVerdict==="APPROVE"&&o.criticVerdict==="APPROVE"}catch{return!1}}var _internals174={readFileSync:readFileSync92,writeFileSync:writeFileSync42,existsSync:existsSync120,renameSync:renameSync36,mkdirSync:mkdirSync61,unlinkSync:unlinkSync38,loadPlanFromLedger:_defaultLoadPlanFromLedger,reproductionReceiptExists:_defaultReproductionReceiptExists,publicationReceiptExists:_defaultPublicationReceiptExists,recurrenceSweepReceiptExists:_defaultRecurrenceSweepReceiptExists,implementationReviewReceiptExists:_defaultImplementationReviewReceiptExists},TRACE_STATUSES=["in_progress","publication_handoff","published"];function isTraceStatus(value){return typeof value==="string"&&TRACE_STATUSES.includes(value)}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 isValidTraceStateShape(obj){if(typeof obj!=="object"||obj===null)return!1;let o=obj;return typeof o.issueNumber==="number"&&(o.lastTransition===null||typeof o.lastTransition==="string")}function normalizeTraceState(obj){let status;if(isTraceStatus(obj.status))status=obj.status;else if(obj.status===void 0&&typeof obj.completed==="boolean")status=obj.completed?"publication_handoff":"in_progress";else status="in_progress";return{issueNumber:obj.issueNumber,lastTransition:obj.lastTransition===null||typeof obj.lastTransition==="string"?obj.lastTransition:null,status}}function readIssueReference(directory){try{let filePath=path235.join(directory,".swarm","issue-reference.json"),raw=_internals174.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,status:"in_progress"};try{let filePath=path235.join(directory,".swarm","issue-trace-state.json"),raw=_internals174.readFileSync(filePath,"utf-8"),parsed=JSON.parse(raw);if(!isValidTraceStateShape(parsed))return defaultState;return normalizeTraceState(parsed)}catch{return defaultState}}function writeTraceState(directory,state){let swarmDir=path235.join(directory,".swarm");_internals174.mkdirSync(swarmDir,{recursive:!0});let finalPath=path235.join(swarmDir,"issue-trace-state.json"),tmpPath=path235.join(swarmDir,`issue-trace-state.tmp.${process.pid}.${Date.now()}.json`);_internals174.writeFileSync(tmpPath,JSON.stringify(state,null,2),"utf-8");try{_internals174.renameSync(tmpPath,finalPath)}catch{try{_internals174.unlinkSync(finalPath)}catch{}try{_internals174.renameSync(tmpPath,finalPath)}catch(retryErr){try{_internals174.unlinkSync(tmpPath)}catch{}throw retryErr}}}function readSpecIssueNumber(directory){try{let filePath=path235.join(directory,".swarm","spec.md"),raw=_internals174.readFileSync(filePath,"utf-8"),sectionStart=raw.indexOf("## Source Issue");if(sectionStart===-1)return null;let nextHeading=raw.indexOf(`
6304
6311
  ## `,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 _internals174.loadPlanFromLedger(directory);if(!plan||plan.phases.length===0)return{planExists:!1,allComplete:!1};return{planExists:!0,allComplete:plan.phases.every((phase)=>isPhaseComplete(phase.status))}}function specExists(directory){return _internals174.existsSync(path235.join(directory,".swarm","spec.md"))}async function reproductionReceiptExists(directory,issueNumber){return _internals174.reproductionReceiptExists(directory,issueNumber)}async function publicationReceiptExists(directory,issueNumber){return _internals174.publicationReceiptExists(directory,issueNumber)}async function recurrenceSweepReceiptExists(directory,issueNumber){return _internals174.recurrenceSweepReceiptExists(directory,issueNumber)}async function implementationReviewReceiptExists(directory,issueNumber){return _internals174.implementationReviewReceiptExists(directory,issueNumber)}var _internals175={readIssueReference,readTraceState,writeTraceState,readSpecIssueNumber,readPlanPhaseStatus,specExists,reproductionReceiptExists,publicationReceiptExists,recurrenceSweepReceiptExists,implementationReviewReceiptExists,isPlanCriticApproved,logError:error48},cachedApproval=null,cachedPhaseStatus=null;async function boundedApprovalCheck(directory,timeoutMs){try{let ledgerPath2=path236.join(directory,".swarm","plan-ledger.jsonl"),currentSize=-1;try{currentSize=fs133.statSync(ledgerPath2).size}catch{let timeout=new Promise((resolve93)=>{setTimeout(()=>resolve93(!1),timeoutMs)});return await Promise.race([_internals175.isPlanCriticApproved(directory),timeout])}if(cachedApproval&&cachedApproval.dir===directory&&cachedApproval.size===currentSize)return cachedApproval.result;let timer;try{let timeout=new Promise((resolve93)=>{timer=setTimeout(()=>resolve93(!1),timeoutMs)}),result=await Promise.race([_internals175.isPlanCriticApproved(directory),timeout]);return cachedApproval={dir:directory,size:currentSize,result},result}finally{if(timer!==void 0)clearTimeout(timer)}}catch{return!1}}async function cachedReadPlanPhaseStatus(directory){let planJsonPath=path236.join(directory,".swarm","plan.json"),currentSize=-1,currentMtime=-1;try{let stat21=fs133.statSync(planJsonPath);currentSize=stat21.size,currentMtime=stat21.mtimeMs}catch{}if(cachedPhaseStatus&&cachedPhaseStatus.dir===directory&&cachedPhaseStatus.planJsonSize===currentSize&&cachedPhaseStatus.planJsonMtime===currentMtime)return cachedPhaseStatus.result;let result=await _internals175.readPlanPhaseStatus(directory);return cachedPhaseStatus={dir:directory,planJsonSize:currentSize,planJsonMtime:currentMtime,result},result}function createIssueTraceHook(_config,directory,approvalTimeoutMs=5000){return{messagesTransform:async(_input,output)=>{try{let issueRef=_internals175.readIssueReference(directory);if(!issueRef||issueRef.flags.trace!==!0)return;let traceState=_internals175.readTraceState(directory),_specExists=_internals175.specExists(directory),_specIssueNumber=_internals175.readSpecIssueNumber(directory),phaseStatus=await cachedReadPlanPhaseStatus(directory),_criticApproved=await boundedApprovalCheck(directory,approvalTimeoutMs),_reproReceipt=await _internals175.reproductionReceiptExists(directory,issueRef.number),_reproductionPermitted=issueRef.flags.noRepro===!0||issueRef.noReproWaiver?.waived===!0||_reproReceipt,_publicationObserved=await _internals175.publicationReceiptExists(directory,issueRef.number),_implementationReviewVerified=await _internals175.implementationReviewReceiptExists(directory,issueRef.number),_recurrenceSweepVerified=await _internals175.recurrenceSweepReceiptExists(directory,issueRef.number),result=computeNextMode({issueReference:issueRef,traceState,workflowArtifacts:{specExists:_specExists,specIssueNumber:_specIssueNumber,planExists:phaseStatus.planExists,criticApproved:_criticApproved,allPhasesComplete:phaseStatus.allComplete,reproductionPermitted:_reproductionPermitted,publicationObserved:_publicationObserved,implementationReviewVerified:_implementationReviewVerified,recurrenceSweepVerified:_recurrenceSweepVerified}});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}]});let out=output;if(!Array.isArray(out.messages)||messagesToAdd.length===0)return;out.messages.push(...messagesToAdd),_internals175.writeTraceState(directory,{issueNumber:traceState.issueNumber,lastTransition:result.nextLastTransition,status:result.nextStatus})}catch(err){_internals175.logError("[issue-trace] hook cycle failed:",err)}}}}init_schema();init_state2();init_logger();import{appendFile as appendFile25,mkdir as mkdir50}from"node:fs/promises";import*as path237 from"node:path";init_knowledge_receipt_ledger();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;function selectCurrentArchitectDirectiveMemberships(memberships){let activeArchitect=memberships.filter((membership)=>membership.exposure_kind==="architect_directive"&&!membership.phase_closed_at),latest,latestAt=Number.NEGATIVE_INFINITY;for(let membership of activeArchitect){let committedAt=Date.parse(membership.committed_at),comparableAt=Number.isFinite(committedAt)?committedAt:Number.NEGATIVE_INFINITY;if(!latest||comparableAt>=latestAt)latest=membership,latestAt=comparableAt}if(!latest)return[];return activeArchitect.filter((membership)=>membership.phase===latest.phase&&membership.task_id===latest.task_id)}function selectStaleUnmarkedMemberships(memberships,now2,stalenessMs){return memberships.filter((membership)=>{if(membership.application_marker)return!1;let committedAt=Date.parse(membership.committed_at);return Number.isFinite(committedAt)&&now2-committedAt>stalenessMs})}function groupMembershipsByTrace(memberships){let byTrace=new Map;for(let membership of memberships){let group=byTrace.get(membership.trace_id)??[];group.push(membership),byTrace.set(membership.trace_id,group)}return byTrace}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");_internals176.writeWarnEvent(directory,{timestamp:new Date().toISOString(),event:"knowledge_application_gate_warn",tool:toolName,agent:agentRaw,reason:"missing_sessionID",mode:config3.mode}).catch(()=>{});return}let receiptState=await queryLiveMemberships(directory,{session_id:sessionID,include_terminal:!0,include_phase_closed:!1,exposure_kind:"architect_directive"});if(!receiptState.ok){if(config3.mode==="enforce")throw Error(`KNOWLEDGE_ENFORCE_GATE_DENY: receipt authority unavailable (${receiptState.code}); refusing to infer acknowledgment from diagnostics`);writeWarnEvent2(directory,{timestamp:new Date().toISOString(),event:"knowledge_application_gate_warn",tool:toolName,agent:agentRaw,sessionID,reason:receiptState.code});return}let criticalMemberships=selectCurrentArchitectDirectiveMemberships(receiptState.memberships).filter((membership)=>membership.critical);if(criticalMemberships.length===0){clearGateDenialCount(sessionID);return}let unackedMemberships=criticalMemberships.filter((membership)=>!membership.application_marker);if(unackedMemberships.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,now2=Date.now(),staleMemberships=selectStaleUnmarkedMemberships(unackedMemberships,now2,stalenessMs);if(staleMemberships.length>0){for(let[traceId,memberships]of groupMembershipsByTrace(staleMemberships)){let committed=await commitApplicationOutcomeBatch(directory,{trace_id:traceId,session_id:sessionID,items:memberships.map((membership)=>({entry_id:membership.entry_id,outcome:"applied",source:"application_gate_staleness_clear",reason:"configured staleness escape hatch"}))});if(!committed.ok||committed.rejected.length>0)throw Error("KNOWLEDGE_ENFORCE_GATE_DENY: could not durably record staleness clear")}let stalePairs=new Set(staleMemberships.map((membership)=>`${membership.trace_id}/${membership.entry_id}`));unackedMemberships=unackedMemberships.filter((membership)=>!stalePairs.has(`${membership.trace_id}/${membership.entry_id}`));let staleIds=[...new Set(staleMemberships.map((membership)=>membership.entry_id))];for(let id of staleIds)if(!unackedMemberships.some((membership)=>membership.entry_id===id))addKnowledgeAckDedup(buildAckDedupKey(sessionID,id,"applied"));if(clearGateDenialCount(sessionID),await writeWarnEvent2(directory,{timestamp:new Date().toISOString(),event:"knowledge_application_gate_staleness_clear",tool:toolName,agent:agentRaw,sessionID,cleared_ids:staleIds,cleared_pairs:[...stalePairs],age_ms:Math.max(...staleMemberships.map((membership)=>now2-Date.parse(membership.committed_at))),staleness_threshold_ms:stalenessMs}).catch((err)=>{warn(`[knowledge-application-gate] staleness-clear audit write failed: ${err instanceof Error?err.message:String(err)}`)}),unackedMemberships.length===0){clearCriticalShownIds(sessionID);return}}let unackedPairs2=unackedMemberships.map((membership)=>`${membership.trace_id}/${membership.entry_id}`),unacked2=[...new Set(unackedMemberships.map((membership)=>membership.entry_id))],directiveKey=buildGateDenialDirectiveKey(unackedPairs2),denials=incrementGateDenialCount(sessionID,directiveKey);if(denials>maxDenials){for(let[traceId,memberships]of groupMembershipsByTrace(unackedMemberships)){let committed=await commitApplicationOutcomeBatch(directory,{trace_id:traceId,session_id:sessionID,items:memberships.map((membership)=>({entry_id:membership.entry_id,outcome:"applied",source:"application_gate_denial_limit_clear",reason:"configured denial-count escape hatch"}))});if(!committed.ok||committed.rejected.length>0)throw Error("KNOWLEDGE_ENFORCE_GATE_DENY: could not durably record denial-limit clear")}for(let id of unacked2)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:unacked2,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=unackedPairs2.join(", ");throw Error(`KNOWLEDGE_ENFORCE_GATE_DENY: ${toolName} blocked — critical knowledge membership(s) ${ids} require exact-pair KNOWLEDGE_APPLIED:<trace_id>:<entry_id>, KNOWLEDGE_N_A:<trace_id>:<entry_id> reason=... (does not apply; neutral), KNOWLEDGE_IGNORED:<trace_id>:<entry_id> reason=... (relevant but deliberately not followed), KNOWLEDGE_CONTRADICTED:<trace_id>:<entry_id> reason=..., or KNOWLEDGE_VIOLATED:<trace_id>:<entry_id> reason=... before this action.`)}let unacked=[...new Set(unackedMemberships.map((membership)=>membership.entry_id))],unackedPairs=unackedMemberships.map((membership)=>`${membership.trace_id}/${membership.entry_id}`);writeWarnEvent2(directory,{timestamp:new Date().toISOString(),event:"knowledge_application_gate_warn",tool:toolName,agent:agentRaw,sessionID,unacknowledged_critical_ids:unacked,unacknowledged_critical_pairs:unackedPairs}).catch(()=>{})}async function writeWarnEvent2(directory,record3){let filePath=path237.join(directory,".swarm","events.jsonl");await mkdir50(path237.dirname(filePath),{recursive:!0}),await appendFile25(filePath,`${JSON.stringify(record3)}
6305
6312
  `,"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(`
6306
6313
  `);if(!text)return;let acks=parseAcknowledgments(text);if(acks.length===0)return;let ctx={sessionId:sessionID},live=await queryLiveMemberships(directory,{session_id:sessionID,include_terminal:!0,include_phase_closed:!1,exposure_kind:"architect_directive"});if(!live.ok){warn(`[knowledge-application-gate] receipt authority unavailable: ${live.code}`);return}for(let ack of acks){if(!ack.trace_id)continue;let key=buildAckDedupKey(sessionID,JSON.stringify([ack.trace_id,ack.id]),ack.result);if(swarmState.knowledgeAckDedup.has(key))continue;let memberships=live.memberships.filter((membership)=>membership.trace_id===ack.trace_id&&membership.entry_id===ack.id&&!membership.application_marker);if(memberships.length===0)continue;let byTrace=new Map;for(let membership of memberships){let group=byTrace.get(membership.trace_id)??[];group.push(membership),byTrace.set(membership.trace_id,group)}let committedAll=!0,newlyCommitted=!1;for(let[traceId,group]of byTrace){let committed=await commitApplicationOutcomeBatch(directory,{trace_id:traceId,session_id:sessionID,items:group.map((membership)=>({entry_id:membership.entry_id,outcome:ack.result,source:"architect_marker",reason:ack.reason}))});if(!committed.ok||committed.rejected.length>0){committedAll=!1;break}if(committed.committed.length>0)newlyCommitted=!0}if(!committedAll)continue;if(addKnowledgeAckDedup(key),!newlyCommitted)continue;try{await recordAcknowledgment(directory,ack,ctx)}catch(err){warn(`[knowledge-application-gate] transform-scan record failed: ${err instanceof Error?err.message:String(err)}`)}}}var _internals176={knowledgeApplicationGateBefore,knowledgeApplicationTransformScan,HIGH_RISK_TOOLS,writeWarnEvent:writeWarnEvent2,selectCurrentArchitectDirectiveMemberships,selectStaleUnmarkedMemberships};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+)/,_internals177={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 _internals177.subscribe(directory,{sessionID,prNumber:prInfo.prNumber,repoFullName:prInfo.repoFullName,prUrl:prInfo.prUrl,maxSubscriptions:config3.max_subscriptions}),_internals177.log("[pr-monitor] Auto-subscribed session to created PR",{sessionID,pr:`${prInfo.repoFullName}#${prInfo.prNumber}`})}catch(err){_internals177.log("[pr-monitor] Auto-subscribe failed (non-fatal)",{error:err instanceof Error?err.message:String(err)})}}}}init_pr_workflow_gate();init_pr_feedback_event_queue();init_pr_workflow_auto_wake();init_pr_workflow_gate();init_utils2();import*as fsp6 from"node:fs/promises";var DEFAULT_WAKE_TIMEOUT_MS=5000,_internals178={readPrWorkflowGateState,claimPrFeedbackMonitorEvents,readPrFeedbackMonitorQueue},DEFAULT_MAX_CONSECUTIVE_UNPRODUCTIVE_WAKES=5,DEFAULT_WAKE_COOLDOWN_MS=30000,DEFAULT_BANNER_COOLDOWN_MS=20000,MAX_FALLBACK_BANNER_INJECTIONS_PER_SESSION=20,BANNER_PREFIX_PATTERN=/^--- \[(?:PR_REVIEW|PR_FEEDBACK) WORKFLOW ACTIVE/,DEFAULT_TOTAL_WAKE_CEILINGS={S:12,M:54,L:102},MAX_TRACKED_WAKE_SESSIONS=200;function isValidTotalWakeCeiling(value){return value!==void 0&&Number.isInteger(value)&&value>0}function canonicalGitHubPrUrl5(value){try{let url3=new URL(value),match=url3.pathname.match(/^\/([^/]+)\/([^/]+)\/pull\/(\d+)\/?$/);if(url3.protocol!=="https:"||url3.hostname.toLowerCase()!=="github.com"||!match)return null;let number7=Number(match[3]);if(!Number.isSafeInteger(number7)||number7<=0)return null;return`github.com/${match[1].toLowerCase()}/${match[2].toLowerCase()}/pull/${number7}`}catch{return null}}function sameGitHubPr3(left,right){let leftCanonical=canonicalGitHubPrUrl5(left);return leftCanonical!==null&&leftCanonical===canonicalGitHubPrUrl5(right)}function formatQueuedMonitorEventsText(events){if(events.length===0)return"";return["Queued PR monitor events are now authorized for this PR_FEEDBACK workflow and must be treated as feedback inputs for the current round:",...events.map((event)=>`- ${event.type} on ${event.repoFullName}#${event.prNumber}: ${event.message.split(`
@@ -6314,7 +6321,7 @@ Do not stop or summarize. Inspect the durable gate, dispatch or collect the next
6314
6321
  ${output.text}`;return}let banner=workflowBanner(state.mode,{suspended,suspendedReason,userInterrupted,maxConsecutive,recovery});bannerStamps.set(input.sessionID,now2),evictBannerDedupeMapsIfOverBound(),output.text=`${banner}
6315
6322
 
6316
6323
  ${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 candidate2=result?.data?.parentID;if(typeof candidate2==="string"&&candidate2.trim())parent=candidate2.trim()}}if(!parent)return original;rememberBounded2(parents,current,parent),current=parent}return original}}}init_review_receipt_collector();init_schema();init_scope_binding();init_state2();init_normalize_tool_name();init_review_receipt();init_review_receipt_scope();init_reviewer_scope_file_fingerprint();init_skill_propagation_gate();init_task_result_classifier();function lifecycleTarget(args2){let delegation=parseDelegationArgs(args2);return delegation?stripKnownSwarmPrefix(delegation.targetAgent).toLowerCase():""}function isTaskTool6(tool3){if(typeof tool3!=="string")return!1;let normalized=normalizeToolName(tool3);return normalized==="Task"||normalized==="task"}function generationFingerprintsAreCurrent(directory,generation){let{modifiedFiles,modifiedFileFingerprints:fingerprints}=generation;if(modifiedFiles.length===0||modifiedFiles.length!==fingerprints.length||new Set(modifiedFiles).size!==modifiedFiles.length||new Set(fingerprints.map((entry)=>entry.file)).size!==fingerprints.length)return!1;let fingerprintBytes=0;for(let file3 of modifiedFiles){let stored=fingerprints.filter((entry)=>entry.file===file3),current=captureReviewerScopeFileFingerprint(directory,file3,MAX_REVIEWER_SCOPE_FINGERPRINT_AGGREGATE_BYTES-fingerprintBytes);if(stored.length!==1||!current||!reviewerScopeFileFingerprintsEqual(stored[0],current))return!1;if(current.kind==="file")fingerprintBytes+=current.size}return!0}function scopeMatchesGenerationFingerprints(scope,generation){let records=new Map;for(let line of scope.content.split(`
6317
- `).slice(1)){if(!line)continue;try{let parsed=JSON.parse(line);if(typeof parsed.path==="string")records.set(parsed.path,parsed)}catch{return!1}}if(records.size!==generation.modifiedFileFingerprints.length||scope.files.length!==generation.modifiedFiles.length)return!1;return generation.modifiedFileFingerprints.every((fingerprint2)=>{let record3=records.get(fingerprint2.file);if(!record3)return!1;return fingerprint2.kind==="deleted"?record3.state==="deleted":record3.state==="file"&&record3.bytes===fingerprint2.size&&record3.sha256===fingerprint2.hash})}async function beginApprovedReviewerScopeLifecycle(input){if(!isTaskTool6(input.tool))return null;let taskId=await resolveReviewerScopeTaskId(input.directory,input.args);if(!taskId)return null;let target=lifecycleTarget(input.args);if(target==="coder"){let binding=getScopeBindingForParentDispatch({parentSessionId:input.parentSessionID,dispatchCallId:input.callID});if(binding?.taskId!==taskId)return null;let rawArgs=input.args&&typeof input.args==="object"?input.args:null;return startReviewerScopeGeneration({parentSessionID:input.parentSessionID,taskId,coderCallID:input.callID,background:rawArgs?.background===!0||rawArgs?.background==="true",declaredFiles:binding.files})?"coder_started":null}if(target==="reviewer"){let ready=peekReadyReviewerScopeGeneration({parentSessionID:input.parentSessionID,taskId});if(!ready||!generationFingerprintsAreCurrent(input.directory,ready)){if(ready)discardReviewerScopeGenerationForCoderCall({parentSessionID:input.parentSessionID,taskId,coderCallID:ready.coderCallID});throw Error("REVIEWER_SCOPE_STALE: coder post-write fingerprints are incomplete or changed before reviewer dispatch")}let snapshot=await buildReviewerTaskScope(input.directory,ready.modifiedFiles,input.maxBytes,{taskId:ready.taskId,coderCallID:ready.coderCallID,generation:ready.generation,sessionIncarnation:ready.sessionIncarnation}),current=peekReadyReviewerScopeGeneration({parentSessionID:input.parentSessionID,taskId}),exactGenerationStillCurrent=current!==null&&current.coderCallID===ready.coderCallID&&current.generation===ready.generation&&current.sessionIncarnation===ready.sessionIncarnation&&isReviewerScopeGenerationCurrent({parentSessionID:input.parentSessionID,taskId,coderCallID:ready.coderCallID,generation:ready.generation,sessionIncarnation:ready.sessionIncarnation});if(!snapshot||!current||!exactGenerationStillCurrent||!generationFingerprintsAreCurrent(input.directory,current)||!scopeMatchesGenerationFingerprints(snapshot,current))throw discardReviewerScopeGenerationForCoderCall({parentSessionID:input.parentSessionID,taskId,coderCallID:ready.coderCallID}),Error("REVIEWER_SCOPE_STALE: exact reviewer dispatch scope changed during capture");let claimed=claimReviewerScopeGeneration({parentSessionID:input.parentSessionID,taskId,reviewerCallID:input.callID});if(!claimed||claimed.coderCallID!==ready.coderCallID||claimed.generation!==ready.generation||claimed.sessionIncarnation!==ready.sessionIncarnation||!attachReviewerScopeGenerationDispatchSnapshot({parentSessionID:input.parentSessionID,taskId,reviewerCallID:input.callID,snapshot:{hash:computeScopeFingerprint(snapshot.content,snapshot.description).hash,description:snapshot.description,files:[...snapshot.files],headSha:snapshot.headSha,taskId:claimed.taskId,coderCallID:claimed.coderCallID,generation:claimed.generation,sessionIncarnation:claimed.sessionIncarnation}}))throw discardReviewerScopeGenerationClaim({parentSessionID:input.parentSessionID,taskId,reviewerCallID:input.callID}),Error("REVIEWER_SCOPE_STALE: exact reviewer dispatch scope could not be captured");return"reviewer_claimed"}return null}async function completeReviewerScopeLifecycle(input){if(!isTaskTool6(input.tool))return null;if(lifecycleTarget(input.args)!=="coder")return null;let result=classifyTaskResult(input.output);if(result==="running")return null;let taskId=await resolveReviewerScopeTaskId(input.directory,input.args);if(!taskId)return discardReviewerScopeGenerationForCoderCall({parentSessionID:input.parentSessionID,coderCallID:input.callID}),null;if(result==="non_success")return discardReviewerScopeGenerationForCoderCall({parentSessionID:input.parentSessionID,taskId,coderCallID:input.callID}),null;return markReviewerScopeGenerationReady({parentSessionID:input.parentSessionID,taskId,coderCallID:input.callID})?"coder_ready":null}init_reviewer_directive_compliance();init_schema();init_bun_compat();init_logger();var import_picomatch2=__toESM(require_picomatch2(),1);import{existsSync as existsSync120,readdirSync as readdirSync33,readFileSync as readFileSync93,statSync as statSync50}from"node:fs";import*as path238 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=path238.resolve(directory),resolved=path238.resolve(baseDir,concrete),rel=path238.relative(baseDir,resolved);if(rel.startsWith("..")||path238.isAbsolute(rel))return null}return v}function findBinaryInPath(binary){let candidates=process.platform==="win32"?[`${binary}.exe`,`${binary}.cmd`,`${binary}.bat`,binary]:[binary];for(let dir of(process.env.PATH??"").split(path238.delimiter)){if(!dir)continue;for(let name of candidates){let candidate2=path238.join(dir,name);if(existsSync120(candidate2))return candidate2}}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((resolve94)=>setTimeout(()=>resolve94("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=readdirSync33(dir,{withFileTypes:!0})}catch{return}for(let entry of entries){if(visited>=GREP_MAX_FILES)return;let fullPath=path238.join(dir,entry.name),relPath=path238.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(statSync50(fullPath).size>GREP_MAX_BYTES_PER_FILE)continue;let found=readFileSync93(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(path238.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 changed2=await changedPaths(directory);if(changed2===null)return{result:"error",detail:`${label}: git unavailable or failed`};let target=path238.normalize(safe),isChanged=changed2.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_knowledge_receipt_ledger();init_skill_propagation_gate();var _internals179={validateAndCommitTerminalBatch,recordKnowledgeEvent,runDirectivePredicate,escalateViolatedEntries},VERDICT_PATTERN=/\b(VERIFIED|VIOLATED|N\/A)\s*:\s*([^:\s]{1,512})\s*:\s*([^:\s]{1,512})(?:\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(),traceId=decodeDirectiveCorrelationId(m[2]),entryId=decodeDirectiveCorrelationId(m[3]);if(!traceId||!entryId)continue;let evidence2=m[4]?.trim().slice(0,280),verdict=verb==="VERIFIED"?"verified":verb==="VIOLATED"?"violated":"n_a";out.push({trace_id:traceId,entry_id:entryId,verdict,evidence:evidence2})}return out}function verdictToEventType(v){return v==="verified"?"applied":v==="violated"?"violated":"n_a"}function pairKey2(traceId,entryId){return JSON.stringify([traceId,entryId])}async function reconcileReviewerVerdicts(params){let result={emitted:[],omittedCriticals:[],uncertainties:[]},verifyByPair=new Map(params.directivesToVerify.map((d)=>[pairKey2(d.trace_id,d.entry_id),d]));if(verifyByPair.size===0)return result;let verdictsByPair=new Map;for(let verdict of parseReviewerDirectiveCompliance(params.transcript)){let key=pairKey2(verdict.trace_id,verdict.entry_id);if(!verifyByPair.has(key))continue;let existing=verdictsByPair.get(key)??[];existing.push(verdict),verdictsByPair.set(key,existing)}let pending=[];for(let[key,directive]of verifyByPair){let matching=verdictsByPair.get(key)??[];if(matching.length>1){result.uncertainties.push({trace_id:directive.trace_id,entry_id:directive.entry_id,code:"duplicate_verdict",uncertainty:"Reviewer emitted more than one verdict for the exact pair"});continue}if(matching.length===0){if(directive.priority!=="critical")continue;result.omittedCriticals.push({trace_id:directive.trace_id,entry_id:directive.entry_id}),pending.push({directive,type:"violated",reason:"reviewer_omitted"});continue}let verdict=matching[0];if(verdict.verdict==="verified"&&!verdict.evidence?.trim()){if(result.uncertainties.push({trace_id:directive.trace_id,entry_id:directive.entry_id,code:"reviewer_missing_evidence",uncertainty:"VERIFIED requires nonempty evidence"}),directive.priority==="critical")result.omittedCriticals.push({trace_id:directive.trace_id,entry_id:directive.entry_id}),pending.push({directive,type:"violated",reason:"reviewer_missing_evidence"});continue}let item={directive,type:verdictToEventType(verdict.verdict),reason:verdict.evidence};if(verdict.verdict==="violated"&&directive.verification_predicate)try{let outcome=await _internals179.runDirectivePredicate(directive.verification_predicate,params.directory);item.predicate_check={predicate:directive.verification_predicate,result:outcome.result,detail:outcome.detail}}catch(error93){item.predicate_check={predicate:directive.verification_predicate,result:"error",detail:error93 instanceof Error?error93.message:String(error93)}}pending.push(item)}let groups=new Map;for(let item of pending){let groupKey=JSON.stringify([item.directive.trace_id,item.directive.session_id,item.directive.cohort_id,item.directive.source_link_id,item.directive.prior_terminal_outcome,item.directive.prior_terminal_event_id]),group=groups.get(groupKey)??[];group.push(item),groups.set(groupKey,group)}let violatedIds=new Set,agent=params.agent??"reviewer";for(let group of groups.values()){let first=group[0].directive,remediationAuthorization=first.prior_terminal_outcome==="violated"&&first.prior_terminal_event_id&&group.some((item)=>item.type!=="violated")?{actor:"reviewer-remediation",reason:"reviewer_verified_remediation",expected_event_id:first.prior_terminal_event_id,expected_outcome:first.prior_terminal_outcome}:void 0,committedEntries;try{let committed=await _internals179.validateAndCommitTerminalBatch(params.directory,{trace_id:first.trace_id,session_id:first.session_id,cohort_id:first.cohort_id,source_link_id:first.source_link_id,authorization:remediationAuthorization,items:group.map((item)=>({entry_id:item.directive.entry_id,outcome:item.type,source:"reviewer",reason:item.reason}))});if(!committed.ok){for(let item of group)result.uncertainties.push({trace_id:item.directive.trace_id,entry_id:item.directive.entry_id,code:committed.code,uncertainty:committed.detail});continue}committedEntries=new Set(committed.accepted.map((terminal)=>terminal.entry_id));for(let rejected of committed.rejected)result.uncertainties.push({trace_id:first.trace_id,entry_id:rejected.entry_id||void 0,code:rejected.reason,uncertainty:"Authoritative ledger rejected reviewer terminal"})}catch(error93){for(let item of group)result.uncertainties.push({trace_id:item.directive.trace_id,entry_id:item.directive.entry_id,code:"ledger_exception",uncertainty:error93 instanceof Error?error93.message:String(error93)});continue}for(let item of group){if(!committedEntries.has(item.directive.entry_id))continue;try{if(await _internals179.recordKnowledgeEvent(params.directory,{type:item.type,trace_id:item.directive.trace_id,knowledge_id:item.directive.entry_id,session_id:item.directive.session_id,task_id:params.taskId,phase:params.phase,agent,source:"reviewer",reason:item.reason,predicate_check:item.predicate_check}),result.emitted.push({trace_id:item.directive.trace_id,entry_id:item.directive.entry_id,id:item.directive.entry_id,type:item.type,source:"reviewer"}),item.type==="violated")violatedIds.add(item.directive.entry_id)}catch(error93){result.uncertainties.push({trace_id:item.directive.trace_id,entry_id:item.directive.entry_id,code:"diagnostic_event_failed",uncertainty:error93 instanceof Error?error93.message:String(error93)})}}}if(violatedIds.size>0)try{await _internals179.escalateViolatedEntries(params.directory,[...violatedIds])}catch(error93){result.uncertainties.push({trace_id:"",code:"escalation_failed",uncertainty:error93 instanceof Error?error93.message:String(error93)})}return result}function isTaskTool7(tool3){return tool3==="Task"||tool3==="task"}async function collectReviewerVerdictsAfter(directory,input,output){if(!isTaskTool7(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_path_identity();init_scope_binding();init_scope_persistence();init_scope_resolution_diagnostic();init_state2();init_normalize_tool_name();init_pr_workflow_gate();init_write_target_resolver();import*as path239 from"node:path";var WRITE_TOOLS2=new Set(WRITE_TOOL_NAMES);function createScopeGuardHook(config3,fallbackDirectory,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 directory=_internals180.resolveSessionWorkspaceDirectory(sessionId,fallbackDirectory),targets=_internals180.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=_internals180.resolveTaskId(session),seamBinding=taskId&&_internals180.resolveAuthorizedScopeBinding!==resolveAuthorizedScopeBinding?_internals180.resolveAuthorizedScopeBinding({directory,taskId,activeSessionId:sessionId}):null,resolution=seamBinding?{status:"found",binding:seamBinding}:taskId?_internals180.resolveAuthorizedScopeBindingDetailed({directory,taskId,activeSessionId:sessionId}):_internals180.resolveAuthorizedScopeBindingForSessionDetailed({directory,activeSessionId:sessionId}),binding=resolution.status==="found"?resolution.binding:null;if(!binding){if(binding=_internals180.getAuthorizedPrFeedbackScopeBinding({directory,activeSessionId:sessionId,taskId:taskId??void 0})??_internals180.resolveAuthorizedPrFeedbackScopeBindingFromDisk({directory,activeSessionId:sessionId,taskId:taskId??void 0}),binding&&!await _internals180.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){let durableDiagnostic=formatScopeResolutionDiagnostic({resolution,taskId,sessionId});if(durableDiagnostic)denyWithArchitectAdvisory(durableDiagnostic,session,injectAdvisory,swarmState);let mismatch=_internals180.describeScopeWorkspaceMismatch({directory,activeSessionId:sessionId,taskId});if(mismatch)denyWithArchitectAdvisory(`${mismatch} ${agentName} cannot invoke ${toolName} for task ${taskId??"unknown"}. ACTION[architect]: redeclare the exact scope against the reported active lane root with replace_existing=true, then dispatch a new Task call.`,session,injectAdvisory,swarmState);denyWithArchitectAdvisory(`SCOPE_NOT_DECLARED: ${agentName} cannot invoke ${toolName} without a validated scope for task ${taskId??"unknown"}. ACTION[architect]: call declare_scope with the exact workspace-relative paths and replace_existing=true, then dispatch a new Task call.`,session,injectAdvisory,swarmState)}for(let rawPath of targets.paths){let filePath=sanitizePath(rawPath),absoluteTarget=path239.resolve(directory,filePath);if(!isPathIdentityWithin(absoluteTarget,directory)){let fallbackRelative=isPathIdentityWithin(absoluteTarget,fallbackDirectory)?path239.relative(fallbackDirectory,absoluteTarget).replace(/\\/g,"/"):null,safeRetry=fallbackRelative?`detected workspace-relative path ${JSON.stringify(sanitizeDiagnosticText(fallbackRelative))}; retry exactly that relative path under the active root`:"no safe workspace-relative retry was detected; stop and correct the command or lane root";denyWithArchitectAdvisory(`SCOPE_ROOT_ESCAPE: attempted target ${JSON.stringify(sanitizeDiagnosticText(filePath))} leaves active root ${JSON.stringify(sanitizeDiagnosticText(directory))}; ${safeRetry}. ACTION[architect]: verify the active lane root, redeclare only the exact relative path with replace_existing=true, and dispatch a new Task call.`,session,injectAdvisory,swarmState)}if(!isFileInScope(filePath,declaredScope,directory))reportScopeViolation(agentName,filePath,taskId,session,injectAdvisory,swarmState,declaredScope)}}}}function isFileInScope(filePath,scopeEntries,directory){let dir=directory??process.cwd(),resolvedFile=path239.resolve(dir,filePath);return scopeEntries.filter((scope)=>scope.length>0).some((scope)=>{let resolvedScope=path239.resolve(dir,scope);return isPathIdentityWithin(resolvedFile,resolvedScope)})}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 _internals180={sanitizePath,resolveWriteTargets:resolveWriteTargets2,resolveAuthorizedScopeBindingDetailed,resolveAuthorizedScopeBindingForSessionDetailed,resolveAuthorizedScopeBinding,resolveAuthorizedScopeBindingForSession,getAuthorizedPrFeedbackScopeBinding,resolveAuthorizedPrFeedbackScopeBindingFromDisk,validatePrFeedbackScopeBinding,resolveSessionWorkspaceDirectory,describeScopeWorkspaceMismatch,resolveTaskId:(session)=>session?.currentTaskId??null};function denyWithArchitectAdvisory(message,session,injectAdvisory,state){if(session)session.lastScopeViolation=message,session.scopeViolationDetected=!0;if(injectAdvisory)for(let[architectSessionId,architectSession]of state.agentSessions){let role=state.activeAgent.get(architectSessionId)??architectSession.agentName;if(stripKnownSwarmPrefix(role)!==ORCHESTRATOR_NAME)continue;try{injectAdvisory(architectSessionId,`[SCOPE GUARD] ${message}`)}catch{}break}throw Error(message)}function reportScopeViolation(agentName,filePath,taskId,session,injectAdvisory,state,scopeEntries){let taskLabel2=taskId??"unknown",safeAgentName=sanitizeDiagnosticText(agentName,128),safeFilePath=sanitizeDiagnosticText(filePath,256),safeScope=scopeEntries.slice(0,3).map((entry)=>sanitizeDiagnosticText(entry,128)).join(", "),violationMessage=`SCOPE_VIOLATION: SCOPE VIOLATION: ${safeAgentName} attempted to modify '${safeFilePath}' which is not in declared scope for task ${taskLabel2}. Declared scope: [${safeScope}${scopeEntries.length>3?"...":""}]. Coder: correct a mistaken target; otherwise stop and ask the architect to expand declare_scope and dispatch a new Task call.`;denyWithArchitectAdvisory(violationMessage,session,injectAdvisory,state)}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(`
6324
+ `).slice(1)){if(!line)continue;try{let parsed=JSON.parse(line);if(typeof parsed.path==="string")records.set(parsed.path,parsed)}catch{return!1}}if(records.size!==generation.modifiedFileFingerprints.length||scope.files.length!==generation.modifiedFiles.length)return!1;return generation.modifiedFileFingerprints.every((fingerprint2)=>{let record3=records.get(fingerprint2.file);if(!record3)return!1;return fingerprint2.kind==="deleted"?record3.state==="deleted":record3.state==="file"&&record3.bytes===fingerprint2.size&&record3.sha256===fingerprint2.hash})}async function beginApprovedReviewerScopeLifecycle(input){if(!isTaskTool6(input.tool))return null;let taskId=await resolveReviewerScopeTaskId(input.directory,input.args);if(!taskId)return null;let target=lifecycleTarget(input.args);if(target==="coder"){let binding=getScopeBindingForParentDispatch({parentSessionId:input.parentSessionID,dispatchCallId:input.callID});if(binding?.taskId!==taskId)return null;let rawArgs=input.args&&typeof input.args==="object"?input.args:null;return startReviewerScopeGeneration({parentSessionID:input.parentSessionID,taskId,coderCallID:input.callID,background:rawArgs?.background===!0||rawArgs?.background==="true",declaredFiles:binding.files})?"coder_started":null}if(target==="reviewer"){let ready=peekReadyReviewerScopeGeneration({parentSessionID:input.parentSessionID,taskId});if(!ready||!generationFingerprintsAreCurrent(input.directory,ready)){if(ready)discardReviewerScopeGenerationForCoderCall({parentSessionID:input.parentSessionID,taskId,coderCallID:ready.coderCallID});throw Error("REVIEWER_SCOPE_STALE: coder post-write fingerprints are incomplete or changed before reviewer dispatch")}let snapshot=await buildReviewerTaskScope(input.directory,ready.modifiedFiles,input.maxBytes,{taskId:ready.taskId,coderCallID:ready.coderCallID,generation:ready.generation,sessionIncarnation:ready.sessionIncarnation}),current=peekReadyReviewerScopeGeneration({parentSessionID:input.parentSessionID,taskId}),exactGenerationStillCurrent=current!==null&&current.coderCallID===ready.coderCallID&&current.generation===ready.generation&&current.sessionIncarnation===ready.sessionIncarnation&&isReviewerScopeGenerationCurrent({parentSessionID:input.parentSessionID,taskId,coderCallID:ready.coderCallID,generation:ready.generation,sessionIncarnation:ready.sessionIncarnation});if(!snapshot||!current||!exactGenerationStillCurrent||!generationFingerprintsAreCurrent(input.directory,current)||!scopeMatchesGenerationFingerprints(snapshot,current))throw discardReviewerScopeGenerationForCoderCall({parentSessionID:input.parentSessionID,taskId,coderCallID:ready.coderCallID}),Error("REVIEWER_SCOPE_STALE: exact reviewer dispatch scope changed during capture");let claimed=claimReviewerScopeGeneration({parentSessionID:input.parentSessionID,taskId,reviewerCallID:input.callID});if(!claimed||claimed.coderCallID!==ready.coderCallID||claimed.generation!==ready.generation||claimed.sessionIncarnation!==ready.sessionIncarnation||!attachReviewerScopeGenerationDispatchSnapshot({parentSessionID:input.parentSessionID,taskId,reviewerCallID:input.callID,snapshot:{hash:computeScopeFingerprint(snapshot.content,snapshot.description).hash,description:snapshot.description,files:[...snapshot.files],headSha:snapshot.headSha,taskId:claimed.taskId,coderCallID:claimed.coderCallID,generation:claimed.generation,sessionIncarnation:claimed.sessionIncarnation}}))throw discardReviewerScopeGenerationClaim({parentSessionID:input.parentSessionID,taskId,reviewerCallID:input.callID}),Error("REVIEWER_SCOPE_STALE: exact reviewer dispatch scope could not be captured");return"reviewer_claimed"}return null}async function completeReviewerScopeLifecycle(input){if(!isTaskTool6(input.tool))return null;if(lifecycleTarget(input.args)!=="coder")return null;let result=classifyTaskResult(input.output);if(result==="running")return null;let taskId=await resolveReviewerScopeTaskId(input.directory,input.args);if(!taskId)return discardReviewerScopeGenerationForCoderCall({parentSessionID:input.parentSessionID,coderCallID:input.callID}),null;if(result==="non_success")return discardReviewerScopeGenerationForCoderCall({parentSessionID:input.parentSessionID,taskId,coderCallID:input.callID}),null;return markReviewerScopeGenerationReady({parentSessionID:input.parentSessionID,taskId,coderCallID:input.callID})?"coder_ready":null}init_reviewer_directive_compliance();init_schema();init_bun_compat();init_logger();var import_picomatch2=__toESM(require_picomatch2(),1);import{existsSync as existsSync121,readdirSync as readdirSync33,readFileSync as readFileSync93,statSync as statSync50}from"node:fs";import*as path238 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=path238.resolve(directory),resolved=path238.resolve(baseDir,concrete),rel=path238.relative(baseDir,resolved);if(rel.startsWith("..")||path238.isAbsolute(rel))return null}return v}function findBinaryInPath(binary){let candidates=process.platform==="win32"?[`${binary}.exe`,`${binary}.cmd`,`${binary}.bat`,binary]:[binary];for(let dir of(process.env.PATH??"").split(path238.delimiter)){if(!dir)continue;for(let name of candidates){let candidate2=path238.join(dir,name);if(existsSync121(candidate2))return candidate2}}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((resolve94)=>setTimeout(()=>resolve94("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=readdirSync33(dir,{withFileTypes:!0})}catch{return}for(let entry of entries){if(visited>=GREP_MAX_FILES)return;let fullPath=path238.join(dir,entry.name),relPath=path238.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(statSync50(fullPath).size>GREP_MAX_BYTES_PER_FILE)continue;let found=readFileSync93(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(path238.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 changed2=await changedPaths(directory);if(changed2===null)return{result:"error",detail:`${label}: git unavailable or failed`};let target=path238.normalize(safe),isChanged=changed2.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_knowledge_receipt_ledger();init_skill_propagation_gate();var _internals179={validateAndCommitTerminalBatch,recordKnowledgeEvent,runDirectivePredicate,escalateViolatedEntries},VERDICT_PATTERN=/\b(VERIFIED|VIOLATED|N\/A)\s*:\s*([^:\s]{1,512})\s*:\s*([^:\s]{1,512})(?:\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(),traceId=decodeDirectiveCorrelationId(m[2]),entryId=decodeDirectiveCorrelationId(m[3]);if(!traceId||!entryId)continue;let evidence2=m[4]?.trim().slice(0,280),verdict=verb==="VERIFIED"?"verified":verb==="VIOLATED"?"violated":"n_a";out.push({trace_id:traceId,entry_id:entryId,verdict,evidence:evidence2})}return out}function verdictToEventType(v){return v==="verified"?"applied":v==="violated"?"violated":"n_a"}function pairKey2(traceId,entryId){return JSON.stringify([traceId,entryId])}async function reconcileReviewerVerdicts(params){let result={emitted:[],omittedCriticals:[],uncertainties:[]},verifyByPair=new Map(params.directivesToVerify.map((d)=>[pairKey2(d.trace_id,d.entry_id),d]));if(verifyByPair.size===0)return result;let verdictsByPair=new Map;for(let verdict of parseReviewerDirectiveCompliance(params.transcript)){let key=pairKey2(verdict.trace_id,verdict.entry_id);if(!verifyByPair.has(key))continue;let existing=verdictsByPair.get(key)??[];existing.push(verdict),verdictsByPair.set(key,existing)}let pending=[];for(let[key,directive]of verifyByPair){let matching=verdictsByPair.get(key)??[];if(matching.length>1){result.uncertainties.push({trace_id:directive.trace_id,entry_id:directive.entry_id,code:"duplicate_verdict",uncertainty:"Reviewer emitted more than one verdict for the exact pair"});continue}if(matching.length===0){if(directive.priority!=="critical")continue;result.omittedCriticals.push({trace_id:directive.trace_id,entry_id:directive.entry_id}),pending.push({directive,type:"violated",reason:"reviewer_omitted"});continue}let verdict=matching[0];if(verdict.verdict==="verified"&&!verdict.evidence?.trim()){if(result.uncertainties.push({trace_id:directive.trace_id,entry_id:directive.entry_id,code:"reviewer_missing_evidence",uncertainty:"VERIFIED requires nonempty evidence"}),directive.priority==="critical")result.omittedCriticals.push({trace_id:directive.trace_id,entry_id:directive.entry_id}),pending.push({directive,type:"violated",reason:"reviewer_missing_evidence"});continue}let item={directive,type:verdictToEventType(verdict.verdict),reason:verdict.evidence};if(verdict.verdict==="violated"&&directive.verification_predicate)try{let outcome=await _internals179.runDirectivePredicate(directive.verification_predicate,params.directory);item.predicate_check={predicate:directive.verification_predicate,result:outcome.result,detail:outcome.detail}}catch(error93){item.predicate_check={predicate:directive.verification_predicate,result:"error",detail:error93 instanceof Error?error93.message:String(error93)}}pending.push(item)}let groups=new Map;for(let item of pending){let groupKey=JSON.stringify([item.directive.trace_id,item.directive.session_id,item.directive.cohort_id,item.directive.source_link_id,item.directive.prior_terminal_outcome,item.directive.prior_terminal_event_id]),group=groups.get(groupKey)??[];group.push(item),groups.set(groupKey,group)}let violatedIds=new Set,agent=params.agent??"reviewer";for(let group of groups.values()){let first=group[0].directive,remediationAuthorization=first.prior_terminal_outcome==="violated"&&first.prior_terminal_event_id&&group.some((item)=>item.type!=="violated")?{actor:"reviewer-remediation",reason:"reviewer_verified_remediation",expected_event_id:first.prior_terminal_event_id,expected_outcome:first.prior_terminal_outcome}:void 0,committedEntries;try{let committed=await _internals179.validateAndCommitTerminalBatch(params.directory,{trace_id:first.trace_id,session_id:first.session_id,cohort_id:first.cohort_id,source_link_id:first.source_link_id,authorization:remediationAuthorization,items:group.map((item)=>({entry_id:item.directive.entry_id,outcome:item.type,source:"reviewer",reason:item.reason}))});if(!committed.ok){for(let item of group)result.uncertainties.push({trace_id:item.directive.trace_id,entry_id:item.directive.entry_id,code:committed.code,uncertainty:committed.detail});continue}committedEntries=new Set(committed.accepted.map((terminal)=>terminal.entry_id));for(let rejected of committed.rejected)result.uncertainties.push({trace_id:first.trace_id,entry_id:rejected.entry_id||void 0,code:rejected.reason,uncertainty:"Authoritative ledger rejected reviewer terminal"})}catch(error93){for(let item of group)result.uncertainties.push({trace_id:item.directive.trace_id,entry_id:item.directive.entry_id,code:"ledger_exception",uncertainty:error93 instanceof Error?error93.message:String(error93)});continue}for(let item of group){if(!committedEntries.has(item.directive.entry_id))continue;try{if(await _internals179.recordKnowledgeEvent(params.directory,{type:item.type,trace_id:item.directive.trace_id,knowledge_id:item.directive.entry_id,session_id:item.directive.session_id,task_id:params.taskId,phase:params.phase,agent,source:"reviewer",reason:item.reason,predicate_check:item.predicate_check}),result.emitted.push({trace_id:item.directive.trace_id,entry_id:item.directive.entry_id,id:item.directive.entry_id,type:item.type,source:"reviewer"}),item.type==="violated")violatedIds.add(item.directive.entry_id)}catch(error93){result.uncertainties.push({trace_id:item.directive.trace_id,entry_id:item.directive.entry_id,code:"diagnostic_event_failed",uncertainty:error93 instanceof Error?error93.message:String(error93)})}}}if(violatedIds.size>0)try{await _internals179.escalateViolatedEntries(params.directory,[...violatedIds])}catch(error93){result.uncertainties.push({trace_id:"",code:"escalation_failed",uncertainty:error93 instanceof Error?error93.message:String(error93)})}return result}function isTaskTool7(tool3){return tool3==="Task"||tool3==="task"}async function collectReviewerVerdictsAfter(directory,input,output){if(!isTaskTool7(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_path_identity();init_scope_binding();init_scope_persistence();init_scope_resolution_diagnostic();init_state2();init_normalize_tool_name();init_pr_workflow_gate();init_write_target_resolver();import*as path239 from"node:path";var WRITE_TOOLS2=new Set(WRITE_TOOL_NAMES);function createScopeGuardHook(config3,fallbackDirectory,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 directory=_internals180.resolveSessionWorkspaceDirectory(sessionId,fallbackDirectory),targets=_internals180.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=_internals180.resolveTaskId(session),seamBinding=taskId&&_internals180.resolveAuthorizedScopeBinding!==resolveAuthorizedScopeBinding?_internals180.resolveAuthorizedScopeBinding({directory,taskId,activeSessionId:sessionId}):null,resolution=seamBinding?{status:"found",binding:seamBinding}:taskId?_internals180.resolveAuthorizedScopeBindingDetailed({directory,taskId,activeSessionId:sessionId}):_internals180.resolveAuthorizedScopeBindingForSessionDetailed({directory,activeSessionId:sessionId}),binding=resolution.status==="found"?resolution.binding:null;if(!binding){if(binding=_internals180.getAuthorizedPrFeedbackScopeBinding({directory,activeSessionId:sessionId,taskId:taskId??void 0})??_internals180.resolveAuthorizedPrFeedbackScopeBindingFromDisk({directory,activeSessionId:sessionId,taskId:taskId??void 0}),binding&&!await _internals180.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){let durableDiagnostic=formatScopeResolutionDiagnostic({resolution,taskId,sessionId});if(durableDiagnostic)denyWithArchitectAdvisory(durableDiagnostic,session,injectAdvisory,swarmState);let mismatch=_internals180.describeScopeWorkspaceMismatch({directory,activeSessionId:sessionId,taskId});if(mismatch)denyWithArchitectAdvisory(`${mismatch} ${agentName} cannot invoke ${toolName} for task ${taskId??"unknown"}. ACTION[architect]: redeclare the exact scope against the reported active lane root with replace_existing=true, then dispatch a new Task call.`,session,injectAdvisory,swarmState);denyWithArchitectAdvisory(`SCOPE_NOT_DECLARED: ${agentName} cannot invoke ${toolName} without a validated scope for task ${taskId??"unknown"}. ACTION[architect]: call declare_scope with the exact workspace-relative paths and replace_existing=true, then dispatch a new Task call.`,session,injectAdvisory,swarmState)}for(let rawPath of targets.paths){let filePath=sanitizePath(rawPath),absoluteTarget=path239.resolve(directory,filePath);if(!isPathIdentityWithin(absoluteTarget,directory)){let fallbackRelative=isPathIdentityWithin(absoluteTarget,fallbackDirectory)?path239.relative(fallbackDirectory,absoluteTarget).replace(/\\/g,"/"):null,safeRetry=fallbackRelative?`detected workspace-relative path ${JSON.stringify(sanitizeDiagnosticText(fallbackRelative))}; retry exactly that relative path under the active root`:"no safe workspace-relative retry was detected; stop and correct the command or lane root";denyWithArchitectAdvisory(`SCOPE_ROOT_ESCAPE: attempted target ${JSON.stringify(sanitizeDiagnosticText(filePath))} leaves active root ${JSON.stringify(sanitizeDiagnosticText(directory))}; ${safeRetry}. ACTION[architect]: verify the active lane root, redeclare only the exact relative path with replace_existing=true, and dispatch a new Task call.`,session,injectAdvisory,swarmState)}if(!isFileInScope(filePath,declaredScope,directory))reportScopeViolation(agentName,filePath,taskId,session,injectAdvisory,swarmState,declaredScope)}}}}function isFileInScope(filePath,scopeEntries,directory){let dir=directory??process.cwd(),resolvedFile=path239.resolve(dir,filePath);return scopeEntries.filter((scope)=>scope.length>0).some((scope)=>{let resolvedScope=path239.resolve(dir,scope);return isPathIdentityWithin(resolvedFile,resolvedScope)})}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 _internals180={sanitizePath,resolveWriteTargets:resolveWriteTargets2,resolveAuthorizedScopeBindingDetailed,resolveAuthorizedScopeBindingForSessionDetailed,resolveAuthorizedScopeBinding,resolveAuthorizedScopeBindingForSession,getAuthorizedPrFeedbackScopeBinding,resolveAuthorizedPrFeedbackScopeBindingFromDisk,validatePrFeedbackScopeBinding,resolveSessionWorkspaceDirectory,describeScopeWorkspaceMismatch,resolveTaskId:(session)=>session?.currentTaskId??null};function denyWithArchitectAdvisory(message,session,injectAdvisory,state){if(session)session.lastScopeViolation=message,session.scopeViolationDetected=!0;if(injectAdvisory)for(let[architectSessionId,architectSession]of state.agentSessions){let role=state.activeAgent.get(architectSessionId)??architectSession.agentName;if(stripKnownSwarmPrefix(role)!==ORCHESTRATOR_NAME)continue;try{injectAdvisory(architectSessionId,`[SCOPE GUARD] ${message}`)}catch{}break}throw Error(message)}function reportScopeViolation(agentName,filePath,taskId,session,injectAdvisory,state,scopeEntries){let taskLabel2=taskId??"unknown",safeAgentName=sanitizeDiagnosticText(agentName,128),safeFilePath=sanitizeDiagnosticText(filePath,256),safeScope=scopeEntries.slice(0,3).map((entry)=>sanitizeDiagnosticText(entry,128)).join(", "),violationMessage=`SCOPE_VIOLATION: SCOPE VIOLATION: ${safeAgentName} attempted to modify '${safeFilePath}' which is not in declared scope for task ${taskLabel2}. Declared scope: [${safeScope}${scopeEntries.length>3?"...":""}]. Coder: correct a mistaken target; otherwise stop and ask the architect to expand declare_scope and dispatch a new Task call.`;denyWithArchitectAdvisory(violationMessage,session,injectAdvisory,state)}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(`
6318
6325
  `);try{injectAdvisory(sessionId,advisory)}catch{}}}}init_skill_propagation_gate();init_skill_scoring();init_skill_usage_log();import*as path240 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
6319
6326
 
6320
6327
  ${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=path240.basename(path240.dirname(s.skillPath));return desc=desc.replace(/,/g,";"),`file:${s.skillPath} (-- ${desc})`}).join(", ")}`}
@@ -6328,7 +6335,7 @@ ${findingText}
6328
6335
  Review before proceeding.`;injectSystemMessage(input.sessionID,message)}}}init_bun_compat();init_utils2();import*as fs135 from"node:fs";function recordSteeringConsumed(directory,directiveId){try{let eventsPath=validateSwarmPath(directory,"events.jsonl"),event={type:"steering-consumed",directiveId,timestamp:new Date().toISOString()};fs135.appendFileSync(eventsPath,`${JSON.stringify(event)}
6329
6336
  `,"utf-8")}catch{}}function createSteeringConsumedHook(directory){return safeHook(async()=>{try{let eventsPath=validateSwarmPath(directory,"events.jsonl"),content=await bunFile(eventsPath).text();if(!content.trim())return;let lines=content.trim().split(`
6330
6337
  `),directiveIds=new Set,consumedIds=new Set;for(let line of lines){if(!line.trim())continue;try{let parsed=JSON.parse(line);if(parsed.type==="steering-directive"&&parsed.directiveId)directiveIds.add(parsed.directiveId);else if(parsed.type==="steering-consumed"&&parsed.directiveId)consumedIds.add(parsed.directiveId)}catch{}}for(let directiveId of directiveIds)if(!consumedIds.has(directiveId))recordSteeringConsumed(directory,directiveId)}catch{}})}init_trajectory_logger();init_p_limit();init_knowledge_curator();init_knowledge_reinforcement();init_knowledge_store();init_knowledge_validator();init_micro_reflector();init_logger();init_candidate_queue();init_provenance();function timeoutSignal(ms){let controller=new AbortController,timer=setTimeout(()=>{controller.abort(new DOMException("The operation timed out.","TimeoutError"))},ms);return{signal:controller.signal,clear:()=>clearTimeout(timer)}}var SCREENING_TOKEN_ESTIMATE=400,SCREENING_PROMPT_CAP=1200;function unionSourceKnowledgeIds(entry,ids){let next=entry.source_knowledge_ids;for(let id of ids)next=unionInsightMarker(next,id);entry.source_knowledge_ids=next??[]}function findActiveEntryWithMarker(entries,marker){return entries.find((entry)=>isActiveSwarmKnowledgeEntry(entry)&&(entry.source_knowledge_ids??[]).includes(marker))}function buildScreeningPrompt(candidate2){return["A subagent proposed this durable procedural lesson for the shared knowledge store.","Answer with exactly one word: ADMIT or REJECT.","REJECT when the lesson is task-specific trivia, a transient environment failure, or not generalizable.","",`LESSON: ${candidate2.lesson}`,`CATEGORY: ${candidate2.category}`,`SCOPE: agents=${(candidate2.applies_to_agents??[]).join(",")} tools=${(candidate2.applies_to_tools??[]).join(",")}`].join(`
6331
- `).slice(0,SCREENING_PROMPT_CAP)}async function screenCandidate(candidate2,deps){let perCandidateMs=deps.llmTimeoutMs??0;if(!deps.llmDelegate||perCandidateMs<=0||!deps.sessionID)return!0;if(!deps.llmBudget)return!0;let remainingMs=deps.remainingBudgetMs?.()??Number.POSITIVE_INFINITY,timeoutMs=Math.min(perCandidateMs,Math.max(0,remainingMs));if(timeoutMs<=0)return!0;if(!reserveLlmBudget(deps.sessionID,SCREENING_TOKEN_ESTIMATE,deps.llmBudget))return!0;let{signal:signal2,clear}=timeoutSignal(timeoutMs);try{let response=await deps.llmDelegate("",buildScreeningPrompt(candidate2),signal2);return!/\bREJECT\b/i.test(response??"")}finally{clear()}}async function admitCandidate(directory,candidate2,deps){let candidateId2=resolveInsightCandidateId(candidate2),marker=insightAdmissionMarker(candidateId2),now2=deps.now??(()=>Date.now());if(!validateActionableFields({applies_to_agents:candidate2.applies_to_agents,applies_to_tools:candidate2.applies_to_tools,required_actions:candidate2.required_actions,forbidden_actions:candidate2.forbidden_actions,verification_checks:candidate2.verification_checks,triggers:candidate2.triggers,directive_priority:candidate2.directive_priority}).valid)return{outcome:"rejected",reason:"invalid_shape",marker};let actionability=validateActionability({applies_to_agents:candidate2.applies_to_agents,applies_to_tools:candidate2.applies_to_tools,required_actions:candidate2.required_actions,forbidden_actions:candidate2.forbidden_actions,verification_checks:candidate2.verification_checks});if(!actionability.actionable)return{outcome:"rejected",reason:actionability.reason??"unactionable",marker};if(!await screenCandidate(candidate2,deps))return{outcome:"rejected",reason:"screened_out",marker};let provenance=stampLearningProvenance({mechanism:candidate2.source?.kind==="prm_pattern"?"prm_pattern":"micro_reflection",sourceKnowledgeIds:[marker],sourceTaskIds:candidate2.source?.task_id?[candidate2.source.task_id]:[],sourceEvidenceRefs:candidate2.source_refs??[]},{sessionId:deps.sessionID,agentRole:candidate2.source?.agent,producedAt:new Date(now2()).toISOString()}),knowledgePath=(deps.resolveKnowledgePath??resolveSwarmKnowledgePath)(directory),entry=insightCandidateToEntry(candidate2,deps.projectName,deps.phaseNumber,deps.knowledgeConfig);if(unionSourceKnowledgeIds(entry,provenance.sourceKnowledgeIds),provenance.sourceEvidenceRefs.length>0){let refs=new Set([...entry.source_refs??[],...provenance.sourceEvidenceRefs]);entry.source_refs=[...refs]}let outcome="rejected",reason="no_change",entryId;if(await transactKnowledge(knowledgePath,(current)=>{if(findActiveEntryWithMarker(current,marker))return outcome="rejected",reason="already_admitted",null;let duplicate=findActiveSwarmNearDuplicate(entry.lesson,current,deps.knowledgeConfig.dedup_threshold);if(duplicate){let result=reinforceSwarmKnowledgeEntry(duplicate,{phase_number:deps.phaseNumber,confirmed_at:new Date(now2()).toISOString(),project_name:deps.projectName});return unionSourceKnowledgeIds(duplicate,[marker]),outcome="reinforced",reason=result.reason,entryId=duplicate.id,current}return current.push(entry),outcome="admitted",reason=void 0,entryId=entry.id,current}),outcome!=="rejected")deps.onKnowledgeChanged?.();return{outcome,reason,entryId,marker,provenance}}async function realtimeAdmissionAfter(directory,input,config3,resolveDeps){if(!isTaskTool(input.tool))return;if(!config3?.enabled)return;let sessionID=typeof input.sessionID==="string"&&input.sessionID.length>0?input.sessionID:void 0;if(!sessionID)return;if(getQueueDepth(sessionID)===0)return;let deps=await resolveDeps();return drainSessionQueue(directory,sessionID,config3,deps)}function emptySummary(){return{attempted:0,admitted:0,reinforced:0,rejected:0,deferred:0,failed:0,retries:0}}async function drainSessionQueue(directory,sessionID,config3,deps){let summary=emptySummary();if(!config3.enabled)return summary;let now2=deps.now??(()=>Date.now()),stats2=getQueueStats(sessionID);if(stats2.depth===0)return summary;let velocity=computeArrivalVelocity(stats2,now2()),size=computeDrainSize(stats2.depth,velocity,{minDrain:config3.min_drain,maxDrain:config3.max_drain,drainDepthFactor:config3.drain_depth_factor,drainVelocityFactor:config3.drain_velocity_factor});if(size<=0)return summary;let batch=takeDrainBatch(sessionID,size);if(batch.length===0)return summary;summary.attempted=batch.length;let startedAt=now2(),wallTimeMs=Math.max(0,Number(config3.max_drain_wall_time_ms)||0),deadline=wallTimeMs>0?startedAt+wallTimeMs:Number.POSITIVE_INFINITY,budgetExhausted=()=>now2()>=deadline,maxRetries=Math.max(0,Math.floor(Number(config3.max_retries_per_candidate)||0)),limit=pLimit(Math.max(1,Math.floor(Number(config3.max_concurrent_admissions)||1))),admissionDeps={...deps,sessionID,llmTimeoutMs:config3.max_llm_calls_per_session>0?deps.llmTimeoutMs??config3.per_candidate_llm_timeout_ms:0,llmBudget:deps.llmBudget??{maxLlmCallsPerSession:config3.max_llm_calls_per_session,maxTokensPerSession:config3.max_tokens_per_session},remainingBudgetMs:()=>deadline-now2()},deferOrAbandon=(item)=>{if(item.attempts>=MAX_CANDIDATE_DRAIN_ATTEMPTS){summary.failed++,warn(`[learning-admission] candidate abandoned after ${item.attempts} drain attempt(s) without completing`);return}requeueCandidate(sessionID,item,{maxQueueSize:config3.max_queue_size}),summary.deferred++};return await Promise.all(batch.map((item)=>limit(async()=>{if(budgetExhausted()){deferOrAbandon(item);return}for(let attempt=0;;attempt++)try{let result=await admitCandidate(directory,item.candidate,admissionDeps);if(result.outcome==="admitted")summary.admitted++;else if(result.outcome==="reinforced")summary.reinforced++;else summary.rejected++;return}catch(err){if(attempt>=maxRetries){warn(`[learning-admission] candidate failed after ${attempt+1} attempt(s): ${isAbortError(err)?"cancelled":err instanceof Error?err.message:String(err)}`),deferOrAbandon(item);return}if(summary.retries++,recordRetry(sessionID),budgetExhausted()){deferOrAbandon(item);return}}}))),summary}init_memory();init_observability();init_manager();init_prm();init_ephemeral_agent_dispatcher();function createReviewModelDispatcher(client){return{dispatch:(request)=>dispatchEphemeralAgent({client,directory:request.directory,parentSessionId:request.parentSessionId,agentName:request.agentName,model:request.model,system:request.system,prompt:request.prompt,readOnlyTools:DEFAULT_READ_ONLY_TOOLS,title:request.title,timeoutMs:request.timeoutMs&&request.timeoutMs>0?request.timeoutMs:DEFAULT_EPHEMERAL_TIMEOUT_MS,promptByteLimit:request.promptByteLimit,responseByteLimit:request.responseByteLimit,abortSignal:request.abortSignal})}}init_finding_validator();init_runtime2();init_compaction_service();init_config_doctor();init_cost_accounting();init_version_check();init_state3();init_utils2();init_state2();init_bun_compat();init_logger();import{renameSync as renameSync38}from"node:fs";var TRANSIENT_SESSION_FIELDS=[{name:"revisionLimitHit",resetValue:!1},{name:"coderRevisions",resetValue:0},{name:"selfFixAttempted",resetValue:!1},{name:"lastGateFailure",resetValue:null},{name:"architectWriteCount",resetValue:0},{name:"selfCodingWarnedAtCount",resetValue:0},{name:"pendingAdvisoryMessages",resetValue:[]},{name:"model_fallback_index",resetValue:0},{name:"modelFallbackExhausted",resetValue:!1},{name:"scopeViolationDetected",resetValue:!1},{name:"delegationActive",resetValue:!1},{name:"autoProceedOverride",resetValue:void 0},{name:"autoProceedNudgeDone",resetValue:void 0}],VALID_TASK_WORKFLOW_STATES=["idle","coder_delegated","pre_check_passed","reviewer_run","tests_run","rework_required","complete","blocked","closed"];function deserializeTaskWorkflowStates(raw){let m=new Map;if(!raw||typeof raw!=="object")return m;for(let[taskId,stateVal]of Object.entries(raw))if(VALID_TASK_WORKFLOW_STATES.includes(stateVal))m.set(taskId,stateVal);return m}function deserializeModifiedFilesByTask(raw){let entries=new Map;if(!raw||typeof raw!=="object")return entries;let serializedEntries=Object.entries(raw);if(serializedEntries.length>MAX_TRACKED_TASK_FILE_ATTRIBUTIONS)return entries;for(let[taskId,files]of serializedEntries){if(!taskId.trim()||!Array.isArray(files))continue;let validFiles=files.filter((file3)=>typeof file3==="string"&&file3.length>0);entries.set(taskId,[...new Set(validFiles)])}return entries}function deserializeAgentSession(s){let lastGateFailure=s.lastGateFailure?{tool:s.lastGateFailure.tool,taskId:s.lastGateFailure.taskId,timestamp:s.lastGateFailure.timestamp,...typeof s.lastGateFailure.code==="string"&&/^[A-Z][A-Z0-9_]{0,63}$/.test(s.lastGateFailure.code)&&{code:s.lastGateFailure.code}}:null,taskWorkflowStates=deserializeTaskWorkflowStates(s.taskWorkflowStates),modifiedFilesByTask=deserializeModifiedFilesByTask(s.modifiedFilesByTask),gateLog=new Map;if(s.gateLog)for(let[taskId,gates]of Object.entries(s.gateLog))gateLog.set(taskId,new Set(gates??[]));let reviewerCallCount=new Map;if(s.reviewerCallCount)for(let[phase,count]of Object.entries(s.reviewerCallCount)){let numPhase=Number(phase);if(Number.isFinite(numPhase))reviewerCallCount.set(numPhase,count)}let partialGateWarningsIssuedForTask=new Set(s.partialGateWarningsIssuedForTask??[]),completionGateWarnedForTask=new Set(s.completionGateWarnedForTask??[]),catastrophicPhaseWarnings=new Set(s.catastrophicPhaseWarnings??[]),phaseAgentsDispatched=new Set(s.phaseAgentsDispatched??[]),lastCompletedPhaseAgentsDispatched=new Set(s.lastCompletedPhaseAgentsDispatched??[]),stageBCompletion=new Map;if(s.stageBCompletion)for(let[taskId,agents]of Object.entries(s.stageBCompletion))stageBCompletion.set(taskId,new Set(agents));let windows={};for(let[key,win]of Object.entries(s.windows??{})){if(!win||typeof win!=="object")continue;windows[key]={...win,transientRetryCount:"transientRetryCount"in win?win.transientRetryCount??0:0}}return{agentName:s.agentName,lastToolCallTime:s.lastToolCallTime,lastAgentEventTime:s.lastAgentEventTime,delegationActive:s.delegationActive,activeInvocationId:s.activeInvocationId,lastInvocationIdByAgent:s.lastInvocationIdByAgent??{},windows,lastCompactionHint:s.lastCompactionHint??0,architectWriteCount:s.architectWriteCount??0,lastCoderDelegationTaskId:s.lastCoderDelegationTaskId??null,currentTaskId:s.currentTaskId??null,turboMode:s.turboMode??!1,turboStrategy:s.turboStrategy==="lean"||s.turboStrategy==="standard"?s.turboStrategy:void 0,leanTurboActive:s.leanTurboActive??!1,leanTurboCurrentPhase:typeof s.leanTurboCurrentPhase==="number"?s.leanTurboCurrentPhase:void 0,epicModeActive:s.epicModeActive??!1,gateLog,reviewerCallCount,lastGateFailure,partialGateWarningsIssuedForTask,completionGateWarnedForTask,selfFixAttempted:s.selfFixAttempted??!1,selfCodingWarnedAtCount:s.selfCodingWarnedAtCount??0,catastrophicPhaseWarnings,lastPhaseCompleteTimestamp:s.lastPhaseCompleteTimestamp??0,lastPhaseCompletePhase:s.lastPhaseCompletePhase??0,phaseAgentsDispatched,lastCompletedPhaseAgentsDispatched,qaSkipCount:s.qaSkipCount??0,qaSkipTaskIds:s.qaSkipTaskIds??[],taskWorkflowStates,lastGateOutcome:null,declaredCoderScope:null,lastScopeViolation:null,scopeViolationDetected:s.scopeViolationDetected,modifiedFilesByTask,modifiedFilesThisCoderTask:s.currentTaskId&&s.currentTaskId.trim()!==""&&modifiedFilesByTask.has(s.currentTaskId)?[...modifiedFilesByTask.get(s.currentTaskId)??[]]:[],loopDetectionWindow:[],pendingAdvisoryMessages:s.pendingAdvisoryMessages??[],model_fallback_index:s.model_fallback_index??0,modelFallbackExhausted:s.modelFallbackExhausted??!1,coderRevisions:s.coderRevisions??0,revisionLimitHit:s.revisionLimitHit??!1,fullAutoMode:s.fullAutoMode??!1,fullAutoInteractionCount:s.fullAutoInteractionCount??0,fullAutoDeadlockCount:s.fullAutoDeadlockCount??0,fullAutoLastQuestionHash:s.fullAutoLastQuestionHash??null,maxConcurrencyOverride:typeof s.maxConcurrencyOverride==="number"?Math.min(64,Math.max(1,s.maxConcurrencyOverride)):void 0,autoProceedOverride:s.autoProceedOverride,autoProceedNudgeDone:s.autoProceedNudgeDone,prmPatternCounts:new Map,prmEscalationLevel:0,prmLastPatternDetected:null,prmTrajectoryStep:0,prmHardStopPending:!1,prmHardStopInjectPending:!1,prmInjectedAdvisoryKeys:new Set,prmStruckEpisodes:new Map,prmLadderCounts:new Map,executionEpisodeArmed:!1,sessionRehydratedAt:s.sessionRehydratedAt??0,stageBCompletion,prSubscriptions:new Map,cachedCohortId:typeof s.cachedCohortId==="string"?s.cachedCohortId:void 0,lastObservedModel:typeof s.lastObservedModel==="string"?s.lastObservedModel:void 0,lastObservedProviderID:typeof s.lastObservedProviderID==="string"?s.lastObservedProviderID:void 0}}async function readSnapshot(directory){try{let resolvedPath=validateSwarmPath(directory,"session/state.json"),content=await bunFile(resolvedPath).text();if(!content.trim())return null;let parsed=JSON.parse(content,(key,value)=>{if(key==="__proto__"||key==="constructor")return;return value});if(parsed.version!==1&&parsed.version!==2&&parsed.version!==3){try{let quarantinePath=validateSwarmPath(directory,"session/state.json.quarantine");renameSync38(resolvedPath,quarantinePath)}catch{}return null}return parsed}catch{return null}}async function rehydrateState(snapshot,directory){if(swarmState.pendingRehydrations.size>0)await Promise.allSettled([...swarmState.pendingRehydrations]);if(swarmState.toolAggregates.clear(),swarmState.activeAgent.clear(),swarmState.delegationChains.clear(),swarmState.agentSessions.clear(),snapshot.toolAggregates)for(let[key,value]of Object.entries(snapshot.toolAggregates))swarmState.toolAggregates.set(key,value);if(snapshot.activeAgent)for(let[key,value]of Object.entries(snapshot.activeAgent))swarmState.activeAgent.set(key,value);if(snapshot.delegationChains)for(let[key,value]of Object.entries(snapshot.delegationChains))swarmState.delegationChains.set(key,value);let now2=Date.now();if(snapshot.agentSessions)for(let[sessionId,serializedSession]of Object.entries(snapshot.agentSessions)){if(!serializedSession||typeof serializedSession!=="object"||typeof serializedSession.agentName!=="string"||typeof serializedSession.lastToolCallTime!=="number"||typeof serializedSession.delegationActive!=="boolean"){log(`[snapshot-reader] Skipping malformed session ${sessionId}: missing required fields (agentName, lastToolCallTime, delegationActive)`);continue}let session=deserializeAgentSession(serializedSession);if(session.taskWorkflowStates=new Map,session.taskWorkflowCache=new Map,session.stageBCompletion=new Map,session.lastToolCallTime=now2,session.lastAgentEventTime=now2,session.sessionRehydratedAt=now2,session.windows)for(let window2 of Object.values(session.windows))window2.startedAtMs=now2,window2.lastSuccessTimeMs=now2,window2.hardLimitHit=!1,window2.toolCalls=0,window2.consecutiveErrors=0,window2.recentToolCalls=[],window2.warningIssued=!1,window2.warningReason="";for(let field of TRANSIENT_SESSION_FIELDS)session[field.name]=field.resetValue;if(session.fullAutoMode){let runStillActive=!1;if(directory)try{runStillActive=loadFullAutoRunState(directory,sessionId)?.status==="running"}catch{runStillActive=!1}if(!runStillActive)session.fullAutoMode=!1}swarmState.agentSessions.set(sessionId,session)}}async function loadSnapshot(directory){try{await buildRehydrationCache(directory);let snapshot=await readSnapshot(directory);if(snapshot!==null){await rehydrateState(snapshot,directory);for(let session of swarmState.agentSessions.values())applyRehydrationCache(session)}}catch{}}init_snapshot_writer();init_state2();init_telemetry();init_zod();init_config();init_agents2();init_schema();init_ephemeral_agent_dispatcher();import*as fs137 from"node:fs/promises";import*as path243 from"node:path";init_runtime2();init_state2();init_telemetry();init_provider_error_classification();init_swarm_artifact_cache();init_bun_compat();init_swarm_artifact_cache();import{rmSync as rmSync17}from"node:fs";import*as fs136 from"node:fs/promises";import*as path242 from"node:path";function leanTurboEvidenceDir(directory,phase){return path242.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=path242.resolve(path242.join(expectedDir,`${laneId}.json`)),resolvedDir=path242.resolve(expectedDir);if(!resolvedPath.startsWith(resolvedDir+path242.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=path242.dirname(filePath);await fs136.mkdir(dir,{recursive:!0});let tempPath=`${filePath}.tmp.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}`;try{await bunWrite(tempPath,content),await fs136.rename(tempPath,filePath),invalidateCachedArtifact(filePath)}catch(error93){try{rmSync17(tempPath,{force:!0})}catch{}throw error93}}function phaseEvidencePath(directory,phase){return path242.join(leanTurboEvidenceDir(directory,phase),"lean-turbo-phase.json")}async function writeLaneEvidence(directory,phase,evidence2){let targetPath=laneEvidencePath(directory,phase,evidence2.laneId);await atomicWriteJson(targetPath,evidence2)}async function writePhaseEvidence(directory,evidence2){let targetPath=phaseEvidencePath(directory,evidence2.phase);await atomicWriteJson(targetPath,evidence2)}async function readPhaseEvidence(directory,phase){let targetPath=phaseEvidencePath(directory,phase),content;try{content=await fs136.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 fs136.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=path242.join(evidenceDir,entry),content;try{content=await fs136.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:DEFAULT_EPHEMERAL_TIMEOUT_MS,requireDiffSummary:!1};function resolveDefaultReviewerAgent(generatedAgentNames,activeAgentName){return resolveAgentForActiveSwarm(generatedAgentNames,"reviewer",activeAgentName)}function resolveLegacyReviewerModelConfig(agentName,config3){if(config3?.dispatcher||config3?.agentModelRegistry)return;let agentBaseName=stripKnownSwarmPrefix(agentName),swarmId=agentBaseName!==agentName?agentName.slice(0,agentName.length-agentBaseName.length-1):void 0;return{agentBaseName,swarmAgents:getSwarmAgents(swarmId)}}async function compileReviewPackage(directory,phase,sessionID,requireDiffSummary){let lanes=await listLaneEvidence(directory,phase),persisted=_internals181.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 parseReviewerVerdict(responseText){let verdictMatch=responseText.toUpperCase().match(/VERDICT\s*:\s*(APPROVED|NEEDS_REVISION|REJECTED)/);if(!verdictMatch)return null;let verdict=verdictMatch[1],lines=responseText.split(`
6338
+ `).slice(0,SCREENING_PROMPT_CAP)}async function screenCandidate(candidate2,deps){let perCandidateMs=deps.llmTimeoutMs??0;if(!deps.llmDelegate||perCandidateMs<=0||!deps.sessionID)return!0;if(!deps.llmBudget)return!0;let remainingMs=deps.remainingBudgetMs?.()??Number.POSITIVE_INFINITY,timeoutMs=Math.min(perCandidateMs,Math.max(0,remainingMs));if(timeoutMs<=0)return!0;if(!reserveLlmBudget(deps.sessionID,SCREENING_TOKEN_ESTIMATE,deps.llmBudget))return!0;let{signal:signal2,clear}=timeoutSignal(timeoutMs);try{let response=await deps.llmDelegate("",buildScreeningPrompt(candidate2),signal2);return!/\bREJECT\b/i.test(response??"")}finally{clear()}}async function admitCandidate(directory,candidate2,deps){let candidateId2=resolveInsightCandidateId(candidate2),marker=insightAdmissionMarker(candidateId2),now2=deps.now??(()=>Date.now());if(!validateActionableFields({applies_to_agents:candidate2.applies_to_agents,applies_to_tools:candidate2.applies_to_tools,required_actions:candidate2.required_actions,forbidden_actions:candidate2.forbidden_actions,verification_checks:candidate2.verification_checks,triggers:candidate2.triggers,directive_priority:candidate2.directive_priority}).valid)return{outcome:"rejected",reason:"invalid_shape",marker};let actionability=validateActionability({applies_to_agents:candidate2.applies_to_agents,applies_to_tools:candidate2.applies_to_tools,required_actions:candidate2.required_actions,forbidden_actions:candidate2.forbidden_actions,verification_checks:candidate2.verification_checks});if(!actionability.actionable)return{outcome:"rejected",reason:actionability.reason??"unactionable",marker};if(!await screenCandidate(candidate2,deps))return{outcome:"rejected",reason:"screened_out",marker};let provenance=stampLearningProvenance({mechanism:candidate2.source?.kind==="prm_pattern"?"prm_pattern":"micro_reflection",sourceKnowledgeIds:[marker],sourceTaskIds:candidate2.source?.task_id?[candidate2.source.task_id]:[],sourceEvidenceRefs:candidate2.source_refs??[]},{sessionId:deps.sessionID,agentRole:candidate2.source?.agent,producedAt:new Date(now2()).toISOString()}),knowledgePath=(deps.resolveKnowledgePath??resolveSwarmKnowledgePath)(directory),entry=insightCandidateToEntry(candidate2,deps.projectName,deps.phaseNumber,deps.knowledgeConfig);if(unionSourceKnowledgeIds(entry,provenance.sourceKnowledgeIds),provenance.sourceEvidenceRefs.length>0){let refs=new Set([...entry.source_refs??[],...provenance.sourceEvidenceRefs]);entry.source_refs=[...refs]}let outcome="rejected",reason="no_change",entryId;if(await transactKnowledge(knowledgePath,(current)=>{if(findActiveEntryWithMarker(current,marker))return outcome="rejected",reason="already_admitted",null;let duplicate=findActiveSwarmNearDuplicate(entry.lesson,current,deps.knowledgeConfig.dedup_threshold);if(duplicate){let result=reinforceSwarmKnowledgeEntry(duplicate,{phase_number:deps.phaseNumber,confirmed_at:new Date(now2()).toISOString(),project_name:deps.projectName});return unionSourceKnowledgeIds(duplicate,[marker]),outcome="reinforced",reason=result.reason,entryId=duplicate.id,current}return current.push(entry),outcome="admitted",reason=void 0,entryId=entry.id,current}),outcome!=="rejected")deps.onKnowledgeChanged?.();return{outcome,reason,entryId,marker,provenance}}async function realtimeAdmissionAfter(directory,input,config3,resolveDeps){if(!isTaskTool(input.tool))return;if(!config3?.enabled)return;let sessionID=typeof input.sessionID==="string"&&input.sessionID.length>0?input.sessionID:void 0;if(!sessionID)return;if(getQueueDepth(sessionID)===0)return;let deps=await resolveDeps();return drainSessionQueue(directory,sessionID,config3,deps)}function emptySummary(){return{attempted:0,admitted:0,reinforced:0,rejected:0,deferred:0,failed:0,retries:0}}async function drainSessionQueue(directory,sessionID,config3,deps){let summary=emptySummary();if(!config3.enabled)return summary;let now2=deps.now??(()=>Date.now()),stats2=getQueueStats(sessionID);if(stats2.depth===0)return summary;let velocity=computeArrivalVelocity(stats2,now2()),size=computeDrainSize(stats2.depth,velocity,{minDrain:config3.min_drain,maxDrain:config3.max_drain,drainDepthFactor:config3.drain_depth_factor,drainVelocityFactor:config3.drain_velocity_factor});if(size<=0)return summary;let batch=takeDrainBatch(sessionID,size);if(batch.length===0)return summary;summary.attempted=batch.length;let startedAt=now2(),wallTimeMs=Math.max(0,Number(config3.max_drain_wall_time_ms)||0),deadline=wallTimeMs>0?startedAt+wallTimeMs:Number.POSITIVE_INFINITY,budgetExhausted=()=>now2()>=deadline,maxRetries=Math.max(0,Math.floor(Number(config3.max_retries_per_candidate)||0)),limit=pLimit(Math.max(1,Math.floor(Number(config3.max_concurrent_admissions)||1))),admissionDeps={...deps,sessionID,llmTimeoutMs:config3.max_llm_calls_per_session>0?deps.llmTimeoutMs??config3.per_candidate_llm_timeout_ms:0,llmBudget:deps.llmBudget??{maxLlmCallsPerSession:config3.max_llm_calls_per_session,maxTokensPerSession:config3.max_tokens_per_session},remainingBudgetMs:()=>deadline-now2()},deferOrAbandon=(item)=>{if(item.attempts>=MAX_CANDIDATE_DRAIN_ATTEMPTS){summary.failed++,warn(`[learning-admission] candidate abandoned after ${item.attempts} drain attempt(s) without completing`);return}requeueCandidate(sessionID,item,{maxQueueSize:config3.max_queue_size}),summary.deferred++};return await Promise.all(batch.map((item)=>limit(async()=>{if(budgetExhausted()){deferOrAbandon(item);return}for(let attempt=0;;attempt++)try{let result=await admitCandidate(directory,item.candidate,admissionDeps);if(result.outcome==="admitted")summary.admitted++;else if(result.outcome==="reinforced")summary.reinforced++;else summary.rejected++;return}catch(err){if(attempt>=maxRetries){warn(`[learning-admission] candidate failed after ${attempt+1} attempt(s): ${isAbortError(err)?"cancelled":err instanceof Error?err.message:String(err)}`),deferOrAbandon(item);return}if(summary.retries++,recordRetry(sessionID),budgetExhausted()){deferOrAbandon(item);return}}}))),summary}init_memory();init_observability();init_manager();init_prm();init_ephemeral_agent_dispatcher();function createReviewModelDispatcher(client){return{dispatch:(request)=>dispatchEphemeralAgent({client,directory:request.directory,parentSessionId:request.parentSessionId,agentName:request.agentName,model:request.model,system:request.system,prompt:request.prompt,readOnlyTools:DEFAULT_READ_ONLY_TOOLS,title:request.title,timeoutMs:request.timeoutMs&&request.timeoutMs>0?request.timeoutMs:DEFAULT_EPHEMERAL_TIMEOUT_MS,promptByteLimit:request.promptByteLimit,responseByteLimit:request.responseByteLimit,abortSignal:request.abortSignal})}}init_finding_validator();init_runtime2();init_compaction_service();init_config_doctor();init_cost_accounting();init_version_check();init_state3();init_utils2();init_state2();init_bun_compat();init_logger();import{renameSync as renameSync37}from"node:fs";var TRANSIENT_SESSION_FIELDS=[{name:"revisionLimitHit",resetValue:!1},{name:"coderRevisions",resetValue:0},{name:"selfFixAttempted",resetValue:!1},{name:"lastGateFailure",resetValue:null},{name:"architectWriteCount",resetValue:0},{name:"selfCodingWarnedAtCount",resetValue:0},{name:"pendingAdvisoryMessages",resetValue:[]},{name:"model_fallback_index",resetValue:0},{name:"modelFallbackExhausted",resetValue:!1},{name:"scopeViolationDetected",resetValue:!1},{name:"delegationActive",resetValue:!1},{name:"autoProceedOverride",resetValue:void 0},{name:"autoProceedNudgeDone",resetValue:void 0}],VALID_TASK_WORKFLOW_STATES=["idle","coder_delegated","pre_check_passed","reviewer_run","tests_run","rework_required","complete","blocked","closed"];function deserializeTaskWorkflowStates(raw){let m=new Map;if(!raw||typeof raw!=="object")return m;for(let[taskId,stateVal]of Object.entries(raw))if(VALID_TASK_WORKFLOW_STATES.includes(stateVal))m.set(taskId,stateVal);return m}function deserializeModifiedFilesByTask(raw){let entries=new Map;if(!raw||typeof raw!=="object")return entries;let serializedEntries=Object.entries(raw);if(serializedEntries.length>MAX_TRACKED_TASK_FILE_ATTRIBUTIONS)return entries;for(let[taskId,files]of serializedEntries){if(!taskId.trim()||!Array.isArray(files))continue;let validFiles=files.filter((file3)=>typeof file3==="string"&&file3.length>0);entries.set(taskId,[...new Set(validFiles)])}return entries}function deserializeAgentSession(s){let lastGateFailure=s.lastGateFailure?{tool:s.lastGateFailure.tool,taskId:s.lastGateFailure.taskId,timestamp:s.lastGateFailure.timestamp,...typeof s.lastGateFailure.code==="string"&&/^[A-Z][A-Z0-9_]{0,63}$/.test(s.lastGateFailure.code)&&{code:s.lastGateFailure.code}}:null,taskWorkflowStates=deserializeTaskWorkflowStates(s.taskWorkflowStates),modifiedFilesByTask=deserializeModifiedFilesByTask(s.modifiedFilesByTask),gateLog=new Map;if(s.gateLog)for(let[taskId,gates]of Object.entries(s.gateLog))gateLog.set(taskId,new Set(gates??[]));let reviewerCallCount=new Map;if(s.reviewerCallCount)for(let[phase,count]of Object.entries(s.reviewerCallCount)){let numPhase=Number(phase);if(Number.isFinite(numPhase))reviewerCallCount.set(numPhase,count)}let partialGateWarningsIssuedForTask=new Set(s.partialGateWarningsIssuedForTask??[]),completionGateWarnedForTask=new Set(s.completionGateWarnedForTask??[]),catastrophicPhaseWarnings=new Set(s.catastrophicPhaseWarnings??[]),phaseAgentsDispatched=new Set(s.phaseAgentsDispatched??[]),lastCompletedPhaseAgentsDispatched=new Set(s.lastCompletedPhaseAgentsDispatched??[]),stageBCompletion=new Map;if(s.stageBCompletion)for(let[taskId,agents]of Object.entries(s.stageBCompletion))stageBCompletion.set(taskId,new Set(agents));let windows={};for(let[key,win]of Object.entries(s.windows??{})){if(!win||typeof win!=="object")continue;windows[key]={...win,transientRetryCount:"transientRetryCount"in win?win.transientRetryCount??0:0}}return{agentName:s.agentName,lastToolCallTime:s.lastToolCallTime,lastAgentEventTime:s.lastAgentEventTime,delegationActive:s.delegationActive,activeInvocationId:s.activeInvocationId,lastInvocationIdByAgent:s.lastInvocationIdByAgent??{},windows,lastCompactionHint:s.lastCompactionHint??0,architectWriteCount:s.architectWriteCount??0,lastCoderDelegationTaskId:s.lastCoderDelegationTaskId??null,currentTaskId:s.currentTaskId??null,turboMode:s.turboMode??!1,turboStrategy:s.turboStrategy==="lean"||s.turboStrategy==="standard"?s.turboStrategy:void 0,leanTurboActive:s.leanTurboActive??!1,leanTurboCurrentPhase:typeof s.leanTurboCurrentPhase==="number"?s.leanTurboCurrentPhase:void 0,epicModeActive:s.epicModeActive??!1,gateLog,reviewerCallCount,lastGateFailure,partialGateWarningsIssuedForTask,completionGateWarnedForTask,selfFixAttempted:s.selfFixAttempted??!1,selfCodingWarnedAtCount:s.selfCodingWarnedAtCount??0,catastrophicPhaseWarnings,lastPhaseCompleteTimestamp:s.lastPhaseCompleteTimestamp??0,lastPhaseCompletePhase:s.lastPhaseCompletePhase??0,phaseAgentsDispatched,lastCompletedPhaseAgentsDispatched,qaSkipCount:s.qaSkipCount??0,qaSkipTaskIds:s.qaSkipTaskIds??[],taskWorkflowStates,lastGateOutcome:null,declaredCoderScope:null,lastScopeViolation:null,scopeViolationDetected:s.scopeViolationDetected,modifiedFilesByTask,modifiedFilesThisCoderTask:s.currentTaskId&&s.currentTaskId.trim()!==""&&modifiedFilesByTask.has(s.currentTaskId)?[...modifiedFilesByTask.get(s.currentTaskId)??[]]:[],loopDetectionWindow:[],pendingAdvisoryMessages:s.pendingAdvisoryMessages??[],model_fallback_index:s.model_fallback_index??0,modelFallbackExhausted:s.modelFallbackExhausted??!1,coderRevisions:s.coderRevisions??0,revisionLimitHit:s.revisionLimitHit??!1,fullAutoMode:s.fullAutoMode??!1,fullAutoInteractionCount:s.fullAutoInteractionCount??0,fullAutoDeadlockCount:s.fullAutoDeadlockCount??0,fullAutoLastQuestionHash:s.fullAutoLastQuestionHash??null,maxConcurrencyOverride:typeof s.maxConcurrencyOverride==="number"?Math.min(64,Math.max(1,s.maxConcurrencyOverride)):void 0,autoProceedOverride:s.autoProceedOverride,autoProceedNudgeDone:s.autoProceedNudgeDone,prmPatternCounts:new Map,prmEscalationLevel:0,prmLastPatternDetected:null,prmTrajectoryStep:0,prmHardStopPending:!1,prmHardStopInjectPending:!1,prmInjectedAdvisoryKeys:new Set,prmStruckEpisodes:new Map,prmLadderCounts:new Map,executionEpisodeArmed:!1,sessionRehydratedAt:s.sessionRehydratedAt??0,stageBCompletion,prSubscriptions:new Map,cachedCohortId:typeof s.cachedCohortId==="string"?s.cachedCohortId:void 0,lastObservedModel:typeof s.lastObservedModel==="string"?s.lastObservedModel:void 0,lastObservedProviderID:typeof s.lastObservedProviderID==="string"?s.lastObservedProviderID:void 0}}async function readSnapshot(directory){try{let resolvedPath=validateSwarmPath(directory,"session/state.json"),content=await bunFile(resolvedPath).text();if(!content.trim())return null;let parsed=JSON.parse(content,(key,value)=>{if(key==="__proto__"||key==="constructor")return;return value});if(parsed.version!==1&&parsed.version!==2&&parsed.version!==3){try{let quarantinePath=validateSwarmPath(directory,"session/state.json.quarantine");renameSync37(resolvedPath,quarantinePath)}catch{}return null}return parsed}catch{return null}}async function rehydrateState(snapshot,directory){if(swarmState.pendingRehydrations.size>0)await Promise.allSettled([...swarmState.pendingRehydrations]);if(swarmState.toolAggregates.clear(),swarmState.activeAgent.clear(),swarmState.delegationChains.clear(),swarmState.agentSessions.clear(),snapshot.toolAggregates)for(let[key,value]of Object.entries(snapshot.toolAggregates))swarmState.toolAggregates.set(key,value);if(snapshot.activeAgent)for(let[key,value]of Object.entries(snapshot.activeAgent))swarmState.activeAgent.set(key,value);if(snapshot.delegationChains)for(let[key,value]of Object.entries(snapshot.delegationChains))swarmState.delegationChains.set(key,value);let now2=Date.now();if(snapshot.agentSessions)for(let[sessionId,serializedSession]of Object.entries(snapshot.agentSessions)){if(!serializedSession||typeof serializedSession!=="object"||typeof serializedSession.agentName!=="string"||typeof serializedSession.lastToolCallTime!=="number"||typeof serializedSession.delegationActive!=="boolean"){log(`[snapshot-reader] Skipping malformed session ${sessionId}: missing required fields (agentName, lastToolCallTime, delegationActive)`);continue}let session=deserializeAgentSession(serializedSession);if(session.taskWorkflowStates=new Map,session.taskWorkflowCache=new Map,session.stageBCompletion=new Map,session.lastToolCallTime=now2,session.lastAgentEventTime=now2,session.sessionRehydratedAt=now2,session.windows)for(let window2 of Object.values(session.windows))window2.startedAtMs=now2,window2.lastSuccessTimeMs=now2,window2.hardLimitHit=!1,window2.toolCalls=0,window2.consecutiveErrors=0,window2.recentToolCalls=[],window2.warningIssued=!1,window2.warningReason="";for(let field of TRANSIENT_SESSION_FIELDS)session[field.name]=field.resetValue;if(session.fullAutoMode){let runStillActive=!1;if(directory)try{runStillActive=loadFullAutoRunState(directory,sessionId)?.status==="running"}catch{runStillActive=!1}if(!runStillActive)session.fullAutoMode=!1}swarmState.agentSessions.set(sessionId,session)}}async function loadSnapshot(directory){try{await buildRehydrationCache(directory);let snapshot=await readSnapshot(directory);if(snapshot!==null){await rehydrateState(snapshot,directory);for(let session of swarmState.agentSessions.values())applyRehydrationCache(session)}}catch{}}init_snapshot_writer();init_state2();init_telemetry();init_zod();init_config();init_agents2();init_schema();init_ephemeral_agent_dispatcher();import*as fs137 from"node:fs/promises";import*as path243 from"node:path";init_runtime2();init_state2();init_telemetry();init_provider_error_classification();init_swarm_artifact_cache();init_bun_compat();init_swarm_artifact_cache();import{rmSync as rmSync17}from"node:fs";import*as fs136 from"node:fs/promises";import*as path242 from"node:path";function leanTurboEvidenceDir(directory,phase){return path242.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=path242.resolve(path242.join(expectedDir,`${laneId}.json`)),resolvedDir=path242.resolve(expectedDir);if(!resolvedPath.startsWith(resolvedDir+path242.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=path242.dirname(filePath);await fs136.mkdir(dir,{recursive:!0});let tempPath=`${filePath}.tmp.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}`;try{await bunWrite(tempPath,content),await fs136.rename(tempPath,filePath),invalidateCachedArtifact(filePath)}catch(error93){try{rmSync17(tempPath,{force:!0})}catch{}throw error93}}function phaseEvidencePath(directory,phase){return path242.join(leanTurboEvidenceDir(directory,phase),"lean-turbo-phase.json")}async function writeLaneEvidence(directory,phase,evidence2){let targetPath=laneEvidencePath(directory,phase,evidence2.laneId);await atomicWriteJson(targetPath,evidence2)}async function writePhaseEvidence(directory,evidence2){let targetPath=phaseEvidencePath(directory,evidence2.phase);await atomicWriteJson(targetPath,evidence2)}async function readPhaseEvidence(directory,phase){let targetPath=phaseEvidencePath(directory,phase),content;try{content=await fs136.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 fs136.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=path242.join(evidenceDir,entry),content;try{content=await fs136.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:DEFAULT_EPHEMERAL_TIMEOUT_MS,requireDiffSummary:!1};function resolveDefaultReviewerAgent(generatedAgentNames,activeAgentName){return resolveAgentForActiveSwarm(generatedAgentNames,"reviewer",activeAgentName)}function resolveLegacyReviewerModelConfig(agentName,config3){if(config3?.dispatcher||config3?.agentModelRegistry)return;let agentBaseName=stripKnownSwarmPrefix(agentName),swarmId=agentBaseName!==agentName?agentName.slice(0,agentName.length-agentBaseName.length-1):void 0;return{agentBaseName,swarmAgents:getSwarmAgents(swarmId)}}async function compileReviewPackage(directory,phase,sessionID,requireDiffSummary){let lanes=await listLaneEvidence(directory,phase),persisted=_internals181.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 parseReviewerVerdict(responseText){let verdictMatch=responseText.toUpperCase().match(/VERDICT\s*:\s*(APPROVED|NEEDS_REVISION|REJECTED)/);if(!verdictMatch)return null;let verdict=verdictMatch[1],lines=responseText.split(`
6332
6339
  `),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=path243.join(directory,".swarm","evidence",String(phase));await fs137.mkdir(evidenceDir,{recursive:!0});let evidencePath=path243.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 fs137.writeFile(tempPath,content,"utf-8"),await fs137.rename(tempPath,evidencePath),invalidateCachedArtifact(evidencePath)}catch(error93){try{await fs137.unlink(tempPath)}catch{}throw error93}return evidencePath}async function defaultDispatchReviewerAgent(directory,reviewPackage,agentName,timeoutMs,parentSessionId,model,dispatcher){let activeDispatcher=dispatcher;if(!activeDispatcher){let legacyClient=swarmState.opencodeClient;if(!legacyClient)throw Error("ReviewModelDispatcher not available");activeDispatcher=createReviewModelDispatcher(legacyClient)}let system=`You are a read-only phase reviewer for Lean Turbo execution.
6333
6340
  Review the supplied phase execution evidence and decide whether the phase is ready to advance.
6334
6341
  Evaluate lane completion, unresolved degraded tasks, the file change set, and build status.
@@ -6370,7 +6377,7 @@ When all tasks are complete, signal completion.`}async _withStateLock(fn2){let c
6370
6377
  `,"utf8")}catch{}}async function removeCheckoutRestoreReceipt(receiptPath){await fsp7.rm(receiptPath)}async function restorePrWorkflowCheckout(directory,rawSessionID,requestedStashOid){let sessionID=normalizeSessionID3(rawSessionID);try{return await withInactivePrWorkflowCheckoutRestoreLock(directory,sessionID,async()=>{let receipts=await listCheckoutReceiptPaths(directory,sessionID);if(receipts.length===0)return{kind:"already_restored"};let normalizedRequested=requestedStashOid?.toLowerCase();if(normalizedRequested&&receipts.filter((entry)=>entry.stashOid===normalizedRequested).length!==1){let available=receipts.slice(0,MAX_CHECKOUT_RECEIPTS).map((entry)=>entry.stashOid);throw new CheckoutRestoreError("CHECKOUT_RESTORE_RECEIPT_AMBIGUOUS",`BLOCKED: no unique checkout receipt exists for stash ${normalizedRequested}; available stash_oid values: ${available.join(", ")}`)}let targets=await Promise.all(receipts.map(async(target)=>({...target,receipt:await readCheckoutRestoreReceipt(directory,target.receiptPath,sessionID,target.stashOid)})));targets.sort((left,right)=>left.receipt.preparedAt.localeCompare(right.receipt.preparedAt)||left.stashOid.localeCompare(right.stashOid));let verifiedCleanup=targets.filter((entry)=>entry.receipt.restoreState==="applied"&&typeof entry.receipt.restoreVerifiedAt==="string"),restoreTargets=targets.filter((entry)=>entry.receipt.restoreState!=="applied"||typeof entry.receipt.restoreVerifiedAt!=="string"),applied=restoreTargets.filter((entry)=>entry.receipt.restoreState==="applied"),pending=restoreTargets.filter((entry)=>entry.receipt.restoreState!=="applied"),observedStashes=null;try{observedStashes=await readCurrentStashOids(directory)}catch{}let receiptCleanupPending=!1;for(let target of verifiedCleanup)try{await _internals184.removeCheckoutRestoreReceipt(target.receiptPath)}catch{receiptCleanupPending=!0}if(restoreTargets.length===0){let first2=verifiedCleanup[0].receipt;return{kind:"restored",stashOids:targets.map((entry)=>entry.stashOid),retainedStashOids:observedStashes?targets.filter((entry)=>observedStashes.has(entry.stashOid)).map((entry)=>entry.stashOid):[],stashRetentionVerified:observedStashes!==null,originalHead:first2.originalHead,originalBranch:first2.originalBranch,restoredHead:first2.restoredHead,receiptCleanupPending}}let pendingDestinations=await Promise.all(pending.map((entry)=>resolveRestoreDestination(directory,entry.receipt))),destinations=[...applied.map((entry)=>({head:entry.receipt.restoredHead,branch:entry.receipt.restoredBranch})),...pendingDestinations],destination=destinations[0];if(destinations.some((candidate2)=>!sameRestoreDestination(destination,candidate2)))throw new CheckoutRestoreError("CHECKOUT_RESTORE_DESTINATION_AMBIGUOUS","BLOCKED: checkout receipts target different original checkouts; no switch or stash apply was attempted");if(pending.length>0){let activeStashes=observedStashes??await readCurrentStashOids(directory),missing=pending.filter((entry)=>!activeStashes.has(entry.stashOid));if(missing.length>0)throw new CheckoutRestoreError("CHECKOUT_RESTORE_STASH_MISSING",`BLOCKED: ${missing.length} preserved checkout stash(es) are missing; no checkout mutation was attempted`)}if(applied.length>0){let currentIdentity;try{currentIdentity=await captureCheckoutIdentity(directory)}catch{throw new CheckoutRestoreError("CHECKOUT_RESTORE_VERIFY_FAILED","BLOCKED: an applied checkout restoration could not be verified; its durable receipt remains for retry or manual recovery")}if(currentIdentity.originalHead!==destination.head||currentIdentity.originalBranch!==destination.branch)throw new CheckoutRestoreError("CHECKOUT_RESTORE_VERIFY_FAILED","BLOCKED: an applied checkout restoration no longer matches its recorded destination; its durable receipt remains for manual recovery")}else if(applied.length===0){let status;try{status=await readPorcelainStatus(directory)}catch{throw new CheckoutRestoreError("CHECKOUT_RESTORE_STATUS_FAILED","BLOCKED: unable to verify a clean destination checkout; no restore was attempted")}if(status.dirtyTrackedPaths.length>0||status.untrackedPaths.length>0||status.renameOrCopy)throw new CheckoutRestoreError("CHECKOUT_RESTORE_NOT_CLEAN","BLOCKED: checkout restoration requires a clean destination working tree; no switch or stash apply was attempted");if((await _internals184.runGit(directory,destination.branch?["switch","--",destination.branch]:["switch","--detach",destination.head])).exitCode!==0)throw new CheckoutRestoreError("CHECKOUT_RESTORE_SWITCH_FAILED","BLOCKED: Git could not return to the recorded original checkout; the stash and receipt remain intact")}for(let target of pending){if((await _internals184.runGit(directory,["stash","apply","--index",target.stashOid])).exitCode!==0)throw new CheckoutRestoreError("CHECKOUT_RESTORE_APPLY_FAILED",`BLOCKED: Git could not reapply preserved stash ${target.stashOid}; its receipt and immutable stash remain for explicit manual recovery`);let appliedReceipt;try{appliedReceipt=await markReceiptApplied(directory,target.receiptPath,target.receipt,destination)}catch{throw new CheckoutRestoreError("CHECKOUT_RESTORE_APPLIED_STATE_WRITE_FAILED",`BLOCKED: preserved stash ${target.stashOid} was applied, but durable applied-state recording failed; inspect the working tree and retained stash manually`)}target.receipt=appliedReceipt}let restoredIdentity;try{restoredIdentity=await captureCheckoutIdentity(directory)}catch{throw new CheckoutRestoreError("CHECKOUT_RESTORE_VERIFY_FAILED","BLOCKED: checkout restoration completed but its final identity could not be verified; inspect the working tree and retained applied-state receipts manually")}if(restoredIdentity.originalHead!==destination.head||restoredIdentity.originalBranch!==destination.branch)throw new CheckoutRestoreError("CHECKOUT_RESTORE_VERIFY_FAILED","BLOCKED: checkout restoration completed but its final identity could not be verified; inspect the working tree and retained applied-state receipts manually");for(let target of restoreTargets){if(!target.receipt.restoreVerifiedAt)try{target.receipt=await markReceiptVerified(directory,target.receiptPath,target.receipt)}catch{throw new CheckoutRestoreError("CHECKOUT_RESTORE_VERIFIED_STATE_WRITE_FAILED","BLOCKED: checkout restoration was verified, but durable verified-state recording failed; retained applied-state receipts remain for retry")}await appendRestoreEvent(directory,sessionID,target.receipt);try{await _internals184.removeCheckoutRestoreReceipt(target.receiptPath)}catch{receiptCleanupPending=!0}}let finalStashes=null;try{finalStashes=await readCurrentStashOids(directory)}catch{}let first=restoreTargets[0].receipt;return{kind:"restored",stashOids:targets.map((entry)=>entry.stashOid),retainedStashOids:finalStashes?targets.filter((entry)=>finalStashes.has(entry.stashOid)).map((entry)=>entry.stashOid):[],stashRetentionVerified:finalStashes!==null,originalHead:first.originalHead,originalBranch:first.originalBranch,restoredHead:destination.head,receiptCleanupPending}})}catch(error93){if(error93 instanceof Error&&error93.message.includes("checkout restoration is allowed only after"))throw new CheckoutRestoreError("CHECKOUT_RESTORE_GATE_ACTIVE",error93.message);if(error93 instanceof Error&&error93.message.includes("checkout restoration cannot mutate this project while session"))throw new CheckoutRestoreError("CHECKOUT_RESTORE_OTHER_SESSION_ACTIVE",error93.message);throw error93}}async function listPendingPrWorkflowCheckoutRestores(directory,sessionID){let receipts=await listCheckoutReceiptPaths(directory,normalizeSessionID3(sessionID));if(receipts.length===0)return[];let activeStashes=null;try{activeStashes=await readCurrentStashOids(directory)}catch{}return receipts.map((receipt)=>({stash_oid:receipt.stashOid,stash_present:activeStashes?.has(receipt.stashOid)??null}))}async function writeReceipt(directory,sessionID,preparation){let receiptPath=validateSwarmPath(directory,path246.join(RECEIPT_DIR,prWorkflowSessionFileStem(sessionID),`${preparation.stashOid}.json`));assertReceiptWithinByteBudget(sessionID,preparation),await writePrWorkflowAtomicJson(directory,receiptPath,buildReceiptDocument(sessionID,preparation))}async function appendPreparationEvent(directory,sessionID,preparation){try{let eventsPath=validateSwarmPath(directory,"events.jsonl");await fsp7.appendFile(eventsPath,`${JSON.stringify({type:"pr_workflow_checkout_prepared",timestamp:preparation.preparedAt,sessionID,mode:preparation.mode,gateRevision:preparation.gateRevision,stashOid:preparation.stashOid,paths:preparation.paths})}
6371
6378
  `,"utf-8")}catch{}}var _internals184={runGit:runGit7,readBoundedGitStdout,classifyGitState:classifyPrWorkflowGitState,removeCheckoutRestoreReceipt};function boundUntrustedPath(value){let cleaned="";for(let ch of value){let code=ch.codePointAt(0)??0,strip=code<=31||code>=127&&code<=159||code>=8234&&code<=8238||code>=8294&&code<=8297||ch==="`"||ch==="<"||ch===">";cleaned+=strip?" ":ch}return cleaned=cleaned.replace(/\s+/g," ").trim(),cleaned.length>MAX_ECHOED_PATH_LEN?`${cleaned.slice(0,MAX_ECHOED_PATH_LEN)}…`:cleaned}function structuredRestoreInstruction(stashOid){return`After complete_pr_workflow or abort_pr_workflow clears the gate, call prepare_pr_workflow_checkout with operation=restore; stash_oid=${stashOid} may be supplied as an exact receipt assertion`}function manualRecoveryInstruction(stashOid){return`manual recovery required: git stash apply --index ${stashOid}`}var prepare_pr_workflow_checkout=createSwarmTool({description:"Prepare or restore an auditable PR workflow checkout. Before binding, operation=prepare (the default) preserves dirty working-tree changes, records the original branch/HEAD and exact stash OID, and refuses unsafe state. After complete_pr_workflow or abort_pr_workflow clears the gate, one operation=restore call returns to the common recorded checkout and reapplies every pending receipt by immutable stash OID under the checkout mutation lock. Restored stashes remain as explicit safety backups because Git exposes no atomic identity-bound deletion for a non-top stash; the response lists retained_stash_oids. A PR_FEEDBACK branch may advance only as a descendant of its recorded commit; PR_REVIEW and detached identities remain exact. Legacy receipts derive the original commit from the stash and use a uniquely matching local branch when available. It refuses dirty, missing-stash, cross-session, divergent, or mixed-destination state without reset/clean. stash_oid is an optional exact receipt assertion, not a selector that leaves other receipts stranded. This tool never permits arbitrary stash commands.",args:{operation:PreparePrWorkflowCheckoutArgsSchema.shape.operation,paths:PreparePrWorkflowCheckoutArgsSchema.shape.paths,stash_oid:PreparePrWorkflowCheckoutArgsSchema.shape.stash_oid},execute:executePreparePrWorkflowCheckout});var AbortPrWorkflowArgsSchema=exports_external.object({mode:exports_external.enum(["PR_REVIEW","PR_FEEDBACK"]).optional(),kind:exports_external.literal("recovery"),reason:exports_external.string().trim().min(1).max(500)}).strict();async function executeAbortPrWorkflow(args2,directory,context={}){let parsed=AbortPrWorkflowArgsSchema.safeParse(args2);if(!parsed.success)return JSON.stringify({success:!1,message:`Invalid PR workflow abort: ${parsed.error.issues.map((issue3)=>`${issue3.path.join(".")}: ${issue3.message}`).join("; ")}`});if(!context.sessionID?.trim())return JSON.stringify({success:!1,message:"PR workflow abort requires an active sessionID"});try{let summary=await abortPrWorkflow(directory,context.sessionID,{kind:parsed.data.kind,reason:parsed.data.reason,...parsed.data.mode?{expectedMode:parsed.data.mode}:{}}),checkoutRestoreRequired=!0,checkoutRestoreReceipts=[];try{checkoutRestoreReceipts=await listPendingPrWorkflowCheckoutRestores(directory,context.sessionID),checkoutRestoreRequired=checkoutRestoreReceipts.length>0}catch{}return JSON.stringify({success:!0,mode:summary.mode,...summary.prHeadSha?{pr_head_sha:summary.prHeadSha}:{},open_lanes:summary.openLanes,gate_cleared:!0,checkout_restore_required:checkoutRestoreRequired,checkout_restore_receipts:checkoutRestoreReceipts})}catch(error93){return JSON.stringify({success:!1,message:error93 instanceof Error?error93.message:String(error93)})}}var abort_pr_workflow=createSwarmTool({description:'Abort an active PR_REVIEW or PR_FEEDBACK mechanical gate and clear its durable session state, stopping the auto-resume loop. Requires kind: "recovery" and a one-line `reason`. Use after bounded recovery is exhausted, including a bound review or feedback workflow; do NOT use as a shortcut while useful recovery work remains. Refuses to abort while the workflow is armed for publication (call complete_pr_workflow instead) or while PR workflow lanes are still in flight (collect their results first). Reports checkout_restore_required when preserved pre-workflow changes remain. Records a best-effort audit event to .swarm/events.jsonl.',args:{mode:AbortPrWorkflowArgsSchema.shape.mode,kind:AbortPrWorkflowArgsSchema.shape.kind,reason:AbortPrWorkflowArgsSchema.shape.reason},execute:executeAbortPrWorkflow});init_zod();init_external_tool_runner();init_path_security();init_create_tool();import*as fs138 from"node:fs";import*as path247 from"node:path";var ACTIONLINT_TIMEOUT_MS=15000,ACTIONLINT_MAX_STDOUT_BYTES=4194304,ACTIONLINT_MAX_STDERR_BYTES=131072,DEFAULT_MAX_RESULTS=200,HARD_CAP_RESULTS=2000,MAX_WORKFLOW_FILES=500,MAX_WORKFLOW_DIRS=200,MAX_WORKFLOW_DEPTH=20;function resolveActionlintBinary(){return _internals185.resolveExecutableFromPath(["actionlint"])}function normalizeRelativeWorkflowFile(file3,workspace){if(!file3||containsControlChars(file3)||containsPathTraversal(file3))return null;if(path247.isAbsolute(file3)||/^[A-Za-z]:[/\\]/.test(file3))return null;let normalizedInput=file3.split(/[\\/]+/).filter(Boolean).join(path247.sep);if(!/\.(ya?ml)$/i.test(normalizedInput))return null;try{let realWorkspace=fs138.realpathSync(workspace),resolved=path247.resolve(realWorkspace,normalizedInput),realFile=fs138.realpathSync(resolved),relative57=path247.relative(realWorkspace,realFile);if(!relative57||relative57.startsWith("..")||path247.isAbsolute(relative57))return null;return relative57.split(path247.sep).join("/")}catch{return null}}function discoverWorkflowFiles(workspace){let root=path247.join(workspace,".github","workflows");if(!fs138.existsSync(root))return{files:[],truncated:!1};let files=[],dirCount=0,truncated=!1,visit=(dir,depth=0)=>{if(files.length>=MAX_WORKFLOW_FILES||dirCount>=MAX_WORKFLOW_DIRS||depth>MAX_WORKFLOW_DEPTH){truncated=!0;return}dirCount++;let entries;try{entries=fs138.readdirSync(dir,{withFileTypes:!0})}catch{return}for(let entry of entries){if(files.length>=MAX_WORKFLOW_FILES||dirCount>=MAX_WORKFLOW_DIRS){truncated=!0;break}let full=path247.join(dir,entry.name);if(entry.isDirectory())visit(full,depth+1);else if(entry.isFile()&&/\.(ya?ml)$/i.test(entry.name)){let rel=normalizeRelativeWorkflowFile(path247.relative(workspace,full),workspace);if(rel)files.push(rel)}}};return visit(root),{files,truncated}}function parseActionlintOutput(stdout,workspace,maxResults){let findings=[],total=0;for(let line of stdout.split(`
6372
6379
  `)){if(!line.trim())continue;try{let entry=JSON.parse(line),file3=typeof entry.filepath==="string"?normalizeRelativeWorkflowFile(path247.isAbsolute(entry.filepath)?path247.relative(workspace,entry.filepath):entry.filepath,workspace):null;if(!file3)continue;if(total++,findings.length>=maxResults)continue;findings.push({file:file3,line:typeof entry.line==="number"?entry.line:1,column:typeof entry.column==="number"?entry.column:1,kind:typeof entry.kind==="string"?entry.kind:"unknown",message:typeof entry.message==="string"?entry.message:"",endColumn:typeof entry.end_column==="number"?entry.end_column:void 0})}catch{}}return{findings,total}}function sanitizeMaxResults(value){let numeric=typeof value==="number"&&Number.isFinite(value)?value:DEFAULT_MAX_RESULTS;return Math.min(Math.max(0,numeric),HARD_CAP_RESULTS)}var actionlint_scan=createSwarmTool({description:"Run actionlint against GitHub Actions workflow YAML files and return structured findings. Read-only; resolves actionlint lazily.",args:{files:exports_external.array(exports_external.string()).optional().describe("Optional workspace-relative workflow YAML files. Defaults to .github/workflows/**/*.yml,yaml."),max_results:exports_external.number().default(DEFAULT_MAX_RESULTS).describe("Maximum findings to return")},execute:async(args2,directory)=>{let obj=typeof args2==="object"&&args2!==null?args2:{},maxResults=sanitizeMaxResults(obj.max_results),requestedFiles=Array.isArray(obj.files)?obj.files:void 0;if(requestedFiles?.some((f)=>typeof f!=="string"))return JSON.stringify({error:!0,type:"invalid-input",message:"files must be an array of strings"},null,2);let discovery=requestedFiles?{files:requestedFiles.map((f)=>normalizeRelativeWorkflowFile(f,directory)).filter((f)=>Boolean(f)),truncated:!1}:_internals185.discoverWorkflowFiles(directory),files=discovery.files;if(requestedFiles&&files.length!==requestedFiles.length)return JSON.stringify({error:!0,type:"path-escape",message:"files must be existing workspace-relative GitHub Actions YAML files"},null,2);let uniqueFiles=Array.from(new Set(files)),cappedFiles=uniqueFiles.slice(0,MAX_WORKFLOW_FILES),discoveryTruncated=discovery.truncated||uniqueFiles.length>cappedFiles.length;if(files=cappedFiles,files.length===0)return JSON.stringify({clean:!discoveryTruncated,findings:[],total:0,truncated:discoveryTruncated,files:[],command:["actionlint","-format","{{json .}}"],note:discoveryTruncated?`Workflow discovery was truncated at ${MAX_WORKFLOW_FILES} files, ${MAX_WORKFLOW_DIRS} directories, or depth ${MAX_WORKFLOW_DEPTH}; result is incomplete.`:"No GitHub Actions workflow YAML files found"},null,2);let executable=_internals185.resolveActionlintBinary();if(!executable)return JSON.stringify({error:!0,type:"actionlint-not-found",message:"actionlint executable not found. Install actionlint and ensure it is on PATH."},null,2);let lintArgs=["-format","{{json .}}",...files.map((file3)=>`./${file3}`)],run=await _internals185.runExternalTool({executable,args:lintArgs,cwd:directory,timeoutMs:ACTIONLINT_TIMEOUT_MS,maxStdoutBytes:ACTIONLINT_MAX_STDOUT_BYTES,maxStderrBytes:ACTIONLINT_MAX_STDERR_BYTES});if(run.status==="timeout")return JSON.stringify({error:!0,type:"timeout",message:`actionlint timed out after ${ACTIONLINT_TIMEOUT_MS}ms`},null,2);if(run.status==="spawn-error")return JSON.stringify({error:!0,type:"unknown",message:run.message??"actionlint failed to start"},null,2);let{findings,total}=parseActionlintOutput(run.stdout,directory,maxResults);if(run.exitCode!==0&&findings.length===0&&run.stderr)return JSON.stringify({error:!0,type:"unknown",message:run.stderr.split(`
6373
- `)[0]},null,2);return JSON.stringify({findings,total,truncated:discoveryTruncated||total>maxResults||run.stdoutTruncated||run.stderrTruncated,files,command:["actionlint",...lintArgs],outputTruncated:run.stdoutTruncated||run.stderrTruncated,clean:findings.length===0&&total===0&&!discoveryTruncated&&!run.stdoutTruncated&&!run.stderrTruncated,note:discoveryTruncated?`Workflow discovery was truncated at ${MAX_WORKFLOW_FILES} files, ${MAX_WORKFLOW_DIRS} directories, or depth ${MAX_WORKFLOW_DEPTH}; result is incomplete.`:void 0},null,2)}}),_internals185={resolveExecutableFromPath,resolveActionlintBinary,runExternalTool,discoverWorkflowFiles,parseActionlintOutput};init_zod();init_config();import{existsSync as existsSync123,mkdirSync as mkdirSync62,mkdtempSync as mkdtempSync4,readFileSync as readFileSync95,realpathSync as realpathSync38,renameSync as renameSync39,rmdirSync as rmdirSync2,unlinkSync as unlinkSync38,writeFileSync as writeFileSync43}from"node:fs";import*as path248 from"node:path";class SequenceMatcher{a;b;isJunk;autoJunk;b2j=new Map;popularSet=new Set;matchingBlocks=null;constructor(isJunk,a,b,autoJunk=!0){this.a=a,this.b=b,this.isJunk=isJunk,this.autoJunk=autoJunk,this.chainB()}setSeqs(a,b){this.a=a,this.b=b,this.matchingBlocks=null,this.chainB()}chainB(){let b=this.b,b2j=new Map;for(let i=0;i<b.length;i++){let ch=b[i],positions=b2j.get(ch);if(positions===void 0)b2j.set(ch,[i]);else positions.push(i)}if(this.isJunk){let junk=[];for(let ch of b2j.keys())if(this.isJunk(ch))junk.push(ch);for(let ch of junk)b2j.delete(ch)}if(this.popularSet=new Set,this.autoJunk&&b.length>=200){let threshold=b.length*0.01+0.5,popular=[];for(let[ch,indices]of b2j)if(indices.length>threshold)popular.push(ch);for(let ch of popular)this.popularSet.add(ch),b2j.delete(ch)}this.b2j=b2j}findLongestMatch(alo,ahi,blo,bhi){let a=this.a,b=this.b,b2j=this.b2j,bestI=alo,bestJ=blo,bestSize=0,j2len=new Map;for(let i=alo;i<ahi;i++){let ch=a[i],positions=b2j.get(ch);if(positions===void 0){j2len.clear();continue}let newJ2len=new Map;for(let j of positions){if(j<blo)continue;if(j>=bhi)break;let size=(j2len.get(j-1)??0)+1;if(newJ2len.set(j,size),size>bestSize)bestI=i-size+1,bestJ=j-size+1,bestSize=size}j2len.clear();for(let[k,v]of newJ2len)j2len.set(k,v)}while(bestI>alo&&bestJ>blo&&a[bestI-1]===b[bestJ-1])bestI--,bestJ--,bestSize++;while(bestI+bestSize<ahi&&bestJ+bestSize<bhi&&a[bestI+bestSize]===b[bestJ+bestSize])bestSize++;return{a:bestI,b:bestJ,size:bestSize}}getMatchingBlocks(){if(this.matchingBlocks!==null)return this.matchingBlocks;let la=this.a.length,lb=this.b.length,matches=[],stack=[[0,la,0,lb]];while(stack.length>0){let[alo,ahi,blo,bhi]=stack.pop(),m=this.findLongestMatch(alo,ahi,blo,bhi),{a:i,b:j,size}=m;if(size>0){if(matches.push(m),alo<i&&blo<j)stack.push([alo,i,blo,j]);if(i+size<ahi&&j+size<bhi)stack.push([i+size,ahi,j+size,bhi])}}return matches.sort((x,y)=>x.a-y.a||x.b-y.b),matches.push({a:la,b:lb,size:0}),this.matchingBlocks=matches,matches}ratio(){let matches=this.getMatchingBlocks(),m=0;for(let block of matches)m+=block.size;let t=this.a.length+this.b.length;if(t===0)return 1;return 2*m/t}getOpcodes(){let blocks=this.getMatchingBlocks(),opcodes=[],i=0,j=0;for(let block of blocks){let{a:ai,b:bj,size}=block;if(i<ai&&j<bj)opcodes.push({tag:"replace",i1:i,i2:ai,j1:j,j2:bj});else if(i<ai)opcodes.push({tag:"delete",i1:i,i2:ai,j1:j,j2:bj});else if(j<bj)opcodes.push({tag:"insert",i1:i,i2:ai,j1:j,j2:bj});if(size>0)opcodes.push({tag:"equal",i1:ai,i2:ai+size,j1:bj,j2:bj+size});i=ai+size,j=bj+size}return opcodes}}var UNICODE_MAP={"“":'"',"”":'"',"‘":"'","’":"'","—":"--","–":"-","…":"..."," ":" "};function unicodeNormalize(text){let out=text;for(let[char,repl]of Object.entries(UNICODE_MAP))out=out.split(char).join(repl);return out}function leadingWhitespace(line){let i=0;while(i<line.length&&(line[i]===" "||line[i]==="\t"))i++;return line.slice(0,i)}function firstMeaningfulLine(text){for(let line of text.split(`
6380
+ `)[0]},null,2);return JSON.stringify({findings,total,truncated:discoveryTruncated||total>maxResults||run.stdoutTruncated||run.stderrTruncated,files,command:["actionlint",...lintArgs],outputTruncated:run.stdoutTruncated||run.stderrTruncated,clean:findings.length===0&&total===0&&!discoveryTruncated&&!run.stdoutTruncated&&!run.stderrTruncated,note:discoveryTruncated?`Workflow discovery was truncated at ${MAX_WORKFLOW_FILES} files, ${MAX_WORKFLOW_DIRS} directories, or depth ${MAX_WORKFLOW_DEPTH}; result is incomplete.`:void 0},null,2)}}),_internals185={resolveExecutableFromPath,resolveActionlintBinary,runExternalTool,discoverWorkflowFiles,parseActionlintOutput};init_zod();init_config();import{existsSync as existsSync124,mkdirSync as mkdirSync62,mkdtempSync as mkdtempSync4,readFileSync as readFileSync95,realpathSync as realpathSync38,renameSync as renameSync38,rmdirSync as rmdirSync2,unlinkSync as unlinkSync39,writeFileSync as writeFileSync43}from"node:fs";import*as path248 from"node:path";class SequenceMatcher{a;b;isJunk;autoJunk;b2j=new Map;popularSet=new Set;matchingBlocks=null;constructor(isJunk,a,b,autoJunk=!0){this.a=a,this.b=b,this.isJunk=isJunk,this.autoJunk=autoJunk,this.chainB()}setSeqs(a,b){this.a=a,this.b=b,this.matchingBlocks=null,this.chainB()}chainB(){let b=this.b,b2j=new Map;for(let i=0;i<b.length;i++){let ch=b[i],positions=b2j.get(ch);if(positions===void 0)b2j.set(ch,[i]);else positions.push(i)}if(this.isJunk){let junk=[];for(let ch of b2j.keys())if(this.isJunk(ch))junk.push(ch);for(let ch of junk)b2j.delete(ch)}if(this.popularSet=new Set,this.autoJunk&&b.length>=200){let threshold=b.length*0.01+0.5,popular=[];for(let[ch,indices]of b2j)if(indices.length>threshold)popular.push(ch);for(let ch of popular)this.popularSet.add(ch),b2j.delete(ch)}this.b2j=b2j}findLongestMatch(alo,ahi,blo,bhi){let a=this.a,b=this.b,b2j=this.b2j,bestI=alo,bestJ=blo,bestSize=0,j2len=new Map;for(let i=alo;i<ahi;i++){let ch=a[i],positions=b2j.get(ch);if(positions===void 0){j2len.clear();continue}let newJ2len=new Map;for(let j of positions){if(j<blo)continue;if(j>=bhi)break;let size=(j2len.get(j-1)??0)+1;if(newJ2len.set(j,size),size>bestSize)bestI=i-size+1,bestJ=j-size+1,bestSize=size}j2len.clear();for(let[k,v]of newJ2len)j2len.set(k,v)}while(bestI>alo&&bestJ>blo&&a[bestI-1]===b[bestJ-1])bestI--,bestJ--,bestSize++;while(bestI+bestSize<ahi&&bestJ+bestSize<bhi&&a[bestI+bestSize]===b[bestJ+bestSize])bestSize++;return{a:bestI,b:bestJ,size:bestSize}}getMatchingBlocks(){if(this.matchingBlocks!==null)return this.matchingBlocks;let la=this.a.length,lb=this.b.length,matches=[],stack=[[0,la,0,lb]];while(stack.length>0){let[alo,ahi,blo,bhi]=stack.pop(),m=this.findLongestMatch(alo,ahi,blo,bhi),{a:i,b:j,size}=m;if(size>0){if(matches.push(m),alo<i&&blo<j)stack.push([alo,i,blo,j]);if(i+size<ahi&&j+size<bhi)stack.push([i+size,ahi,j+size,bhi])}}return matches.sort((x,y)=>x.a-y.a||x.b-y.b),matches.push({a:la,b:lb,size:0}),this.matchingBlocks=matches,matches}ratio(){let matches=this.getMatchingBlocks(),m=0;for(let block of matches)m+=block.size;let t=this.a.length+this.b.length;if(t===0)return 1;return 2*m/t}getOpcodes(){let blocks=this.getMatchingBlocks(),opcodes=[],i=0,j=0;for(let block of blocks){let{a:ai,b:bj,size}=block;if(i<ai&&j<bj)opcodes.push({tag:"replace",i1:i,i2:ai,j1:j,j2:bj});else if(i<ai)opcodes.push({tag:"delete",i1:i,i2:ai,j1:j,j2:bj});else if(j<bj)opcodes.push({tag:"insert",i1:i,i2:ai,j1:j,j2:bj});if(size>0)opcodes.push({tag:"equal",i1:ai,i2:ai+size,j1:bj,j2:bj+size});i=ai+size,j=bj+size}return opcodes}}var UNICODE_MAP={"“":'"',"”":'"',"‘":"'","’":"'","—":"--","–":"-","…":"..."," ":" "};function unicodeNormalize(text){let out=text;for(let[char,repl]of Object.entries(UNICODE_MAP))out=out.split(char).join(repl);return out}function leadingWhitespace(line){let i=0;while(i<line.length&&(line[i]===" "||line[i]==="\t"))i++;return line.slice(0,i)}function firstMeaningfulLine(text){for(let line of text.split(`
6374
6381
  `))if(line.trim())return line;return null}function fuzzyFindAndReplace(content,oldString,newString,replaceAll=!1,options={}){if(!oldString)return{content,matchCount:0,strategy:null,error:"old_string cannot be empty"};if(oldString===newString)return{content,matchCount:0,strategy:null,error:"old_string and new_string are identical"};let strategies=[["exact",strategyExact],["line_trimmed",strategyLineTrimmed],["whitespace_normalized",strategyWhitespaceNormalized],["indentation_flexible",strategyIndentationFlexible],["escape_normalized",strategyEscapeNormalized],["trimmed_boundary",strategyTrimmedBoundary],["unicode_normalized",strategyUnicodeNormalized],["block_anchor",strategyBlockAnchor]];if(options.includeContextAware!==!1)strategies.push(["context_aware",strategyContextAware]);for(let[strategyName,strategyFn]of strategies){let matches=strategyFn(content,oldString);if(matches.length===0)continue;if(matches.length>1&&!replaceAll)return{content,matchCount:0,strategy:null,error:`Found ${matches.length} matches for old_string. Provide more context to make it unique, or use replace_all=true.`};if(strategyName!=="exact"){let driftErr=detectEscapeDrift(content,matches,oldString,newString);if(driftErr)return{content,matchCount:0,strategy:null,error:driftErr}}let effectiveNew=maybeUnescapeNewString(newString,content,matches);if(strategyName==="unicode_normalized"||strategyName==="block_anchor"||strategyName==="context_aware")effectiveNew=preserveUnicodeInReplacement(content,matches,oldString,effectiveNew);return{content:applyReplacements(content,matches,effectiveNew,strategyName!=="exact"?oldString:null),matchCount:matches.length,strategy:strategyName,error:null}}return{content,matchCount:0,strategy:null,error:"Could not find a match for old_string in the file"}}function detectEscapeDrift(content,matches,oldString,newString){if(!newString.includes("\\'")&&!newString.includes("\\\""))return null;let matchedRegions="";for(let[start,end]of matches)matchedRegions+=content.slice(start,end);for(let suspect of["\\'","\\\""])if(newString.includes(suspect)&&oldString.includes(suspect)&&!matchedRegions.includes(suspect)){let plain=suspect[1];return`Escape-drift detected: old_string and new_string contain the literal sequence ${JSON.stringify(suspect)} but the matched region of the file does not. This is almost always a tool-call serialization artifact where an apostrophe or quote got prefixed with a spurious backslash. Re-read the file with read_file and pass old_string/new_string without backslash-escaping ${JSON.stringify(plain)} characters.`}return null}function maybeUnescapeNewString(newString,content,matches){if(!newString.includes("\\t")&&!newString.includes("\\r"))return newString;let matchedRegions="";for(let[start,end]of matches)matchedRegions+=content.slice(start,end);let out=newString;if(out.includes("\\t")&&matchedRegions.includes("\t"))out=out.split("\\t").join("\t");if(out.includes("\\r")&&matchedRegions.includes("\r"))out=out.split("\\r").join("\r");return out}function reindentReplacement(fileRegion,oldString,newString){if(!newString)return newString;let oldFirst=firstMeaningfulLine(oldString),fileFirst=firstMeaningfulLine(fileRegion);if(oldFirst===null||fileFirst===null)return newString;let oldIndent=leadingWhitespace(oldFirst),fileIndent=leadingWhitespace(fileFirst);if(oldIndent===fileIndent)return newString;let outLines=[];for(let line of newString.split(`
6375
6382
  `)){if(!line.trim()){outLines.push(line);continue}if(leadingWhitespace(line).startsWith(oldIndent)){let remainder=line.slice(oldIndent.length);outLines.push(fileIndent+remainder)}else outLines.push(fileIndent+line.replace(/^[ \t]+/,""))}return outLines.join(`
6376
6383
  `)}function preserveUnicodeInReplacement(content,matches,oldString,newString){let fileRegion="";for(let[start,end]of matches)fileRegion+=content.slice(start,end);let normOld=unicodeNormalize(oldString),normFile=unicodeNormalize(fileRegion);if(normOld!==normFile)return newString;let fileOrigToNorm=buildOrigToNormMap(fileRegion),fileNormToOrig=new Map;for(let origPos=0;origPos<fileOrigToNorm.length-1;origPos++){let np=fileOrigToNorm[origPos];if(!fileNormToOrig.has(np))fileNormToOrig.set(np,origPos)}let opcodes=new SequenceMatcher(null,normOld,newString).getOpcodes(),resultParts=[];for(let op of opcodes){let{tag,i1,i2,j1,j2}=op;if(tag==="equal"){let origStart=fileNormToOrig.get(i1)??0,origEnd=origStart;while(origEnd<fileRegion.length&&fileOrigToNorm[origEnd]<i2)origEnd++;resultParts.push(fileRegion.slice(origStart,origEnd))}else if(tag==="replace")resultParts.push(newString.slice(j1,j2));else if(tag==="delete");else if(tag==="insert")resultParts.push(newString.slice(j1,j2))}return resultParts.join("")}function applyReplacements(content,matches,newString,oldString){let sorted=[...matches].sort((x,y)=>y[0]-x[0]),result=content;for(let[start,end]of sorted){let adjusted=oldString!==null?reindentReplacement(content.slice(start,end),oldString,newString):newString;result=result.slice(0,start)+adjusted+result.slice(end)}return result}function buildOrigToNormMap(original){let result=[],normPos=0;for(let i=0;i<original.length;i++){result.push(normPos);let repl=UNICODE_MAP[original[i]];normPos+=repl!==void 0?repl.length:1}return result.push(normPos),result}function mapPositionsNormToOrig(origToNorm,normMatches){let normToOrigStart=new Map;for(let origPos=0;origPos<origToNorm.length-1;origPos++){let normPos=origToNorm[origPos];if(!normToOrigStart.has(normPos))normToOrigStart.set(normPos,origPos)}let results=[],origLen=origToNorm.length-1;for(let[normStart,normEnd]of normMatches){if(!normToOrigStart.has(normStart))continue;let origStart=normToOrigStart.get(normStart),origEnd=origStart;while(origEnd<origLen&&origToNorm[origEnd]<normEnd)origEnd++;results.push([origStart,origEnd])}return results}function calculateLinePositions(contentLines,startLine,endLine,contentLength){let start=0;for(let i=0;i<startLine;i++)start+=contentLines[i].length+1;let end=0;for(let i=0;i<endLine;i++)end+=contentLines[i].length+1;return end-=1,end=Math.min(contentLength,end),[start,end]}function findNormalizedMatches(content,contentLines,contentNormalizedLines,patternNormalized){let numPatternLines=patternNormalized.split(`
@@ -6405,34 +6412,34 @@ When all tasks are complete, signal completion.`}async _withStateLock(fn2){let c
6405
6412
  `),fuzzy=fuzzyFindAndReplace(currentContent,oldString,newString,!1,{includeContextAware:options.fuzzyMatchContextAware});if(fuzzy.error===null&&fuzzy.matchCount===1){fileLines.length=0;for(let line of fuzzy.content.split(`
6406
6413
  `))fileLines.push(line);accumulatedDelta+=newLinesForHunk.length-expectedOldLines.length;continue}fuzzyAttemptedThisHunk=!0}if(!matchFound){let diagStart=Math.min(searchStart,fileLines.length),diagEnd=Math.min(diagStart+expectedOldLines.length,fileLines.length),actualContent=fileLines.slice(diagStart,diagEnd).join(`
6407
6414
  `),expectedContent=expectedOldLines.join(`
6408
- `);return{success:!1,failedHunkIndex:hunkIdx,fuzzyAttempted:fuzzyAttemptedThisHunk?!0:void 0,error:{hunkIndex:hunkIdx,type:"context-mismatch",message:`Context mismatch in hunk ${hunkIdx+1} at line ${searchStart+1}: expected context does not match file content`,expected:expectedContent.length>200?`${expectedContent.slice(0,200)}... (truncated)`:expectedContent,actual:actualContent.length>200?`${actualContent.slice(0,200)}... (truncated)`:actualContent,line:searchStart+1}}}}return{success:!0,appliedLines:fileLines}}function atomicWriteFileSync3(targetPath,content){let dir=path248.dirname(targetPath);mkdirSync62(dir,{recursive:!0});let tempPrefix=`.apply-patch-${Date.now()}-${process.pid}`,tempPath;try{let tempDir=realpathSync38(mkdtempSync4(path248.join(dir,tempPrefix)));tempPath=path248.join(tempDir,"content")}catch{tempPath=path248.join(dir,`${tempPrefix}.tmp`)}try{writeFileSync43(tempPath,content,"utf-8"),renameSync39(tempPath,targetPath)}finally{if(existsSync123(tempPath))try{unlinkSync38(tempPath)}catch{}let tempDir=path248.dirname(tempPath);if(tempDir!==dir&&existsSync123(tempDir))try{rmdirSync2(tempDir)}catch{}}}function detectLineEnding(content){return content.includes(`\r
6415
+ `);return{success:!1,failedHunkIndex:hunkIdx,fuzzyAttempted:fuzzyAttemptedThisHunk?!0:void 0,error:{hunkIndex:hunkIdx,type:"context-mismatch",message:`Context mismatch in hunk ${hunkIdx+1} at line ${searchStart+1}: expected context does not match file content`,expected:expectedContent.length>200?`${expectedContent.slice(0,200)}... (truncated)`:expectedContent,actual:actualContent.length>200?`${actualContent.slice(0,200)}... (truncated)`:actualContent,line:searchStart+1}}}}return{success:!0,appliedLines:fileLines}}function atomicWriteFileSync3(targetPath,content){let dir=path248.dirname(targetPath);mkdirSync62(dir,{recursive:!0});let tempPrefix=`.apply-patch-${Date.now()}-${process.pid}`,tempPath;try{let tempDir=realpathSync38(mkdtempSync4(path248.join(dir,tempPrefix)));tempPath=path248.join(tempDir,"content")}catch{tempPath=path248.join(dir,`${tempPrefix}.tmp`)}try{writeFileSync43(tempPath,content,"utf-8"),renameSync38(tempPath,targetPath)}finally{if(existsSync124(tempPath))try{unlinkSync39(tempPath)}catch{}let tempDir=path248.dirname(tempPath);if(tempDir!==dir&&existsSync124(tempDir))try{rmdirSync2(tempDir)}catch{}}}function detectLineEnding(content){return content.includes(`\r
6409
6416
  `)?`\r
6410
6417
  `:`
6411
6418
  `}function ensureFinalNewline(content,originalEndsWithNewline){if(originalEndsWithNewline&&!content.endsWith(`
6412
6419
  `))return`${content}
6413
6420
  `;if(!originalEndsWithNewline&&content.endsWith(`
6414
- `))return content.slice(0,-1);return content}function processFileDiff(fileDiff,targetPath,fullPath,workspace,dryRun,allowCreates,allowDeletes,hunkOptions){let hunksTotal=fileDiff.hunks.length;if(!isCanonicalPathWithinWorkspace(fullPath,workspace))return{file:targetPath,status:"error",hunks:hunksTotal,hunksApplied:0,hunksFailed:hunksTotal,errors:[{hunkIndex:0,type:"context-mismatch",message:`Path escapes workspace via symlink/junction: ${targetPath}`}]};if(isCanonicalProtectedPath(fullPath,workspace))return{file:targetPath,status:"error",hunks:hunksTotal,hunksApplied:0,hunksFailed:hunksTotal,errors:[{hunkIndex:0,type:"context-mismatch",message:`Protected directory target rejected via symlink: ${targetPath}`}]};if(fileDiff.isNewFile){if(!allowCreates)return{file:targetPath,status:"error",hunks:hunksTotal,hunksApplied:0,hunksFailed:hunksTotal,errors:[{hunkIndex:0,type:"create-not-allowed",message:`New file creation not allowed: ${targetPath} (set allowCreates to true)`}]};let parentDir=path248.dirname(fullPath);if(!existsSync123(parentDir))return{file:targetPath,status:"error",hunks:hunksTotal,hunksApplied:0,hunksFailed:hunksTotal,errors:[{hunkIndex:0,type:"file-not-found",message:`Parent directory does not exist: ${parentDir}`}]};if(existsSync123(fullPath))return{file:targetPath,status:"error",hunks:hunksTotal,hunksApplied:0,hunksFailed:hunksTotal,errors:[{hunkIndex:0,type:"file-not-found",message:`File already exists: ${targetPath} (cannot create — patch may be stale)`}]};if(hunksTotal===0)return{file:targetPath,status:"no-changes",hunks:0,hunksApplied:0,hunksFailed:0};let hunkResult2=applyHunks("",fileDiff);if(!hunkResult2.success||!hunkResult2.appliedLines)return{file:targetPath,status:"error",hunks:hunksTotal,hunksApplied:0,hunksFailed:hunksTotal,errors:hunkResult2.error?[hunkResult2.error]:[]};if(!dryRun){let content2=ensureFinalNewline(hunkResult2.appliedLines.join(`
6415
- `),!0);atomicWriteFileSync3(fullPath,content2)}return{file:targetPath,status:"created",hunks:hunksTotal,hunksApplied:hunksTotal,hunksFailed:0}}if(fileDiff.isDelete){if(hunksTotal===0)return{file:targetPath,status:"no-changes",hunks:0,hunksApplied:0,hunksFailed:0};if(!allowDeletes)return{file:targetPath,status:"error",hunks:hunksTotal,hunksApplied:0,hunksFailed:hunksTotal,errors:[{hunkIndex:0,type:"delete-not-allowed",message:`File deletion not allowed: ${targetPath} (set allowDeletes to true)`}]};if(!existsSync123(fullPath))return{file:targetPath,status:"error",hunks:hunksTotal,hunksApplied:0,hunksFailed:hunksTotal,errors:[{hunkIndex:0,type:"file-not-found",message:`File not found for deletion: ${targetPath}`}]};if(!dryRun)try{unlinkSync38(fullPath)}catch(err){return{file:targetPath,status:"error",hunks:hunksTotal,hunksApplied:0,hunksFailed:hunksTotal,errors:[{hunkIndex:0,type:"file-not-found",message:`Failed to delete file: ${err instanceof Error?err.message:String(err)}`}]}}return{file:targetPath,status:"applied",hunks:hunksTotal,hunksApplied:hunksTotal,hunksFailed:0}}if(!existsSync123(fullPath))return{file:targetPath,status:"error",hunks:hunksTotal,hunksApplied:0,hunksFailed:hunksTotal,errors:[{hunkIndex:0,type:"file-not-found",message:`File not found: ${targetPath}`}]};let content;try{content=readFileSync95(fullPath,"utf-8")}catch(err){return{file:targetPath,status:"error",hunks:hunksTotal,hunksApplied:0,hunksFailed:hunksTotal,errors:[{hunkIndex:0,type:"file-not-found",message:`Could not read file: ${err instanceof Error?err.message:String(err)}`}]}}if(hunksTotal===0)return{file:targetPath,status:"no-changes",hunks:0,hunksApplied:0,hunksFailed:0};let originalEndsWithNewline=content.endsWith(`
6421
+ `))return content.slice(0,-1);return content}function processFileDiff(fileDiff,targetPath,fullPath,workspace,dryRun,allowCreates,allowDeletes,hunkOptions){let hunksTotal=fileDiff.hunks.length;if(!isCanonicalPathWithinWorkspace(fullPath,workspace))return{file:targetPath,status:"error",hunks:hunksTotal,hunksApplied:0,hunksFailed:hunksTotal,errors:[{hunkIndex:0,type:"context-mismatch",message:`Path escapes workspace via symlink/junction: ${targetPath}`}]};if(isCanonicalProtectedPath(fullPath,workspace))return{file:targetPath,status:"error",hunks:hunksTotal,hunksApplied:0,hunksFailed:hunksTotal,errors:[{hunkIndex:0,type:"context-mismatch",message:`Protected directory target rejected via symlink: ${targetPath}`}]};if(fileDiff.isNewFile){if(!allowCreates)return{file:targetPath,status:"error",hunks:hunksTotal,hunksApplied:0,hunksFailed:hunksTotal,errors:[{hunkIndex:0,type:"create-not-allowed",message:`New file creation not allowed: ${targetPath} (set allowCreates to true)`}]};let parentDir=path248.dirname(fullPath);if(!existsSync124(parentDir))return{file:targetPath,status:"error",hunks:hunksTotal,hunksApplied:0,hunksFailed:hunksTotal,errors:[{hunkIndex:0,type:"file-not-found",message:`Parent directory does not exist: ${parentDir}`}]};if(existsSync124(fullPath))return{file:targetPath,status:"error",hunks:hunksTotal,hunksApplied:0,hunksFailed:hunksTotal,errors:[{hunkIndex:0,type:"file-not-found",message:`File already exists: ${targetPath} (cannot create — patch may be stale)`}]};if(hunksTotal===0)return{file:targetPath,status:"no-changes",hunks:0,hunksApplied:0,hunksFailed:0};let hunkResult2=applyHunks("",fileDiff);if(!hunkResult2.success||!hunkResult2.appliedLines)return{file:targetPath,status:"error",hunks:hunksTotal,hunksApplied:0,hunksFailed:hunksTotal,errors:hunkResult2.error?[hunkResult2.error]:[]};if(!dryRun){let content2=ensureFinalNewline(hunkResult2.appliedLines.join(`
6422
+ `),!0);atomicWriteFileSync3(fullPath,content2)}return{file:targetPath,status:"created",hunks:hunksTotal,hunksApplied:hunksTotal,hunksFailed:0}}if(fileDiff.isDelete){if(hunksTotal===0)return{file:targetPath,status:"no-changes",hunks:0,hunksApplied:0,hunksFailed:0};if(!allowDeletes)return{file:targetPath,status:"error",hunks:hunksTotal,hunksApplied:0,hunksFailed:hunksTotal,errors:[{hunkIndex:0,type:"delete-not-allowed",message:`File deletion not allowed: ${targetPath} (set allowDeletes to true)`}]};if(!existsSync124(fullPath))return{file:targetPath,status:"error",hunks:hunksTotal,hunksApplied:0,hunksFailed:hunksTotal,errors:[{hunkIndex:0,type:"file-not-found",message:`File not found for deletion: ${targetPath}`}]};if(!dryRun)try{unlinkSync39(fullPath)}catch(err){return{file:targetPath,status:"error",hunks:hunksTotal,hunksApplied:0,hunksFailed:hunksTotal,errors:[{hunkIndex:0,type:"file-not-found",message:`Failed to delete file: ${err instanceof Error?err.message:String(err)}`}]}}return{file:targetPath,status:"applied",hunks:hunksTotal,hunksApplied:hunksTotal,hunksFailed:0}}if(!existsSync124(fullPath))return{file:targetPath,status:"error",hunks:hunksTotal,hunksApplied:0,hunksFailed:hunksTotal,errors:[{hunkIndex:0,type:"file-not-found",message:`File not found: ${targetPath}`}]};let content;try{content=readFileSync95(fullPath,"utf-8")}catch(err){return{file:targetPath,status:"error",hunks:hunksTotal,hunksApplied:0,hunksFailed:hunksTotal,errors:[{hunkIndex:0,type:"file-not-found",message:`Could not read file: ${err instanceof Error?err.message:String(err)}`}]}}if(hunksTotal===0)return{file:targetPath,status:"no-changes",hunks:0,hunksApplied:0,hunksFailed:0};let originalEndsWithNewline=content.endsWith(`
6416
6423
  `),originalLineEnding=detectLineEnding(content),hunkResult=applyHunks(content,fileDiff,hunkOptions);if(!hunkResult.success){let errors5=hunkResult.error?[hunkResult.error]:[];if(hunkResult.fuzzyAttempted&&errors5.length>0&&hunkOptions?.fuzzyMatch){let expectedAnchor=errors5[0].expected??"",hint=findClosestLines(expectedAnchor,content);if(hint)errors5=[{...errors5[0],message:`${errors5[0].message}
6417
6424
 
6418
6425
  Did you mean one of these sections?
6419
6426
  ${hint}`}]}return{file:targetPath,status:"error",hunks:hunksTotal,hunksApplied:0,hunksFailed:hunksTotal,errors:errors5}}let resultContent=hunkResult.appliedLines.join(`
6420
6427
  `);if(resultContent===""&&!dryRun&&!allowDeletes&&content.length>0)return{file:targetPath,status:"error",hunks:hunksTotal,hunksApplied:hunksTotal,hunksFailed:0,errors:[{hunkIndex:0,type:"delete-not-allowed",message:`Patch would delete all content from ${targetPath}. Set allowDeletes to true to permit file deletion.`}]};let finalContent;if(resultContent==="")finalContent="";else{let withLineEnding=originalLineEnding===`\r
6421
6428
  `?resultContent.replace(/\n/g,`\r
6422
- `):resultContent;finalContent=ensureFinalNewline(withLineEnding,originalEndsWithNewline)}if(finalContent===content)return{file:targetPath,status:"no-changes",hunks:hunksTotal,hunksApplied:hunksTotal,hunksFailed:0};if(!dryRun)atomicWriteFileSync3(fullPath,finalContent);return{file:targetPath,status:"applied",hunks:hunksTotal,hunksApplied:hunksTotal,hunksFailed:0}}function buildErrorResult(message){return{success:!1,files:[{file:"",status:"error",hunks:0,hunksApplied:0,hunksFailed:0,errors:[{hunkIndex:0,type:"context-mismatch",message}]}],summary:{totalFiles:0,applied:0,failed:1,totalHunks:0}}}function isUnsupportedPatchFormat(patchText){let trimmed=patchText.trimStart();return trimmed.startsWith("*** Begin Patch")||trimmed.startsWith("*** Update File")||trimmed.startsWith("*** Add File")||trimmed.startsWith("*** Delete File")||trimmed.startsWith("*** End Patch")}var swarmApplyPatch2=createSwarmTool({description:"Apply a unified diff patch to workspace files. Validates paths, matches context exactly, and writes atomically. Coder-scoped write tool. Use standard unified diff format (--- a/file / +++ b/file / @@ hunks). Indented patches (e.g. inside a fenced markdown/YAML block) are automatically dedented to column 0 before parsing — the diff body itself may be indented. Does NOT support *** Begin Patch / *** Update File payloads — use the native apply_patch tool for those. Accepts the payload as `patch` (canonical) or any of the aliases `patchText`, `patch_text`, `patchPayload` (#2206); the resolver picks the first non-empty one.",args:{patch:exports_external.string().optional().describe("Unified diff text to parse and apply (optional when an alias below carries the payload)"),patchText:exports_external.string().optional().describe("Alias for patch — unified diff payload; accepted because models frequently hallucinate alternative argument names (#2206)"),patch_text:exports_external.string().optional().describe("Alias for patch — unified diff payload; accepted because models frequently hallucinate alternative argument names (#2206)"),patchPayload:exports_external.string().optional().describe("Alias for patch — unified diff payload; accepted because models frequently hallucinate alternative argument names (#2206)"),files:exports_external.array(exports_external.string()).min(1).describe("Array of target file paths the patch is expected to touch. Every parsed target must appear in this list."),dryRun:exports_external.boolean().optional().default(!1).describe("Validate without writing files (default: false)"),allowCreates:exports_external.boolean().optional().default(!1).describe("Allow creating new files from patches with --- /dev/null (default: false)"),allowDeletes:exports_external.boolean().optional().default(!1).describe("Allow deleting files from patches with +++ /dev/null (default: false)")},execute:async(args2,directory)=>{if(!args2||typeof args2!=="object")return JSON.stringify(buildErrorResult("Could not parse swarm_apply_patch arguments"),null,2);let obj=args2,patchText=[obj.patch,obj.patchText,obj.patch_text,obj.patchPayload].find((value)=>typeof value==="string"&&value.length>0)??"",files=obj.files??[],dryRun=obj.dryRun??!1,allowCreates=obj.allowCreates??!1,allowDeletes=obj.allowDeletes??!1,{config:config3}=_internals186.loadPluginConfigWithMeta(directory),fuzzyMatch=config3.apply_patch?.fuzzy_match===!0,fuzzyMatchContextAware=config3.apply_patch?.fuzzy_match_context_aware===!0,hunkOptions=fuzzyMatch||fuzzyMatchContextAware?{fuzzyMatch,fuzzyMatchContextAware}:void 0;if(!existsSync123(directory))return JSON.stringify(buildErrorResult("Workspace directory does not exist"),null,2);if(files.length===0)return JSON.stringify(buildErrorResult("files array cannot be empty"),null,2);if(!patchText||patchText.trim()==="")return JSON.stringify(buildErrorResult("patch text cannot be empty"),null,2);if(isUnsupportedPatchFormat(patchText))return JSON.stringify(buildErrorResult("Unsupported patch format: *** Begin Patch / *** Update File style payloads are not supported by swarm_apply_patch. Use the native apply_patch tool for this format, or provide a standard unified diff (--- a/file / +++ b/file / @@ hunks)."),null,2);for(let filePath of files){let validationError=validatePatchTargetPath(filePath,directory);if(validationError)return JSON.stringify(buildErrorResult(validationError),null,2)}let{files:parsedFiles,error:parseError}=parseUnifiedDiff(patchText);if(parseError)return JSON.stringify(buildErrorResult(parseError),null,2);if(parsedFiles.length===0)return JSON.stringify({success:!0,dryRun,files:[],summary:{totalFiles:0,applied:0,failed:0,totalHunks:0}},null,2);let declaredFileSet=new Set(files),undeclaredTargets=[];for(let fileDiff of parsedFiles){let targetPath=fileDiff.isDelete?fileDiff.oldPath:fileDiff.newPath;if(targetPath&&targetPath!=="/dev/null"&&!declaredFileSet.has(targetPath))undeclaredTargets.push(targetPath)}if(undeclaredTargets.length>0)return JSON.stringify(buildErrorResult(`Patch targets files not in the declared files array: ${undeclaredTargets.join(", ")}`),null,2);let parsedTargetSet=new Set(parsedFiles.map((fd)=>fd.isDelete?fd.oldPath:fd.newPath).filter(Boolean)),extraFiles=files.filter((f)=>!parsedTargetSet.has(f)),fileResults=[],totalApplied=0,totalFailed=0,totalHunks=0;for(let fileDiff of parsedFiles){let targetPath=fileDiff.isDelete?fileDiff.oldPath:fileDiff.newPath,fullPath=path248.resolve(directory,targetPath);totalHunks+=fileDiff.hunks.length;let result=processFileDiff(fileDiff,targetPath,fullPath,directory,dryRun,allowCreates,allowDeletes,hunkOptions);if(fileResults.push(result),result.status==="applied"||result.status==="created")totalApplied++;else if(result.status==="error")totalFailed++}let output={success:totalFailed===0,dryRun,files:fileResults,summary:{totalFiles:fileResults.length,applied:totalApplied,failed:totalFailed,totalHunks}};if(extraFiles.length>0)return JSON.stringify({...output,warnings:[`files[] contains entries not targeted by the patch: ${extraFiles.join(", ")}`]},null,2);return JSON.stringify(output,null,2)}});init_zod();init_delegation_gate();init_create_tool();var ApprovePlanCriticArgsSchema=exports_external.object({reason:exports_external.string().trim().min(1).max(500).describe('Why a manual approval is being recorded (e.g. "critic returned APPROVED but the verdict format did not match the mechanical recorder"). Audited to .swarm/events.jsonl.')}).strict();async function executeApprovePlanCritic(args2,directory,context={}){let parsed=ApprovePlanCriticArgsSchema.safeParse(args2);if(!parsed.success)return JSON.stringify({success:!1,message:`Invalid approve_plan_critic call: ${parsed.error.issues.map((issue3)=>`${issue3.path.join(".")}: ${issue3.message}`).join("; ")}`});if(!context.sessionID?.trim())return JSON.stringify({success:!1,message:"approve_plan_critic requires an active sessionID"});try{let summary=await forceRecordPlanCriticApproval(directory,context.sessionID,{reason:parsed.data.reason,userConfirmed:!1});return JSON.stringify({success:!0,plan_id:summary.planId,recorded_at:summary.recordedAt,method:"manual_override",user_confirmed:!1,message:"Recorded a manual plan_critic_gate approval snapshot. The critic_pre_plan execution gate will now allow coder delegation. An audit event was appended to .swarm/events.jsonl."})}catch(error93){return JSON.stringify({success:!1,message:error93 instanceof Error?error93.message:String(error93)})}}var approve_plan_critic=createSwarmTool({description:'Record a MANUAL plan_critic_gate approval snapshot to unblock the ratchet-tighter critic_pre_plan execution gate when the critic already returned APPROVED but the mechanical snapshot recorder failed to persist it (verdict-format mismatch, dispatch-signal miss, or a plan.json read race — issue #2012). The snapshot carries a distinct method: "manual_override" audit marker. Architect-only: the active session must be the architect. Prefer re-running MODE: CRITIC-GATE first; use this only as an escape hatch when a legitimate APPROVED was lost. A reason is required and audited to .swarm/events.jsonl. The human-confirmed variant is /swarm approve-plan-critic.',args:{reason:ApprovePlanCriticArgsSchema.shape.reason},execute:executeApprovePlanCritic});init_zod();init_external_tool_runner();init_path_security();init_create_tool();import*as fs139 from"node:fs";import*as path249 from"node:path";var AST_GREP_TIMEOUT_MS=1e4,AST_GREP_MAX_STDOUT_BYTES=8388608,AST_GREP_MAX_STDERR_BYTES=65536,DEFAULT_MAX_RESULTS2=100,HARD_CAP_RESULTS2=1e4,MAX_PATTERN_LENGTH=20000;function splitGlobPatterns(value){return value?value.split(",").map((p)=>p.trim()).filter(Boolean):[]}function resolveAstGrepBinary(){return _internals187.resolveExecutableFromPath(["ast-grep","sg"])}function toWorkspaceRelativePath(filePath,workspace){try{let resolved=path249.resolve(workspace,filePath),realWorkspace=fs139.realpathSync(workspace),realResolved=fs139.realpathSync(resolved),relative59=path249.relative(realWorkspace,realResolved);if(!relative59||relative59.startsWith("..")||path249.isAbsolute(relative59))return null;return relative59.split(path249.sep).join("/")}catch{return null}}function parseAstGrepStream(stdout,workspace,maxResults){let matches=[],total=0;for(let line of stdout.split(`
6429
+ `):resultContent;finalContent=ensureFinalNewline(withLineEnding,originalEndsWithNewline)}if(finalContent===content)return{file:targetPath,status:"no-changes",hunks:hunksTotal,hunksApplied:hunksTotal,hunksFailed:0};if(!dryRun)atomicWriteFileSync3(fullPath,finalContent);return{file:targetPath,status:"applied",hunks:hunksTotal,hunksApplied:hunksTotal,hunksFailed:0}}function buildErrorResult(message){return{success:!1,files:[{file:"",status:"error",hunks:0,hunksApplied:0,hunksFailed:0,errors:[{hunkIndex:0,type:"context-mismatch",message}]}],summary:{totalFiles:0,applied:0,failed:1,totalHunks:0}}}function isUnsupportedPatchFormat(patchText){let trimmed=patchText.trimStart();return trimmed.startsWith("*** Begin Patch")||trimmed.startsWith("*** Update File")||trimmed.startsWith("*** Add File")||trimmed.startsWith("*** Delete File")||trimmed.startsWith("*** End Patch")}var swarmApplyPatch2=createSwarmTool({description:"Apply a unified diff patch to workspace files. Validates paths, matches context exactly, and writes atomically. Coder-scoped write tool. Use standard unified diff format (--- a/file / +++ b/file / @@ hunks). Indented patches (e.g. inside a fenced markdown/YAML block) are automatically dedented to column 0 before parsing — the diff body itself may be indented. Does NOT support *** Begin Patch / *** Update File payloads — use the native apply_patch tool for those. Accepts the payload as `patch` (canonical) or any of the aliases `patchText`, `patch_text`, `patchPayload` (#2206); the resolver picks the first non-empty one.",args:{patch:exports_external.string().optional().describe("Unified diff text to parse and apply (optional when an alias below carries the payload)"),patchText:exports_external.string().optional().describe("Alias for patch — unified diff payload; accepted because models frequently hallucinate alternative argument names (#2206)"),patch_text:exports_external.string().optional().describe("Alias for patch — unified diff payload; accepted because models frequently hallucinate alternative argument names (#2206)"),patchPayload:exports_external.string().optional().describe("Alias for patch — unified diff payload; accepted because models frequently hallucinate alternative argument names (#2206)"),files:exports_external.array(exports_external.string()).min(1).describe("Array of target file paths the patch is expected to touch. Every parsed target must appear in this list."),dryRun:exports_external.boolean().optional().default(!1).describe("Validate without writing files (default: false)"),allowCreates:exports_external.boolean().optional().default(!1).describe("Allow creating new files from patches with --- /dev/null (default: false)"),allowDeletes:exports_external.boolean().optional().default(!1).describe("Allow deleting files from patches with +++ /dev/null (default: false)")},execute:async(args2,directory)=>{if(!args2||typeof args2!=="object")return JSON.stringify(buildErrorResult("Could not parse swarm_apply_patch arguments"),null,2);let obj=args2,patchText=[obj.patch,obj.patchText,obj.patch_text,obj.patchPayload].find((value)=>typeof value==="string"&&value.length>0)??"",files=obj.files??[],dryRun=obj.dryRun??!1,allowCreates=obj.allowCreates??!1,allowDeletes=obj.allowDeletes??!1,{config:config3}=_internals186.loadPluginConfigWithMeta(directory),fuzzyMatch=config3.apply_patch?.fuzzy_match===!0,fuzzyMatchContextAware=config3.apply_patch?.fuzzy_match_context_aware===!0,hunkOptions=fuzzyMatch||fuzzyMatchContextAware?{fuzzyMatch,fuzzyMatchContextAware}:void 0;if(!existsSync124(directory))return JSON.stringify(buildErrorResult("Workspace directory does not exist"),null,2);if(files.length===0)return JSON.stringify(buildErrorResult("files array cannot be empty"),null,2);if(!patchText||patchText.trim()==="")return JSON.stringify(buildErrorResult("patch text cannot be empty"),null,2);if(isUnsupportedPatchFormat(patchText))return JSON.stringify(buildErrorResult("Unsupported patch format: *** Begin Patch / *** Update File style payloads are not supported by swarm_apply_patch. Use the native apply_patch tool for this format, or provide a standard unified diff (--- a/file / +++ b/file / @@ hunks)."),null,2);for(let filePath of files){let validationError=validatePatchTargetPath(filePath,directory);if(validationError)return JSON.stringify(buildErrorResult(validationError),null,2)}let{files:parsedFiles,error:parseError}=parseUnifiedDiff(patchText);if(parseError)return JSON.stringify(buildErrorResult(parseError),null,2);if(parsedFiles.length===0)return JSON.stringify({success:!0,dryRun,files:[],summary:{totalFiles:0,applied:0,failed:0,totalHunks:0}},null,2);let declaredFileSet=new Set(files),undeclaredTargets=[];for(let fileDiff of parsedFiles){let targetPath=fileDiff.isDelete?fileDiff.oldPath:fileDiff.newPath;if(targetPath&&targetPath!=="/dev/null"&&!declaredFileSet.has(targetPath))undeclaredTargets.push(targetPath)}if(undeclaredTargets.length>0)return JSON.stringify(buildErrorResult(`Patch targets files not in the declared files array: ${undeclaredTargets.join(", ")}`),null,2);let parsedTargetSet=new Set(parsedFiles.map((fd)=>fd.isDelete?fd.oldPath:fd.newPath).filter(Boolean)),extraFiles=files.filter((f)=>!parsedTargetSet.has(f)),fileResults=[],totalApplied=0,totalFailed=0,totalHunks=0;for(let fileDiff of parsedFiles){let targetPath=fileDiff.isDelete?fileDiff.oldPath:fileDiff.newPath,fullPath=path248.resolve(directory,targetPath);totalHunks+=fileDiff.hunks.length;let result=processFileDiff(fileDiff,targetPath,fullPath,directory,dryRun,allowCreates,allowDeletes,hunkOptions);if(fileResults.push(result),result.status==="applied"||result.status==="created")totalApplied++;else if(result.status==="error")totalFailed++}let output={success:totalFailed===0,dryRun,files:fileResults,summary:{totalFiles:fileResults.length,applied:totalApplied,failed:totalFailed,totalHunks}};if(extraFiles.length>0)return JSON.stringify({...output,warnings:[`files[] contains entries not targeted by the patch: ${extraFiles.join(", ")}`]},null,2);return JSON.stringify(output,null,2)}});init_zod();init_delegation_gate();init_create_tool();var ApprovePlanCriticArgsSchema=exports_external.object({reason:exports_external.string().trim().min(1).max(500).describe('Why a manual approval is being recorded (e.g. "critic returned APPROVED but the verdict format did not match the mechanical recorder"). Audited to .swarm/events.jsonl.')}).strict();async function executeApprovePlanCritic(args2,directory,context={}){let parsed=ApprovePlanCriticArgsSchema.safeParse(args2);if(!parsed.success)return JSON.stringify({success:!1,message:`Invalid approve_plan_critic call: ${parsed.error.issues.map((issue3)=>`${issue3.path.join(".")}: ${issue3.message}`).join("; ")}`});if(!context.sessionID?.trim())return JSON.stringify({success:!1,message:"approve_plan_critic requires an active sessionID"});try{let summary=await forceRecordPlanCriticApproval(directory,context.sessionID,{reason:parsed.data.reason,userConfirmed:!1});return JSON.stringify({success:!0,plan_id:summary.planId,recorded_at:summary.recordedAt,method:"manual_override",user_confirmed:!1,message:"Recorded a manual plan_critic_gate approval snapshot. The critic_pre_plan execution gate will now allow coder delegation. An audit event was appended to .swarm/events.jsonl."})}catch(error93){return JSON.stringify({success:!1,message:error93 instanceof Error?error93.message:String(error93)})}}var approve_plan_critic=createSwarmTool({description:'Record a MANUAL plan_critic_gate approval snapshot to unblock the ratchet-tighter critic_pre_plan execution gate when the critic already returned APPROVED but the mechanical snapshot recorder failed to persist it (verdict-format mismatch, dispatch-signal miss, or a plan.json read race — issue #2012). The snapshot carries a distinct method: "manual_override" audit marker. Architect-only: the active session must be the architect. Prefer re-running MODE: CRITIC-GATE first; use this only as an escape hatch when a legitimate APPROVED was lost. A reason is required and audited to .swarm/events.jsonl. The human-confirmed variant is /swarm approve-plan-critic.',args:{reason:ApprovePlanCriticArgsSchema.shape.reason},execute:executeApprovePlanCritic});init_zod();init_external_tool_runner();init_path_security();init_create_tool();import*as fs139 from"node:fs";import*as path249 from"node:path";var AST_GREP_TIMEOUT_MS=1e4,AST_GREP_MAX_STDOUT_BYTES=8388608,AST_GREP_MAX_STDERR_BYTES=65536,DEFAULT_MAX_RESULTS2=100,HARD_CAP_RESULTS2=1e4,MAX_PATTERN_LENGTH=20000;function splitGlobPatterns(value){return value?value.split(",").map((p)=>p.trim()).filter(Boolean):[]}function resolveAstGrepBinary(){return _internals187.resolveExecutableFromPath(["ast-grep","sg"])}function toWorkspaceRelativePath(filePath,workspace){try{let resolved=path249.resolve(workspace,filePath),realWorkspace=fs139.realpathSync(workspace),realResolved=fs139.realpathSync(resolved),relative59=path249.relative(realWorkspace,realResolved);if(!relative59||relative59.startsWith("..")||path249.isAbsolute(relative59))return null;return relative59.split(path249.sep).join("/")}catch{return null}}function parseAstGrepStream(stdout,workspace,maxResults){let matches=[],total=0;for(let line of stdout.split(`
6423
6430
  `)){if(!line.trim())continue;try{let entry=JSON.parse(line),relativePath2=typeof entry.file==="string"?toWorkspaceRelativePath(entry.file,workspace):null;if(!relativePath2)continue;if(total++,matches.length>=maxResults)continue;let start=entry.range?.start??{},end=entry.range?.end??{};matches.push({file:relativePath2,lineNumber:typeof start.line==="number"?start.line+1:1,column:typeof start.column==="number"?start.column+1:1,endLineNumber:typeof end.line==="number"?end.line+1:1,endColumn:typeof end.column==="number"?end.column+1:1,text:typeof entry.text==="string"?entry.text:"",lines:typeof entry.lines==="string"?entry.lines.trimEnd():"",language:typeof entry.language==="string"?entry.language:void 0,metaVariables:entry.metaVariables&&typeof entry.metaVariables==="object"?entry.metaVariables:void 0})}catch{}}return{matches,total}}function validateGlobArg(kind,value){if(!value)return null;if(containsControlChars(value))return{error:!0,type:"path-escape",message:`${kind} pattern contains invalid control characters`};if(containsPathTraversal(value))return{error:!0,type:"path-escape",message:`${kind} pattern contains path traversal sequence`};return null}var ast_grep=createSwarmTool({description:"Read-only structural AST search using ast-grep. Searches code patterns with optional language and glob filters; does not rewrite files.",args:{pattern:exports_external.string().describe("ast-grep pattern to search for"),language:exports_external.string().optional().describe("Optional ast-grep language, e.g. ts, tsx, js, py, rust"),include:exports_external.string().optional().describe("Comma-separated include globs, passed to ast-grep --globs"),exclude:exports_external.string().optional().describe("Comma-separated exclude globs, passed to ast-grep as !glob"),max_results:exports_external.number().default(DEFAULT_MAX_RESULTS2).describe("Maximum number of matches to return")},execute:async(args2,directory)=>{let pattern,language,include,exclude,maxResults=DEFAULT_MAX_RESULTS2;try{let obj=args2;pattern=typeof obj.pattern==="string"?obj.pattern:"",language=typeof obj.language==="string"?obj.language:void 0,include=typeof obj.include==="string"?obj.include:void 0,exclude=typeof obj.exclude==="string"?obj.exclude:void 0;let rawMaxResults=typeof obj.max_results==="number"?obj.max_results:DEFAULT_MAX_RESULTS2,sanitizedMaxResults=Number.isFinite(rawMaxResults)?rawMaxResults:DEFAULT_MAX_RESULTS2;maxResults=Math.min(Math.max(0,sanitizedMaxResults),HARD_CAP_RESULTS2)}catch{return JSON.stringify({error:!0,type:"invalid-pattern",message:"Could not parse ast_grep arguments"},null,2)}if(!pattern||pattern.trim()==="")return JSON.stringify({error:!0,type:"invalid-pattern",message:"Pattern cannot be empty"},null,2);if(pattern.length>MAX_PATTERN_LENGTH||containsControlChars(pattern))return JSON.stringify({error:!0,type:"invalid-pattern",message:`Pattern is invalid or exceeds ${MAX_PATTERN_LENGTH} characters`},null,2);if(language&&!/^[A-Za-z0-9_-]+$/.test(language))return JSON.stringify({error:!0,type:"invalid-pattern",message:"Language must contain only letters, numbers, _ or -"},null,2);let includeError=validateGlobArg("Include",include);if(includeError)return JSON.stringify(includeError,null,2);let excludeError=validateGlobArg("Exclude",exclude);if(excludeError)return JSON.stringify(excludeError,null,2);if(!fs139.existsSync(directory))return JSON.stringify({error:!0,type:"unknown",message:"Workspace directory does not exist"},null,2);let executable=_internals187.resolveAstGrepBinary();if(!executable)return JSON.stringify({error:!0,type:"ast-grep-not-found",message:"ast-grep executable not found. Install ast-grep and ensure ast-grep or sg is on PATH."},null,2);let sgArgs=["run","--pattern",pattern,"--json=stream","--color","never"];if(language)sgArgs.push("--lang",language);for(let glob of splitGlobPatterns(include))sgArgs.push("--globs",glob);for(let glob of splitGlobPatterns(exclude))sgArgs.push("--globs",`!${glob}`);sgArgs.push(".");let run=await _internals187.runExternalTool({executable,args:sgArgs,cwd:directory,timeoutMs:AST_GREP_TIMEOUT_MS,maxStdoutBytes:AST_GREP_MAX_STDOUT_BYTES,maxStderrBytes:AST_GREP_MAX_STDERR_BYTES});if(run.status==="timeout")return JSON.stringify({error:!0,type:"timeout",message:`ast-grep timed out after ${AST_GREP_TIMEOUT_MS}ms`},null,2);if(run.status==="spawn-error")return JSON.stringify({error:!0,type:"unknown",message:run.message??"ast-grep failed to start"},null,2);if(run.exitCode!==0&&run.stderr)return JSON.stringify({error:!0,type:"invalid-pattern",message:run.stderr.split(`
6424
6431
  `)[0]},null,2);let{matches,total}=parseAstGrepStream(run.stdout,directory,maxResults);return JSON.stringify({matches,truncated:total>maxResults||run.stdoutTruncated||run.stderrTruncated,total,pattern,language,maxResults,outputTruncated:run.stdoutTruncated||run.stderrTruncated},null,2)}}),_internals187={resolveExecutableFromPath,resolveAstGrepBinary,runExternalTool,parseAstGrepStream};init_dist();init_create_tool();import*as fs140 from"node:fs";import*as path250 from"node:path";init_path_security();var WINDOWS_RESERVED_NAMES4=/^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;function containsWindowsAttacks3(str){if(/:[^\\/]/.test(str))return!0;let parts=str.split(/[/\\]/);for(let part of parts)if(WINDOWS_RESERVED_NAMES4.test(part))return!0;return!1}function isPathInWorkspace2(filePath,workspace){try{let resolvedPath=path250.resolve(workspace,filePath);if(!fs140.existsSync(resolvedPath))return!0;let realWorkspace=fs140.realpathSync(workspace),realResolvedPath=fs140.realpathSync(resolvedPath),relativePath2=path250.relative(realWorkspace,realResolvedPath);if(relativePath2.startsWith("..")||path250.isAbsolute(relativePath2))return!1;return!0}catch{return!1}}function processFile(file3,cwd,exportedOnly){let ext=path250.extname(file3);if(containsControlChars(file3))return{file:file3,success:!1,error:"Path contains invalid control characters",errorType:"invalid-path"};if(containsPathTraversal(file3))return{file:file3,success:!1,error:"Path contains path traversal sequence",errorType:"path-traversal"};if(containsWindowsAttacks3(file3))return{file:file3,success:!1,error:"Path contains invalid Windows-specific sequence",errorType:"invalid-path"};if(!isPathInWorkspace2(file3,cwd))return{file:file3,success:!1,error:"Path is outside workspace",errorType:"path-outside-workspace"};let fullPath=path250.join(cwd,file3);if(!fs140.existsSync(fullPath))return{file:file3,success:!1,error:`File not found: ${file3}`,errorType:"file-not-found"};let syms;switch(ext){case".ts":case".tsx":case".js":case".jsx":case".mjs":case".cjs":syms=extractTSSymbols(file3,cwd);break;case".py":case".pyw":syms=extractPythonSymbols(file3,cwd);break;case".rs":syms=extractRustSymbols(file3,cwd);break;case".go":syms=extractGoSymbols(file3,cwd);break;default:return{file:file3,success:!1,error:`Unsupported file extension: ${ext}. Supported: .ts, .tsx, .js, .jsx, .mjs, .cjs, .py, .pyw, .rs, .go`,errorType:"unsupported-language"}}let isEmptyFile=!1;try{if(fs140.statSync(fullPath).size===0)isEmptyFile=!0}catch{}if(syms.length===0)try{if(fs140.readFileSync(fullPath,"utf-8").trim().length===0)isEmptyFile=!0}catch{}if(isEmptyFile)return{file:file3,success:!0,symbols:[],error:"empty-file",errorType:"empty-file"};if(exportedOnly)syms=syms.filter((s)=>s.exported);return{file:file3,success:!0,symbols:syms}}var batch_symbols=createSwarmTool({description:"Extract symbols from multiple files in a single batch call. Accepts an array of file paths and returns per-file symbol summaries. One bad file does not crash the batch. Use for surveying a module when you need symbol information from multiple files at once.",args:{files:tool.schema.array(tool.schema.string()).describe("Array of file paths to extract symbols from"),exported_only:tool.schema.boolean().default(!0).describe("If true, only return exported/public symbols. If false, include all top-level symbols.")},execute:async(args2,directory)=>{let files,exportedOnly=!0;try{let obj=args2;if(!Array.isArray(obj.files))return JSON.stringify({results:[],totalFiles:0,successCount:0,failureCount:0,error:"Invalid arguments: files must be an array"},null,2);files=obj.files.map((f)=>String(f)),exportedOnly=obj.exported_only!==!1}catch{return JSON.stringify({results:[],totalFiles:0,successCount:0,failureCount:0,error:"Invalid arguments: could not extract files array"},null,2)}let cwd=directory,results=[];for(let file3 of files){let result=processFile(file3,cwd,exportedOnly);results.push(result)}let successCount=results.filter((r)=>r.success).length,failureCount=results.filter((r)=>!r.success).length,batchResult={results,totalFiles:files.length,successCount,failureCount};return JSON.stringify(batchResult,null,2)}});init_zod();init_discovery();init_manager2();init_bun_compat();init_logger();init_create_tool();var DEFAULT_TIMEOUT_MS4=300000,MAX_OUTPUT_BYTES6=10240,MAX_OUTPUT_LINES=100;function truncateOutput(output,maxLines=MAX_OUTPUT_LINES,maxBytes=MAX_OUTPUT_BYTES6){if(!output)return"";let truncated=output;if(truncated.length>maxBytes)truncated=truncated.slice(-maxBytes);let lines=truncated.split(`
6425
6432
  `);if(lines.length>maxLines)return lines.slice(-maxLines).join(`
6426
6433
  `);return truncated}function getCommandKind(command){let lower=command.toLowerCase();if(lower.includes("typecheck")||lower.includes("check")||lower.includes("analyze")||lower.includes("lint"))return"typecheck";if(lower.includes("test")||lower.includes("spec")||lower.includes("jest")||lower.includes("vitest")||lower.includes("mocha")||lower.includes("pytest"))return"test";return"build"}function filterByMode(commands,mode){if(mode==="both")return commands;return commands.filter((cmd)=>getCommandKind(cmd.command)===mode)}async function executeCommand(command){let startTime=Date.now(),kind=getCommandKind(command.command),isWindows=process.platform==="win32",cmd,args2;if(isWindows&&!command.command.includes(" "))cmd=[command.command],args2=[];else if(isWindows)cmd=["cmd","/c",command.command],args2=[];else cmd=["/bin/sh"],args2=["-c",command.command];let result=bunSpawn([...cmd,...args2],{cwd:command.cwd,stdout:"pipe",stderr:"pipe",timeout:DEFAULT_TIMEOUT_MS4}),[exitCode,stdout,stderr]=await Promise.all([result.exited,result.stdout.text(),result.stderr.text()]),duration_ms=Date.now()-startTime;return{kind,command:command.command,cwd:command.cwd,exit_code:exitCode??-1,duration_ms,stdout_tail:truncateOutput(stdout),stderr_tail:truncateOutput(stderr)}}async function runBuildCheck(workingDir,input){let scope=input.scope??"all",mode=input.mode??"both",changedFiles=input.changed_files??[],discoveryResult=await discoverBuildCommands(workingDir,{scope,changedFiles}),commands=filterByMode(discoveryResult.commands,mode),runs=[],failedCount=0;for(let cmd of commands)try{let run=await executeCommand(cmd);if(runs.push(run),run.exit_code!==0)failedCount++}catch(error93){runs.push({kind:getCommandKind(cmd.command),command:cmd.command,cwd:cmd.cwd,exit_code:-1,duration_ms:0,stdout_tail:"",stderr_tail:error93 instanceof Error?error93.message:"Unknown error"}),failedCount++}let verdict,skipped_reason;if(runs.length===0)if(verdict="info",discoveryResult.skipped.length>0)skipped_reason=discoveryResult.skipped.map((s)=>`${s.ecosystem}: ${s.reason}`).join("; ");else skipped_reason="No build commands discovered (no toolchains found)";else if(failedCount>0)verdict="fail";else verdict="pass";return{verdict,runs,summary:{files_scanned:changedFiles.length,runs_count:runs.length,failed_count:failedCount,skipped_reason}}}var build_check=createSwarmTool({allowWorkingDirectoryOverride:!0,description:"Discover and run build commands for various ecosystems in a project directory. Supports build, typecheck, and test commands.",args:{scope:exports_external.enum(["changed","all"]).describe('Scope of detection: "all" for all build files, "changed" for only changed files'),changed_files:exports_external.array(exports_external.string()).optional().describe('List of changed files when scope is "changed"'),mode:exports_external.enum(["build","typecheck","both"]).optional().describe('Mode: "build" for build commands, "typecheck" for type checking, "both" for all (default: both)')},async execute(args2,directory){let obj=args2,scope=obj.scope??"all",changedFiles=obj.changed_files??[],mode=obj.mode??"both",workingDir=directory,result=await runBuildCheck(workingDir,{scope,changed_files:changedFiles,mode}),evidence2={task_id:"build",type:"build",timestamp:new Date().toISOString(),agent:"build_check",verdict:result.verdict,summary:`${result.runs.length} build command(s) executed, ${result.summary.failed_count} failed`,runs:result.runs,files_scanned:result.summary.files_scanned,runs_count:result.summary.runs_count,failed_count:result.summary.failed_count,skipped_reason:result.summary.skipped_reason};try{await saveEvidence(workingDir,"build",evidence2)}catch(error93){log("Failed to save build evidence:",error93 instanceof Error?error93.message:String(error93))}return JSON.stringify(result,null,2)}});init_zod();init_manager2();init_task_id();init_create_tool();init_resolve_working_directory();import*as fs141 from"node:fs";import*as path251 from"node:path";var EVIDENCE_DIR=".swarm/evidence";function isValidTaskId4(taskId){return isStrictTaskId2(taskId)}function isPathWithinSwarm(filePath,workspaceRoot){let normalizedWorkspace=path251.resolve(workspaceRoot),swarmPath3=path251.join(normalizedWorkspace,".swarm","evidence");return path251.resolve(filePath).startsWith(swarmPath3)}function readEvidenceFile(evidencePath){if(!fs141.existsSync(evidencePath))return null;let content;try{content=fs141.readFileSync(evidencePath,"utf-8")}catch{return null}let parsed;try{parsed=JSON.parse(content)}catch{return null}if(parsed&&typeof parsed==="object"&&Array.isArray(parsed.required_gates)&&typeof parsed.gates==="object"&&parsed.gates!==null)return parsed;return null}var check_gate_status=createSwarmTool({description:"Read-only tool to check the gate status of a specific task. Reads .swarm/evidence/{taskId}.json and returns structured JSON describing required, passed, and missing gates.",args:{task_id:exports_external.string().min(1).regex(/^\d+\.\d+(\.\d+)*$/,'Task ID must be in N.M or N.M.P format (e.g., "1.1", "1.2.3", "1.2.3.4")').describe('The task ID to check gate status for (e.g., "1.1", "2.3.1")'),working_directory:exports_external.string().optional().describe("Explicit project root directory. When provided, .swarm/evidence/ is resolved relative to this path instead of the plugin context directory. Use this when CWD differs from the actual project root.")},async execute(args2,directory){let taskIdInput,workingDirInput;try{if(args2&&typeof args2==="object"){let obj=args2;taskIdInput=typeof obj.task_id==="string"?obj.task_id:void 0,workingDirInput=typeof obj.working_directory==="string"?obj.working_directory:void 0}}catch{}let dirResult=resolveWorkingDirectory(workingDirInput,directory);if(!dirResult.success){let errorResult={taskId:taskIdInput??"",status:"no_evidence",required_gates:[],passed_gates:[],missing_gates:[],gates:{},message:dirResult.message,todo_scan:null};return JSON.stringify(errorResult,null,2)}if(directory=dirResult.directory,!taskIdInput)return JSON.stringify({taskId:"",status:"no_evidence",required_gates:[],passed_gates:[],missing_gates:[],gates:{},message:"Invalid task_id: task_id is required",todo_scan:null},null,2);if(!isValidTaskId4(taskIdInput)){let errorResult={taskId:taskIdInput,status:"no_evidence",required_gates:[],passed_gates:[],missing_gates:[],gates:{},message:`Invalid task_id format: "${taskIdInput}". Must match N.M or N.M.P (e.g. "1.1", "1.2.3", "1.2.3.4")`,todo_scan:null};return JSON.stringify(errorResult,null,2)}let evidencePath=path251.join(directory,EVIDENCE_DIR,`${taskIdInput}.json`);if(!isPathWithinSwarm(evidencePath,directory))return JSON.stringify({taskId:taskIdInput,status:"no_evidence",required_gates:[],passed_gates:[],missing_gates:[],gates:{},message:"Invalid path: evidence path validation failed",todo_scan:null},null,2);let evidenceData=readEvidenceFile(evidencePath);if(!evidenceData){let errorResult={taskId:taskIdInput,status:"no_evidence",required_gates:[],passed_gates:[],missing_gates:[],gates:{},message:`No evidence file found for task "${taskIdInput}" at ${evidencePath}. Evidence file may be missing or invalid.`,todo_scan:null};return JSON.stringify(errorResult,null,2)}let requiredGates=evidenceData.required_gates||[],gatesMap=evidenceData.gates||{},passedGates=[],missingGates=[];for(let requiredGate of requiredGates)if(gatesMap[requiredGate])passedGates.push(requiredGate);else missingGates.push(requiredGate);let status=missingGates.length===0?"all_passed":"incomplete",message;if(status==="all_passed")message=`All required gates have passed for task "${taskIdInput}".`;else message=`Task "${taskIdInput}" is incomplete. Missing gates: ${missingGates.join(", ")}.`;let secretscanVerdict="not_run";try{let evidenceResult=await loadEvidence(directory,taskIdInput);if(evidenceResult.status==="found"){let secretscanEntries=evidenceResult.bundle.entries.filter((entry)=>entry.type==="secretscan");if(secretscanEntries.length>0){let lastSecretscan=secretscanEntries[secretscanEntries.length-1];if(isSecretscanEvidence(lastSecretscan)){let{incomplete_files:incompleteFiles,incomplete_paths:incompletePaths}=lastSecretscan,findingsCount=lastSecretscan.findings_count??0,hasIncompleteCoverage=incompleteFiles>0||incompletePaths.length>0,hasFindings=findingsCount>0,hasZeroCoverage=lastSecretscan.files_scanned===0;if(hasIncompleteCoverage||hasFindings||hasZeroCoverage||lastSecretscan.verdict==="fail"||lastSecretscan.verdict==="rejected")if(secretscanVerdict="fail",hasIncompleteCoverage&&!hasFindings){if(missingGates.push("secretscan (BLOCKED — incomplete coverage)"),status==="all_passed")status="incomplete";message=`BLOCKED: Secretscan incomplete coverage in prior scan. ${message}`}else if(hasFindings&&hasIncompleteCoverage){if(missingGates.push("secretscan (BLOCKED — secrets detected; incomplete coverage)"),status==="all_passed")status="incomplete";message=`BLOCKED: Secretscan found secrets and incomplete coverage in prior scan. ${message}`}else if(hasFindings){if(missingGates.push("secretscan (BLOCKED — secrets detected)"),status==="all_passed")status="incomplete";message=`BLOCKED: Secretscan found secrets in prior scan. ${message}`}else{if(missingGates.push("secretscan (BLOCKED — zero coverage)"),status==="all_passed")status="incomplete";message=`BLOCKED: Secretscan scanned zero files in prior scan. ${message}`}else if(lastSecretscan.verdict==="pass"||lastSecretscan.verdict==="approved"||lastSecretscan.verdict==="info")secretscanVerdict="pass"}}else message+=" Advisory: No secretscan evidence found for this task. Consider running secretscan."}else if(evidenceResult.status==="invalid_schema")secretscanVerdict="fail",missingGates.push("secretscan (BLOCKED — invalid evidence)"),status="incomplete",message=`BLOCKED: Secretscan evidence is invalid and cannot prove complete coverage. ${message}`}catch{}let todoScan=evidenceData.todo_scan;return JSON.stringify({taskId:taskIdInput,status,required_gates:requiredGates,passed_gates:passedGates,missing_gates:missingGates,gates:gatesMap,message,todo_scan:todoScan??null,secretscan_verdict:secretscanVerdict},null,2)}});init_checkpoint();init_co_change_analyzer();init_zod();init_pr_workflow_gate();init_create_tool();var CompletePrWorkflowArgsSchema=exports_external.object({mode:exports_external.enum(["PR_REVIEW","PR_FEEDBACK"]),pr_head_sha:exports_external.string().trim().min(1).max(80)}).strict();async function executeCompletePrWorkflow(args2,directory,context={}){let parsed=CompletePrWorkflowArgsSchema.safeParse(args2);if(!parsed.success)return JSON.stringify({success:!1,message:`Invalid PR workflow completion: ${parsed.error.issues.map((issue3)=>`${issue3.path.join(".")}: ${issue3.message}`).join("; ")}`});if(!context.sessionID?.trim())return JSON.stringify({success:!1,message:"PR workflow completion requires an active sessionID"});try{let status=await _internals188.completePrWorkflow(directory,context.sessionID,parsed.data.mode,parsed.data.pr_head_sha),checkoutRestoreRequired=!1,checkoutRestoreReceipts=[];if(status==="completed")try{checkoutRestoreReceipts=await _internals188.listPendingPrWorkflowCheckoutRestores(directory,context.sessionID),checkoutRestoreRequired=checkoutRestoreReceipts.length>0}catch{checkoutRestoreRequired=!0}return JSON.stringify({success:!0,mode:parsed.data.mode,pr_head_sha:parsed.data.pr_head_sha,status,ready_to_publish:status==="ready-to-publish",verified_no_change:status==="verified-no-change",gate_cleared:status==="completed"||status==="verified-no-change",checkout_restore_required:checkoutRestoreRequired,checkout_restore_receipts:checkoutRestoreReceipts})}catch(error93){return JSON.stringify({success:!1,message:error93 instanceof Error?error93.message:String(error93)})}}var complete_pr_workflow=createSwarmTool({description:"Validate terminal PR workflow coverage. After the ordered PR_FEEDBACK gates permit one standalone commit, the first call requires a clean tree and a non-merge direct child of intake HEAD, then binds its structured upstream target; the second clears only after both the local tracking ref and an actual-remote query point to that exact commit. A cleared result reports checkout_restore_required when preserved pre-workflow changes must be restored.",args:{mode:CompletePrWorkflowArgsSchema.shape.mode,pr_head_sha:CompletePrWorkflowArgsSchema.shape.pr_head_sha},execute:executeCompletePrWorkflow}),_internals188={completePrWorkflow,listPendingPrWorkflowCheckoutRestores};init_zod();init_utils2();init_state2();init_swarm_artifact_cache();init_create_tool();init_resolve_working_directory();import*as fs142 from"node:fs";import*as path252 from"node:path";function extractMatches(regex,text){return Array.from(text.matchAll(regex))}function parseIdentifiers(description){let identifiers=new Set,backtickRegex=/`([^`]+)`/g;for(let match of extractMatches(backtickRegex,description))identifiers.add(match[1]);let camelCaseRegex=/\b([a-z][a-zA-Z0-9]{2,})\b/g;for(let match of extractMatches(camelCaseRegex,description)){let word=match[1];if(word==="the"||word==="and"||word==="for"||word==="have"||word==="this"||word==="with"||word==="from"||word==="they"||word==="been"||word==="will"||word==="your"||word==="also")continue;identifiers.add(word)}let pascalCaseRegex=/\b([A-Z][a-zA-Z0-9]{2,})\b/g;for(let match of extractMatches(pascalCaseRegex,description))identifiers.add(match[1]);let configKeyRegex=/\b([a-z][a-zA-Z0-9]*(?:\.[a-z][a-zA-Z0-9]*)+)\b/g;for(let match of extractMatches(configKeyRegex,description))identifiers.add(match[1]);let quotedPathRegex=/['"](\.{0,3}(?:src|lib|test)[/\\][^'"]+)['"]/g;for(let match of extractMatches(quotedPathRegex,description))identifiers.add(match[1]);return Array.from(identifiers)}function parseFilePaths(description,filesTouched){if(filesTouched&&Array.isArray(filesTouched)&&filesTouched.length>0)return filesTouched;let filePaths=[],srcPathRegex=/\b(?:src|lib|test|app|packages?)[/\\][a-zA-Z0-9_./-]+\.(?:ts|tsx|js|jsx|mjs|cjs)\b/g;for(let match of extractMatches(srcPathRegex,description))filePaths.push(match[0]);let genericPathRegex=/\b[a-zA-Z0-9_./-]+[/\\][a-zA-Z0-9_./-]+\.[a-zA-Z0-9]+(?=\s|$|[.,;])/g;for(let match of extractMatches(genericPathRegex,description)){let pathStr=match[0];if(pathStr.includes("src/")||pathStr.includes("src\\")||pathStr.includes("lib/")||pathStr.includes("lib\\")||pathStr.includes("test/")||pathStr.includes("test\\"))filePaths.push(pathStr)}return filePaths}function buildVerifySummary(tasksChecked,tasksSkipped,tasksBlocked){if(tasksBlocked>0)return`Blocked: ${tasksBlocked} task(s) with missing identifiers`;let verified=tasksChecked-tasksSkipped;if(tasksSkipped===tasksChecked)return`All ${tasksChecked} completed task(s) skipped — research/inventory tasks`;if(tasksSkipped>0)return`${verified} task(s) verified, ${tasksSkipped} skipped (research tasks)`;return`All ${tasksChecked} completed tasks verified successfully`}async function executeCompletionVerify(args2,directory){let phase=Number(args2.phase);if(Number.isNaN(phase)||phase<1||!Number.isFinite(phase))return JSON.stringify({success:!1,phase,status:"blocked",reason:"Invalid phase number",tasksChecked:0,tasksSkipped:0,tasksBlocked:0,blockedTasks:[]},null,2);if(hasActiveTurboMode(args2.sessionID))return JSON.stringify({success:!0,phase,status:"passed",reason:"Turbo Mode active — completion verification bypassed",tasksChecked:0,tasksSkipped:0,tasksBlocked:0,blockedTasks:[]},null,2);let plan;try{let planPath=validateSwarmPath(directory,"plan.json"),planRaw=fs142.readFileSync(planPath,"utf-8");plan=JSON.parse(planRaw)}catch{return JSON.stringify({success:!0,phase,status:"passed",reason:"Cannot verify without plan.json",tasksChecked:0,tasksSkipped:0,tasksBlocked:0,blockedTasks:[]},null,2)}let targetPhase=plan.phases.find((p)=>p.id===phase);if(!targetPhase){let result2={success:!1,phase,status:"blocked",reason:`Phase ${phase} not found in plan.json`,tasksChecked:0,tasksSkipped:0,tasksBlocked:0,blockedTasks:[]};return JSON.stringify(result2,null,2)}let tasksChecked=0,tasksSkipped=0,tasksBlocked=0,blockedTasks=[];for(let task2 of targetPhase.tasks){if(task2.status!=="completed")continue;tasksChecked++;let fileTargets=parseFilePaths(task2.description,task2.files_touched),identifiers=parseIdentifiers(task2.description);if(fileTargets.length===0){tasksSkipped++;continue}if(identifiers.length===0){blockedTasks.push({task_id:task2.id,identifier:"",file_path:"",reason:"No identifiers — cannot verify completion without identifiers"}),tasksBlocked++;continue}let foundIdentifiers=new Set,hasFileReadFailure=!1;for(let filePath of fileTargets){let normalizedPath2=filePath.replace(/\\/g,"/"),resolvedPath=path252.resolve(directory,normalizedPath2),projectRoot=path252.resolve(directory),relative61=path252.relative(projectRoot,resolvedPath);if(!(relative61===""||!relative61.startsWith("..")&&!path252.isAbsolute(relative61))){blockedTasks.push({task_id:task2.id,identifier:"",file_path:filePath,reason:`File path '${filePath}' escapes the project directory — cannot verify completion`}),hasFileReadFailure=!0;continue}let fileContent;try{fileContent=fs142.readFileSync(resolvedPath,"utf-8")}catch{blockedTasks.push({task_id:task2.id,identifier:"",file_path:filePath,reason:`File '${filePath}' not found — cannot verify completion`}),hasFileReadFailure=!0;continue}for(let identifier of identifiers)if(fileContent.includes(identifier))foundIdentifiers.add(identifier)}let foundCount=foundIdentifiers.size;if(hasFileReadFailure||foundCount===0){if(!hasFileReadFailure)blockedTasks.push({task_id:task2.id,identifier:"",file_path:"",reason:"No identifiers found in target files"});tasksBlocked++}}let now2=new Date().toISOString(),result={success:tasksBlocked===0,phase,status:tasksBlocked===0?"passed":"blocked",reason:tasksBlocked>0?`COMPLETION_INCOMPLETE: ${tasksBlocked} task(s) blocked — missing identifiers or target files`:void 0,tasksChecked,tasksSkipped,tasksBlocked,blockedTasks};try{let evidenceDir=path252.join(directory,".swarm","evidence",`${phase}`),evidencePath=path252.join(evidenceDir,"completion-verify.json");fs142.mkdirSync(evidenceDir,{recursive:!0});let evidenceBundle={schema_version:"1.0.0",task_id:"completion-verify",created_at:now2,entries:[{task_id:"completion-verify",type:"completion_verify",timestamp:now2,agent:"completion_verify",verdict:tasksBlocked===0?"pass":"fail",summary:buildVerifySummary(tasksChecked,tasksSkipped,tasksBlocked),phase,tasks_checked:tasksChecked,tasks_skipped:tasksSkipped,tasks_blocked:tasksBlocked,blocked_tasks:blockedTasks}]};fs142.writeFileSync(evidencePath,JSON.stringify(evidenceBundle,null,2),"utf-8"),invalidateCachedArtifact(evidencePath)}catch{}return JSON.stringify(result,null,2)}var completion_verify=createSwarmTool({description:"Deterministic pre-check verifying that plan task identifiers exist in their target source files before phase completion. Blocks if obviously incomplete.",args:{phase:exports_external.number().describe("The phase number to check"),sessionID:exports_external.string().optional().describe("Session ID for tracking state (auto-provided by plugin context)"),working_directory:exports_external.string().optional().describe("Explicit project root directory. When provided, .swarm/ is resolved relative to this path instead of the plugin context directory. Use this when CWD differs from the actual project root.")},execute:async(args2,directory)=>{let parsedArgs;try{if(args2&&typeof args2==="object"){let obj=args2;parsedArgs={phase:typeof obj.phase==="number"?obj.phase:typeof obj.phase==="string"?Number(obj.phase):0,sessionID:typeof obj.sessionID==="string"?obj.sessionID:void 0,working_directory:typeof obj.working_directory==="string"?obj.working_directory:void 0}}else parsedArgs={phase:0}}catch{return JSON.stringify({success:!1,phase:0,status:"blocked",reason:"Invalid arguments",tasksChecked:0,tasksSkipped:0,tasksBlocked:0,blockedTasks:[]},null,2)}let dirResult=resolveWorkingDirectory(parsedArgs.working_directory,directory);if(!dirResult.success)return JSON.stringify({success:!1,phase:parsedArgs.phase,status:"blocked",reason:dirResult.message,tasksChecked:0,tasksSkipped:0,tasksBlocked:0,blockedTasks:[]},null,2);return executeCompletionVerify(parsedArgs,dirResult.directory)}});init_zod();init_metrics();init_bun_compat();init_create_tool();init_path_security();import*as fs143 from"node:fs";import*as path253 from"node:path";var MAX_FILE_SIZE_BYTES5=262144,DEFAULT_DAYS=90,DEFAULT_TOP_N2=20,DEFAULT_EXTENSIONS="ts,tsx,js,jsx,py,rs,ps1",SHELL_METACHAR_REGEX=/[;&|%$`\\]/;function validateDays(days){if(typeof days>"u")return{valid:!0,value:DEFAULT_DAYS,error:null};if(typeof days!=="number"||!Number.isInteger(days))return{valid:!1,value:0,error:"days must be an integer"};if(days<1||days>365)return{valid:!1,value:0,error:"days must be between 1 and 365"};return{valid:!0,value:days,error:null}}function validateTopN(topN){if(typeof topN>"u")return{valid:!0,value:DEFAULT_TOP_N2,error:null};if(typeof topN!=="number"||!Number.isInteger(topN))return{valid:!1,value:0,error:"top_n must be an integer"};if(topN<1||topN>100)return{valid:!1,value:0,error:"top_n must be between 1 and 100"};return{valid:!0,value:topN,error:null}}function validateExtensions(extensions){if(typeof extensions>"u")return{valid:!0,value:DEFAULT_EXTENSIONS,error:null};if(typeof extensions!=="string")return{valid:!1,value:"",error:"extensions must be a string"};if(containsControlChars(extensions))return{valid:!1,value:"",error:"extensions contains control characters"};if(SHELL_METACHAR_REGEX.test(extensions))return{valid:!1,value:"",error:"extensions contains shell metacharacters (;|&%$`\\)"};if(!/^[a-zA-Z0-9,.]+$/.test(extensions))return{valid:!1,value:"",error:"extensions contains invalid characters (only alphanumeric, commas, dots allowed)"};return{valid:!0,value:extensions,error:null}}async function getGitChurn(days,directory){let churnMap=new Map,proc=bunSpawn(["git","log",`--since=${days} days ago`,"--name-only","--pretty=format:"],{stdout:"pipe",stderr:"pipe",cwd:directory}),[stdout]=await Promise.all([proc.stdout.text(),proc.exited]),lines=stdout.split(/\r?\n/);for(let line of lines){let normalizedPath2=line.replace(/\\/g,"/");if(!normalizedPath2||normalizedPath2.trim()==="")continue;if(normalizedPath2.includes("node_modules")||normalizedPath2.includes("/.git/")||normalizedPath2.includes("/dist/")||normalizedPath2.includes("/build/")||normalizedPath2.includes("__tests__"))continue;if(normalizedPath2.includes(".test.")||normalizedPath2.includes(".spec."))continue;churnMap.set(normalizedPath2,(churnMap.get(normalizedPath2)||0)+1)}return churnMap}function getComplexityForFile2(filePath){try{if(fs143.statSync(filePath).size>MAX_FILE_SIZE_BYTES5)return null;let content=fs143.readFileSync(filePath,"utf-8");return estimateCyclomaticComplexity(content)}catch{return null}}async function analyzeHotspots(days,topN,extensions,directory){let churnMap=await getGitChurn(days,directory),extSet=new Set(extensions.map((e)=>e.startsWith(".")?e:`.${e}`)),filteredChurn=new Map;for(let[file3,count]of churnMap){let ext=path253.extname(file3).toLowerCase();if(extSet.has(ext))filteredChurn.set(file3,count)}let hotspots=[],cwd=directory,analyzedFiles=0;for(let[file3,churnCount]of filteredChurn){let fullPath=file3;if(!fs143.existsSync(fullPath))fullPath=path253.join(cwd,file3);let complexity=getComplexityForFile2(fullPath);if(complexity!==null){analyzedFiles++;let riskScore=Math.round(churnCount*Math.log2(Math.max(complexity,1))*10)/10,recommendation;if(riskScore>=50)recommendation="full_gates";else if(riskScore>=30)recommendation="security_review";else if(riskScore>=15)recommendation="enhanced_review";else recommendation="standard";hotspots.push({file:file3,churnCount,complexity,riskScore,recommendation})}}hotspots.sort((a,b)=>b.riskScore-a.riskScore);let topHotspots=hotspots.slice(0,topN),summary={fullGates:topHotspots.filter((h)=>h.recommendation==="full_gates").length,securityReview:topHotspots.filter((h)=>h.recommendation==="security_review").length,enhancedReview:topHotspots.filter((h)=>h.recommendation==="enhanced_review").length,standard:topHotspots.filter((h)=>h.recommendation==="standard").length};return{analyzedFiles,period:`${days} days`,hotspots:topHotspots,summary}}var complexity_hotspots=createSwarmTool({description:"Identify high-risk code hotspots by combining git churn frequency with cyclomatic complexity estimates. Returns files with their churn count, complexity score, risk score, and recommended review level.",args:{days:exports_external.number().optional().describe("Number of days of git history to analyze (default: 90, valid range: 1-365)"),top_n:exports_external.number().optional().describe("Number of top hotspots to return (default: 20, valid range: 1-100)"),extensions:exports_external.string().optional().describe('Comma-separated extensions to include (default: "ts,tsx,js,jsx,py,rs,ps1")')},async execute(args2,directory){if(!directory||typeof directory!=="string"||directory.trim()==="")return JSON.stringify({error:"project directory is required but was not provided",analyzedFiles:0,period:"0 days",hotspots:[],summary:{fullGates:0,securityReview:0,enhancedReview:0,standard:0}},null,2);let daysInput,topNInput,extensionsInput;try{if(args2&&typeof args2==="object"){let obj=args2;daysInput=typeof obj.days==="number"?obj.days:void 0,topNInput=typeof obj.top_n==="number"?obj.top_n:void 0,extensionsInput=typeof obj.extensions==="string"?obj.extensions:void 0}}catch{}let daysValidation=validateDays(daysInput);if(!daysValidation.valid){let errorResult={error:`invalid days: ${daysValidation.error}`,analyzedFiles:0,period:"0 days",hotspots:[],summary:{fullGates:0,securityReview:0,enhancedReview:0,standard:0}};return JSON.stringify(errorResult,null,2)}let topNValidation=validateTopN(topNInput);if(!topNValidation.valid){let errorResult={error:`invalid top_n: ${topNValidation.error}`,analyzedFiles:0,period:"0 days",hotspots:[],summary:{fullGates:0,securityReview:0,enhancedReview:0,standard:0}};return JSON.stringify(errorResult,null,2)}let extensionsValidation=validateExtensions(extensionsInput);if(!extensionsValidation.valid){let errorResult={error:`invalid extensions: ${extensionsValidation.error}`,analyzedFiles:0,period:"0 days",hotspots:[],summary:{fullGates:0,securityReview:0,enhancedReview:0,standard:0}};return JSON.stringify(errorResult,null,2)}let days=daysValidation.value,topN=topNValidation.value,extensions=extensionsValidation.value.split(",").map((e)=>e.trim());try{let result=await analyzeHotspots(days,topN,extensions,directory);return JSON.stringify(result,null,2)}catch(e){let errorResult={error:e instanceof Error?`analysis failed: ${e.message}`:"analysis failed: unknown error",analyzedFiles:0,period:`${days} days`,hotspots:[],summary:{fullGates:0,securityReview:0,enhancedReview:0,standard:0}};return JSON.stringify(errorResult,null,2)}}});init_zod();init_config();init_schema();init_miner();init_miner();init_store3();async function mineAndStoreConsensusV1(options){let priorFingerprints=options.deps.priorFingerprints??await listConsensusProposalFingerprints(options.directory),result=await mineConsensus(options.directory,options.request,{...options.deps,priorFingerprints}),report=await writeConsensusReport(options.directory,result.report);return{...result,report}}init_store3();init_memory();init_recommendation_ledger();init_state2();init_logger();init_create_tool();var MAX_FILTER_ENTRIES=200,FilterListSchema=exports_external.array(exports_external.string().min(1).max(512)).max(MAX_FILTER_ENTRIES),MAX_INLINE_ATTRIBUTES=25;function countSummaries(attributes,inlineLimit){let total=0,shown=0;for(let[index,attribute]of attributes.entries()){if(attribute.llmSummary===void 0)continue;if(total+=1,index<inlineLimit)shown+=1}return{total,hidden:total-shown}}function buildMinerRecommendationCandidates(report,sessionId){return report.proposals.map((proposal)=>({kind:"miner",target:proposal.target,statement:proposal.intent,scopeKeys:[],provenance:{mechanism:"consensus_mine",sourceEvidenceRefs:proposal.evidenceRefs,sourceRunIds:proposal.provenance.sourceRunIds,sourceModelIds:proposal.provenance.sourceModelIds,sourceTaskIds:proposal.provenance.sourceTaskIds},origin:{agentRole:"consensus_mine",...sessionId?{sessionId}:{},producedAt:report.generatedAt}}))}var MIRRORED_PROPOSAL_KIND="todo";async function mirrorProposalsToMemory(options){if(options.memoryConfig?.enabled!==!0)return{enabled:!1,attempted:0,proposed:0,rejected:0,failed:0};let proposals=options.report.proposals;if(proposals.length===0)return{enabled:!0,attempted:0,proposed:0,rejected:0,failed:0};let gateway;try{gateway=_internals189.createMemoryGateway({directory:options.directory,...options.sessionId?{sessionID:options.sessionId,runId:options.sessionId}:{},agentRole:"consensus_mine"},{config:options.memoryConfig})}catch(err){let message=err instanceof Error?err.message:String(err);return warn(`[consensus_mine] memory mirror unavailable (fail-open): ${message}`),{enabled:!0,attempted:proposals.length,proposed:0,rejected:0,failed:proposals.length,error:message}}let proposed=0,rejected=0,failed=0,error93;try{for(let proposal of proposals)try{if((await gateway.propose({operation:"add",kind:MIRRORED_PROPOSAL_KIND,text:proposal.intent,rationale:`consensus_mine proposal from report ${options.report.reportId}, attribute ${proposal.sourceAttributeId} (target ${proposal.target}, confidence ${proposal.confidence})`,evidenceRefs:proposal.evidenceRefs})).status==="rejected")rejected+=1;else proposed+=1}catch(err){failed+=1,error93??=err instanceof Error?err.message:String(err)}}finally{try{await gateway.dispose()}catch(err){warn(`[consensus_mine] memory gateway dispose failed: ${err instanceof Error?err.message:String(err)}`)}}if(error93!==void 0)warn(`[consensus_mine] memory mirror partially failed: ${error93}`);return{enabled:!0,attempted:proposals.length,proposed,rejected,failed,...error93?{error:error93}:{}}}var _internals189={createMemoryGateway};var consensus_mine=createSwarmTool({description:"Mine cross-run consensus from existing .swarm evidence — evaluation runs, gate audits, gate "+"ground truth, task trajectories, PRM sessions, skill usage, knowledge outcomes, evidence "+"bundles, and curated failures (nine sources) — and persist an immutable report of "+`agreed-upon attributes plus proposals-only recommendations. It never activates a skill, writes a knowledge entry, admits a durable memory record, edits a project file, or mutates any evidence it reads. It is NOT otherwise write-minimal, so plan for these effects: it DELETES its own older reports past consensus.report_retention (default 50) on every run; it rewrites the shared recommendation dedup ledger whole, with FIFO eviction that can drop another producer's oldest entries; it leaves one never-removed lock sentinel per report id under .swarm/locks/; when memory.enabled is true it mirrors each proposal into a PENDING swarm-memory proposal (curator review still required); and when consensus.llm_summarization_enabled is true (the default) it issues up to ${MAX_LLM_SUMMARIES} session.create plus session.prompt calls. Under a knowledge or memory link the ledger and the memory store resolve to the shared cohort root, outside this project's .swarm/.`,args:{run_ids:FilterListSchema.optional().describe("Restrict mining to these run ids (raw or namespaced). Omit for all runs."),task_categories:FilterListSchema.optional().describe("Restrict to these evaluation task categories. Omit for all categories."),agent_roles:FilterListSchema.optional().describe("Restrict to these agent roles. Omit for all roles."),model_ids:FilterListSchema.optional().describe("Restrict to these model ids. Omit for all models."),min_support:exports_external.number().int().min(1).max(1e4).optional().describe("Distinct runs required to emit an attribute. Defaults to consensus.default_min_support."),min_successful_runs:exports_external.number().int().min(0).max(1e4).optional().describe("Successful runs required. Defaults to consensus.default_min_successful_runs."),max_evidence_items:exports_external.number().int().min(1).max(1e4).optional().describe("Cap on corpus observations read. Defaults to consensus.default_max_evidence_items.")},execute:async(args2,directory,ctx)=>{let input=args2??{},loaded=loadPluginConfigWithMeta(directory),config3=ConsensusConfigSchema.parse(loaded.config.consensus??{});if(!config3.enabled)return JSON.stringify({success:!1,disabled:!0,message:"Consensus mining is disabled (consensus.enabled = false). No report was written."},null,2);let request={...input.run_ids?{runIds:input.run_ids}:{},...input.task_categories?{taskCategories:input.task_categories}:{},...input.agent_roles?{agentRoles:input.agent_roles}:{},...input.model_ids?{modelIds:input.model_ids}:{},minSupport:input.min_support??config3.default_min_support,minSuccessfulRuns:input.min_successful_runs??config3.default_min_successful_runs,maxEvidenceItems:input.max_evidence_items??config3.default_max_evidence_items},client=swarmState.opencodeClient,dispatcher=config3.llm_summarization_enabled&&client?createEvaluationModelDispatcher(client):void 0,result=await mineAndStoreConsensusV1({directory,request,deps:{config:config3,...dispatcher?{dispatcher}:{},...ctx?.sessionID?{sessionId:ctx.sessionID}:{},agentRole:"consensus_mine"}}),report=result.report,ledger=await recordEmittedRecommendations(directory,buildMinerRecommendationCandidates(report,ctx?.sessionID),{producedAt:report.generatedAt});if(ledger.degraded)warn("[consensus_mine] recommendation ledger write degraded; proposals were not recorded for cross-producer dedup");let memoryMirror=await mirrorProposalsToMemory({directory,memoryConfig:loaded.config.memory,report,...ctx?.sessionID?{sessionId:ctx.sessionID}:{}}),pruned=await pruneConsensusReports(directory,config3.report_retention),pruningEnabled=config3.report_retention>0,summaries=countSummaries(report.attributes,MAX_INLINE_ATTRIBUTES);return JSON.stringify({success:!0,report_id:report.reportId,report_path:`.swarm/evolution/consensus/${report.reportId}.json`,generated_at:report.generatedAt,integrity_hash:report.integrityHash,config_hash:report.configHash,redaction_policy_version:report.redactionPolicyVersion,thresholds:{min_support:request.minSupport,min_successful_runs:request.minSuccessfulRuns,max_evidence_items:request.maxEvidenceItems,min_task_diversity:MIN_TASK_DIVERSITY_FOR_PROPOSAL,min_support_for_proposal:MIN_SUPPORT_FOR_PROPOSAL},input_run_count:report.inputIds.length,corpus:report.corpusHashes.map((entry)=>({source:entry.source,observations:entry.observations})),corpus_truncated:result.truncated,truncation:{corpus:report.truncation.corpus,observations_tallied:report.truncation.observations,input_ids_truncated:report.truncation.inputIds,total_input_ids:report.truncation.totalInputIds,attributes_dropped:report.truncation.attributesDropped},unreadable_sources:result.unreadableSources,attribute_count:report.attributes.length,investigation_note_count:result.investigationNoteCount,proposal_count:report.proposals.length,deduped_proposal_count:result.dedupedProposalCount,recommendation_ledger:{recorded:ledger.recorded,duplicate_recommendation_count:ledger.suppressed,evicted:ledger.evicted,degraded:ledger.degraded},memory_mirror:memoryMirror,summarized_count:summaries.total,summarized_but_not_shown:summaries.hidden,restatements_accepted_this_run:result.summarizedCount,...result.summarizationSkippedReason?{summarization_skipped_reason:result.summarizationSkippedReason}:{},attributes:report.attributes.slice(0,MAX_INLINE_ATTRIBUTES).map((attribute)=>({id:attribute.id,statement:attribute.statement,...attribute.llmSummary?{llm_summary:attribute.llmSummary}:{},support:attribute.support,success_support:attribute.successSupport,failure_support:attribute.failureSupport,task_diversity:attribute.taskDiversity,model_diversity:attribute.modelDiversity,confidence:attribute.confidence,proposed_target:attribute.proposedTarget,counterexample_count:attribute.counterexampleRefs.length})),attributes_truncated:report.attributes.length>MAX_INLINE_ATTRIBUTES,retention:pruningEnabled?{configured:config3.report_retention,pruning_enabled:!0,deleted:pruned.deleted.length,retained:pruned.retained.length,failed:pruned.failed.length,corrupt:pruned.corrupt.length}:{configured:config3.report_retention,pruning_enabled:!1,deleted:0,failed:0},guarantees:["proposals only — no skill activation, no knowledge write, no durable memory record, and no mutation of any evidence read",'model_diversity 0 means "not measurable from this corpus", never "measured as none"',`attributes below task diversity ${MIN_TASK_DIVERSITY_FOR_PROPOSAL} or below support ${MIN_SUPPORT_FOR_PROPOSAL} are investigation notes, never proposals`,"an attribute counting failing runs always carries counterexample refs (schema-enforced)","truncation is not biased toward successes, but it is still a cut: it balances per source, and drops whole sources once the budget is spent","statement is deterministic; llm_summary is an optional restatement excluded from integrity_hash","reproducible: identical corpus, request, config_hash, and prior proposals yield the same integrity_hash and report_id; model wording never moves it",'truncation is declared on the report; read failure_support 0 on a truncated report as "none survived the cut"']},null,2)}});init_config();init_model_limits();init_utils2();init_state2();init_create_tool();var _internals190={loadPluginConfig,fetchSessionMessages:async(sessionID,directory,limit=100)=>{if(!swarmState.opencodeClient?.session)return null;try{return(await swarmState.opencodeClient.session.messages({path:{id:sessionID},query:{directory,limit}})).data??null}catch{return null}}};function computeContextHeadroom(messages,warnThreshold=0.7,criticalThreshold=0.9,modelLimitsConfig={},liveContextLimit,modelIdentity){let{modelID,providerID}=modelIdentity??extractModelInfo(messages),modelLimit=resolveModelLimit(modelID,providerID,modelLimitsConfig,liveContextLimit),totalTokens=0;for(let message of messages){if(!message?.parts)continue;for(let part of message.parts)if(part?.type==="text"&&part.text)totalTokens+=estimateTokens(part.text)}let usagePercent=totalTokens/modelLimit,thresholdCrossed="none";if(usagePercent>criticalThreshold)thresholdCrossed="critical";else if(usagePercent>warnThreshold)thresholdCrossed="warn";return{tokensUsed:totalTokens,modelLimit,usagePercent,thresholdCrossed,modelId:modelID??null,provider:providerID??null}}var context_status=createSwarmTool({allowWorkingDirectoryOverride:!0,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.",args:{},async execute(_args,directory,ctx){let config3=_internals190.loadPluginConfig(directory),warnThreshold=config3.context_budget?.warn_threshold??0.7,criticalThreshold=config3.context_budget?.critical_threshold??0.9,modelLimitsConfig=config3.context_budget?.model_limits??{},messages=[];if(ctx?.sessionID){let sessionMessages=await _internals190.fetchSessionMessages(ctx.sessionID,directory);if(sessionMessages)messages=sessionMessages}let{modelID,providerID}=getLiveContextModelIdentity(ctx?.sessionID)??extractModelInfo(messages),headroom=computeContextHeadroom(messages,warnThreshold,criticalThreshold,modelLimitsConfig,getLiveContextWindow(ctx?.sessionID,{modelID,providerID}),{modelID,providerID});return JSON.stringify(headroom,null,2)}});init_zod();init_loader();function pushCouncilAdvisory(session,synthesis){let dedupKey=`council:${synthesis.taskId}:${synthesis.roundNumber}`;if(synthesis.overallVerdict==="APPROVE"&&synthesis.advisoryFindings.length===0)return;if(session.pendingAdvisoryMessages??=[],session.pendingAdvisoryMessages.some((m)=>m.includes(dedupKey)))return;let blocking=synthesis.overallVerdict==="REJECT",header=`[${dedupKey}] (priority=HIGH, blocking=${blocking})`,body=synthesis.unifiedFeedbackMd;pushAdvisory(session,`${header}
6427
- ${body}`,{dedupeKey:dedupKey})}init_zod();init_task_file();init_gate_evidence();init_project_boundary();import{existsSync as existsSync128,mkdirSync as mkdirSync64,readFileSync as readFileSync100}from"node:fs";import{join as join202}from"node:path";var EVIDENCE_DIR2=".swarm/evidence",VALID_TASK_ID=/^\d+\.\d+(\.\d+)*$/,COUNCIL_GATE_NAME="council",COUNCIL_AGENT_ID="architect",EvidenceFileSchema=exports_external.record(exports_external.string(),exports_external.unknown()),_internals191={withTaskEvidenceLock},FORBIDDEN_KEYS=new Set(["__proto__","constructor","prototype"]);function safeAssignOwnProps(target,source){for(let key of Object.keys(source)){if(FORBIDDEN_KEYS.has(key))continue;let value=source[key];if(value!==null&&typeof value==="object"&&!Array.isArray(value)){let nested=Object.create(null);safeAssignOwnProps(nested,value),target[key]=nested}else if(Array.isArray(value))target[key]=value.map((item)=>{if(item!==null&&typeof item==="object"&&!Array.isArray(item)){let nested=Object.create(null);return safeAssignOwnProps(nested,item),nested}return item});else target[key]=value}return target}async function writeCouncilEvidence(workingDir,synthesis,attemptId,expectedGeneration){if(!VALID_TASK_ID.test(synthesis.taskId))throw Error(`writeCouncilEvidence: invalid taskId "${synthesis.taskId}" — must match N.M or N.M.P format`);let dir=join202(workingDir,EVIDENCE_DIR2);assertProjectRoot(workingDir),mkdirSync64(dir,{recursive:!0});let filePath=taskEvidencePath(workingDir,synthesis.taskId);await _internals191.withTaskEvidenceLock(workingDir,synthesis.taskId,COUNCIL_AGENT_ID,async()=>{assertTaskEvidenceWriteAllowed(workingDir,synthesis.taskId);let existingRoot=Object.create(null);if(existsSync128(filePath))try{let raw=readFileSync100(filePath,"utf-8");if(expectedGeneration!==void 0){let exactEvidence=parseTaskEvidence(raw,synthesis.taskId),workflow=getTaskWorkflowSnapshot(exactEvidence);if(!workflow.authoritative||workflow.generation!==expectedGeneration||workflow.state!=="pre_check_passed")throw Error(`TASK_COUNCIL_GENERATION_MISMATCH: expected pre_check_passed@${expectedGeneration}, found ${workflow.state}@${workflow.generation}`)}let parsed=EvidenceFileSchema.parse(JSON.parse(raw));safeAssignOwnProps(existingRoot,parsed)}catch(error93){if(expectedGeneration!==void 0)throw error93}else if(expectedGeneration!==void 0)throw Error(`TASK_COUNCIL_GENERATION_MISMATCH: no exact evidence exists for generation ${expectedGeneration}`);let existingGatesRaw=existingRoot.gates,mergedGates=Object.create(null);if(existingGatesRaw&&typeof existingGatesRaw==="object"&&!Array.isArray(existingGatesRaw))safeAssignOwnProps(mergedGates,existingGatesRaw);mergedGates[COUNCIL_GATE_NAME]={sessionId:synthesis.swarmId,timestamp:synthesis.timestamp,agent:COUNCIL_AGENT_ID,verdict:synthesis.overallVerdict,vetoedBy:synthesis.vetoedBy,roundNumber:synthesis.roundNumber,allCriteriaMet:synthesis.allCriteriaMet,quorumSize:synthesis.quorumSize,...expectedGeneration!==void 0?{workflowGeneration:expectedGeneration}:{},...attemptId?{attemptId}:{}};let updated=Object.create(null);if(safeAssignOwnProps(updated,existingRoot),updated.gates=mergedGates,!updated.taskId)updated.taskId=synthesis.taskId;if(!Array.isArray(updated.required_gates))updated.required_gates=[];await atomicWriteFile(filePath,JSON.stringify(updated,null,2))})}function hasCouncilEvidenceAttempt(workingDir,taskId,attemptId,roundNumber){if(!VALID_TASK_ID.test(taskId))return!1;try{let council=EvidenceFileSchema.parse(JSON.parse(readFileSync100(taskEvidencePath(workingDir,taskId),"utf-8"))).gates?.[COUNCIL_GATE_NAME];return council?.attemptId===attemptId&&council.roundNumber===roundNumber}catch{return!1}}init_lock();init_task_file();import{createHash as createHash50,randomUUID as randomUUID27}from"node:crypto";import{closeSync as closeSync21,existsSync as existsSync129,fsyncSync as fsyncSync7,mkdirSync as mkdirSync65,openSync as openSync21,readFileSync as readFileSync101,readSync as readSync14,statSync as statSync53,writeSync as writeSync2}from"node:fs";import{dirname as dirname103,join as join203}from"node:path";var VERSION=1,MAX_ROUND=10,MAX_AUDIT_TAIL=262144,STATE_AGENT="council-round-state";class CouncilRoundStateUncertainError extends Error{constructor(message){super(message);this.name="CouncilRoundStateUncertainError"}}function sha2564(value){return createHash50("sha256").update(value).digest("hex")}var UUID_PATTERN2=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,DIGEST_PATTERN=/^[a-f0-9]{64}$/;function isUuid2(value){return typeof value==="string"&&UUID_PATTERN2.test(value)}function isDigest(value){return typeof value==="string"&&DIGEST_PATTERN.test(value)}function isRound(value){return Number.isInteger(value)&&Number(value)>=1&&Number(value)<=MAX_ROUND}function isDisposition(value){return typeof value==="string"&&value.length>0&&value.length<=80}function isEvidenceRef(value){return typeof value==="string"&&value.length>0&&value.length<=240&&value.startsWith(".swarm/")&&!value.includes("..")}function scopeToken(scope){if(scope.kind==="task"){if(!/^\d+\.\d+(\.\d+)*$/.test(scope.taskId))throw Error("invalid task council scope");return`task-${sha2564(scope.taskId)}`}if(scope.kind==="phase"){if(!Number.isInteger(scope.phaseNumber)||scope.phaseNumber<1||scope.phaseNumber>1000)throw Error("invalid phase council scope");return`phase-${scope.phaseNumber}`}if(typeof scope.generation!=="string"||scope.generation.length===0||scope.generation.length>256)throw Error("invalid final council scope");return`final-${sha2564(scope.generation)}`}function auditScope(scope){if(scopeToken(scope),scope.kind==="task")return{kind:"task",scopeHash:sha2564(scope.taskId)};if(scope.kind==="phase")return{kind:"phase",phaseNumber:scope.phaseNumber};return{kind:"final",scopeHash:sha2564(scope.generation)}}function sameAuditScope(left,right){if(left.kind!==right.kind)return!1;if(left.kind==="phase"&&right.kind==="phase")return left.phaseNumber===right.phaseNumber;if(left.kind!=="phase"&&right.kind!=="phase")return left.scopeHash===right.scopeHash;return!1}function councilRoundStatePaths(directory,scope){let token=scopeToken(scope);return{state:join203(directory,".swarm","council","round-state",`${token}.json`),audit:join203(directory,".swarm","council","attempts",`${token}.jsonl`),lock:join203("council","round-state",`${token}.json`)}}function canonicalize2(value){if(Array.isArray(value))return value.map(canonicalize2);if(value&&typeof value==="object"){let result=Object.create(null);for(let key of Object.keys(value).sort()){if(key==="working_directory"||key==="roundNumber"||key==="provenanceAgentName"||key==="provenanceSessionId")continue;result[key]=canonicalize2(value[key])}return result}return value}function councilRequestDigest(request,round){return sha2564(JSON.stringify({round,request:canonicalize2(request)}))}function isSnapshot(value){if(!value||typeof value!=="object")return!1;let state=value;return state.version===VERSION&&isRound(state.currentRound)&&(state.status==="open"||state.status==="closed")&&typeof state.maxRoundsExhausted==="boolean"&&(state.lastAttemptId===void 0||isUuid2(state.lastAttemptId))&&(state.lastDigest===void 0||isDigest(state.lastDigest))&&state.lastAttemptId===void 0===(state.lastDigest===void 0)}function isTransition(value){return value==="stay"||value==="advance"||value==="close"}function isGateEffect(value){return value==="none"||value==="blocked"||value==="allowed"}function isVerdict(value){return value==="APPROVE"||value==="CONCERNS"||value==="REJECT"}function auditTransitionIsConsistent(record3){if(!record3.nextState||!record3.transition)return!1;if(record3.transition==="close")return record3.nextState.status==="closed"&&record3.nextState.currentRound===record3.authoritativeRound;if(record3.transition==="stay"){if(record3.nextState.status==="closed"&&!["duplicate_submission","council_round_closed","council_round_mismatch"].includes(record3.disposition))return!1;return(record3.nextState.status==="open"||record3.nextState.status==="closed")&&record3.nextState.currentRound===record3.authoritativeRound}return record3.nextState.status==="open"&&(record3.nextState.currentRound===record3.authoritativeRound+1&&record3.nextState.maxRoundsExhausted===!1||record3.nextState.currentRound===record3.authoritativeRound&&record3.nextState.maxRoundsExhausted===!0)}function recoverAuditHistory(tail2){let current=tail2.truncated?void 0:initialState(),awaiting,sawTransition=!1;for(let record3 of tail2.records){if(record3.event==="received"){if(awaiting)throw new CouncilRoundStateUncertainError("council audit contains overlapping attempts");if(current&&record3.authoritativeRound!==current.currentRound||!current&&!tail2.truncated&&record3.authoritativeRound!==1)throw new CouncilRoundStateUncertainError("council audit round history is not monotonic");awaiting=record3;continue}if(!record3.nextState||!record3.transition)throw new CouncilRoundStateUncertainError("council audit transition is incomplete");if(awaiting){if(awaiting.attemptId!==record3.attemptId||awaiting.digest!==record3.digest||awaiting.authoritativeRound!==record3.authoritativeRound)throw new CouncilRoundStateUncertainError("council audit attempt pairing is inconsistent");awaiting=void 0}else if(!tail2.truncated||sawTransition)throw new CouncilRoundStateUncertainError("council audit transition has no matching received record");if(current){if(record3.authoritativeRound!==current.currentRound)throw new CouncilRoundStateUncertainError("council audit transition regresses the authoritative round");if(record3.transition==="stay"&&record3.nextState.status!==current.status)throw new CouncilRoundStateUncertainError("council audit stay transition changes scope status");if((record3.transition==="stay"||record3.transition==="close")&&record3.nextState.maxRoundsExhausted!==current.maxRoundsExhausted)throw new CouncilRoundStateUncertainError("council audit changes exhaustion without advancing");if(current.status==="closed"&&(record3.transition!=="stay"||record3.nextState.status!=="closed"))throw new CouncilRoundStateUncertainError("council audit reopens a closed scope")}current=record3.nextState,sawTransition=!0}if(awaiting)throw new CouncilRoundStateUncertainError("council audit ends with an unresolved received attempt");return current}function pendingMatchesParent(state,pending){if(state.status!=="open"||pending.round!==state.currentRound)return!1;if(pending.nextState.lastAttemptId!==pending.attemptId||pending.nextState.lastDigest!==pending.digest)return!1;if(pending.transition==="stay")return pending.nextState.status==="open"&&pending.nextState.currentRound===state.currentRound&&pending.nextState.maxRoundsExhausted===state.maxRoundsExhausted;if(pending.transition==="close")return pending.nextState.status==="closed"&&pending.nextState.currentRound===state.currentRound&&pending.nextState.maxRoundsExhausted===state.maxRoundsExhausted;return pending.nextState.status==="open"&&(pending.nextState.currentRound===state.currentRound+1&&pending.nextState.maxRoundsExhausted===!1||pending.nextState.currentRound===state.currentRound&&pending.nextState.maxRoundsExhausted===!0)}function parseState(raw){let value;try{value=JSON.parse(raw)}catch{throw new CouncilRoundStateUncertainError("council round state is corrupt")}if(!isSnapshot(value))throw new CouncilRoundStateUncertainError("council round state is invalid");let state=value;if(state.pending){let pending=state.pending;if(!isUuid2(pending.attemptId)||!isDigest(pending.digest)||!isRound(pending.round)||!isSnapshot(pending.nextState)||!isTransition(pending.transition)||!isDisposition(pending.disposition)||!isGateEffect(pending.gateEffect)||typeof pending.evidenceExpected!=="boolean"||pending.evidenceExpected!==(pending.evidenceRef!==void 0)||pending.evidenceRef!==void 0&&!isEvidenceRef(pending.evidenceRef)||pending.verdict!==void 0&&!isVerdict(pending.verdict)||pending.quorumSize!==void 0&&(!Number.isInteger(pending.quorumSize)||pending.quorumSize<0||pending.quorumSize>5)||pending.verdict===void 0!==(pending.quorumSize===void 0)||!pendingMatchesParent(state,pending))throw new CouncilRoundStateUncertainError("pending council state is invalid")}return state}function parseAuditRecord(line,expectedScope){try{let record3=JSON.parse(line);if(record3.version!==VERSION||!["received","finalized","recovered"].includes(record3.event)||!isUuid2(record3.attemptId)||typeof record3.timestamp!=="string"||record3.timestamp.length>40||!Number.isFinite(Date.parse(record3.timestamp))||!sameAuditScope(record3.scope,expectedScope)||record3.clientRound!==void 0&&!isRound(record3.clientRound)||!isRound(record3.authoritativeRound)||!isDigest(record3.digest)||record3.sessionHash!==void 0&&!isDigest(record3.sessionHash)||!isDisposition(record3.disposition)||!Number.isInteger(record3.verdictCount)||record3.verdictCount<0||record3.verdictCount>5||!Array.isArray(record3.members)||record3.members.length>5||record3.members.some((member)=>typeof member!=="string"||member.length===0||member.length>32)||new Set(record3.members).size!==record3.members.length)throw Error("invalid");if(record3.event==="received"){if(record3.disposition!=="received"||record3.transition!==void 0||record3.gateEffect!==void 0||record3.nextState!==void 0||record3.evidenceRef!==void 0)throw Error("invalid")}else if(!isTransition(record3.transition)||!isGateEffect(record3.gateEffect)||!isSnapshot(record3.nextState)||record3.nextState.lastAttemptId!==record3.attemptId||record3.nextState.lastDigest!==record3.digest||!auditTransitionIsConsistent(record3))throw Error("invalid");if(record3.verdict!==void 0&&!isVerdict(record3.verdict))throw Error("invalid");if(record3.quorumSize!==void 0&&(!Number.isInteger(record3.quorumSize)||record3.quorumSize<0||record3.quorumSize>5))throw Error("invalid");if(record3.verdict===void 0!==(record3.quorumSize===void 0))throw Error("invalid");if(record3.evidenceRef!==void 0&&!isEvidenceRef(record3.evidenceRef))throw Error("invalid");return record3}catch{throw new CouncilRoundStateUncertainError("council attempt audit is corrupt")}}function appendAudit2(path254,record3){mkdirSync65(dirname103(path254),{recursive:!0});let descriptor=openSync21(path254,"a");try{writeSync2(descriptor,`${JSON.stringify(record3)}
6428
- `,void 0,"utf8"),fsyncSync7(descriptor)}finally{closeSync21(descriptor)}}function readAuditTail(path254,scope){if(!existsSync129(path254))return{records:[],truncated:!1};let size=statSync53(path254).size;if(size===0)return{records:[],truncated:!1};let offset=Math.max(0,size-MAX_AUDIT_TAIL),length=size-offset,descriptor=openSync21(path254,"r"),buffer=Buffer.alloc(length);try{readSync14(descriptor,buffer,0,length,offset)}finally{closeSync21(descriptor)}let text=buffer.toString("utf8");if(!text.endsWith(`
6434
+ ${body}`,{dedupeKey:dedupKey})}init_zod();init_task_file();init_gate_evidence();init_project_boundary();import{existsSync as existsSync129,mkdirSync as mkdirSync64,readFileSync as readFileSync100}from"node:fs";import{join as join202}from"node:path";var EVIDENCE_DIR2=".swarm/evidence",VALID_TASK_ID=/^\d+\.\d+(\.\d+)*$/,COUNCIL_GATE_NAME="council",COUNCIL_AGENT_ID="architect",EvidenceFileSchema=exports_external.record(exports_external.string(),exports_external.unknown()),_internals191={withTaskEvidenceLock},FORBIDDEN_KEYS=new Set(["__proto__","constructor","prototype"]);function safeAssignOwnProps(target,source){for(let key of Object.keys(source)){if(FORBIDDEN_KEYS.has(key))continue;let value=source[key];if(value!==null&&typeof value==="object"&&!Array.isArray(value)){let nested=Object.create(null);safeAssignOwnProps(nested,value),target[key]=nested}else if(Array.isArray(value))target[key]=value.map((item)=>{if(item!==null&&typeof item==="object"&&!Array.isArray(item)){let nested=Object.create(null);return safeAssignOwnProps(nested,item),nested}return item});else target[key]=value}return target}async function writeCouncilEvidence(workingDir,synthesis,attemptId,expectedGeneration){if(!VALID_TASK_ID.test(synthesis.taskId))throw Error(`writeCouncilEvidence: invalid taskId "${synthesis.taskId}" — must match N.M or N.M.P format`);let dir=join202(workingDir,EVIDENCE_DIR2);assertProjectRoot(workingDir),mkdirSync64(dir,{recursive:!0});let filePath=taskEvidencePath(workingDir,synthesis.taskId);await _internals191.withTaskEvidenceLock(workingDir,synthesis.taskId,COUNCIL_AGENT_ID,async()=>{assertTaskEvidenceWriteAllowed(workingDir,synthesis.taskId);let existingRoot=Object.create(null);if(existsSync129(filePath))try{let raw=readFileSync100(filePath,"utf-8");if(expectedGeneration!==void 0){let exactEvidence=parseTaskEvidence(raw,synthesis.taskId),workflow=getTaskWorkflowSnapshot(exactEvidence);if(!workflow.authoritative||workflow.generation!==expectedGeneration||workflow.state!=="pre_check_passed")throw Error(`TASK_COUNCIL_GENERATION_MISMATCH: expected pre_check_passed@${expectedGeneration}, found ${workflow.state}@${workflow.generation}`)}let parsed=EvidenceFileSchema.parse(JSON.parse(raw));safeAssignOwnProps(existingRoot,parsed)}catch(error93){if(expectedGeneration!==void 0)throw error93}else if(expectedGeneration!==void 0)throw Error(`TASK_COUNCIL_GENERATION_MISMATCH: no exact evidence exists for generation ${expectedGeneration}`);let existingGatesRaw=existingRoot.gates,mergedGates=Object.create(null);if(existingGatesRaw&&typeof existingGatesRaw==="object"&&!Array.isArray(existingGatesRaw))safeAssignOwnProps(mergedGates,existingGatesRaw);mergedGates[COUNCIL_GATE_NAME]={sessionId:synthesis.swarmId,timestamp:synthesis.timestamp,agent:COUNCIL_AGENT_ID,verdict:synthesis.overallVerdict,vetoedBy:synthesis.vetoedBy,roundNumber:synthesis.roundNumber,allCriteriaMet:synthesis.allCriteriaMet,quorumSize:synthesis.quorumSize,...expectedGeneration!==void 0?{workflowGeneration:expectedGeneration}:{},...attemptId?{attemptId}:{}};let updated=Object.create(null);if(safeAssignOwnProps(updated,existingRoot),updated.gates=mergedGates,!updated.taskId)updated.taskId=synthesis.taskId;if(!Array.isArray(updated.required_gates))updated.required_gates=[];await atomicWriteFile(filePath,JSON.stringify(updated,null,2))})}function hasCouncilEvidenceAttempt(workingDir,taskId,attemptId,roundNumber){if(!VALID_TASK_ID.test(taskId))return!1;try{let council=EvidenceFileSchema.parse(JSON.parse(readFileSync100(taskEvidencePath(workingDir,taskId),"utf-8"))).gates?.[COUNCIL_GATE_NAME];return council?.attemptId===attemptId&&council.roundNumber===roundNumber}catch{return!1}}init_lock();init_task_file();import{createHash as createHash50,randomUUID as randomUUID27}from"node:crypto";import{closeSync as closeSync21,existsSync as existsSync130,fsyncSync as fsyncSync7,mkdirSync as mkdirSync65,openSync as openSync21,readFileSync as readFileSync101,readSync as readSync14,statSync as statSync53,writeSync as writeSync2}from"node:fs";import{dirname as dirname103,join as join203}from"node:path";var VERSION=1,MAX_ROUND=10,MAX_AUDIT_TAIL=262144,STATE_AGENT="council-round-state";class CouncilRoundStateUncertainError extends Error{constructor(message){super(message);this.name="CouncilRoundStateUncertainError"}}function sha2564(value){return createHash50("sha256").update(value).digest("hex")}var UUID_PATTERN2=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,DIGEST_PATTERN=/^[a-f0-9]{64}$/;function isUuid2(value){return typeof value==="string"&&UUID_PATTERN2.test(value)}function isDigest(value){return typeof value==="string"&&DIGEST_PATTERN.test(value)}function isRound(value){return Number.isInteger(value)&&Number(value)>=1&&Number(value)<=MAX_ROUND}function isDisposition(value){return typeof value==="string"&&value.length>0&&value.length<=80}function isEvidenceRef(value){return typeof value==="string"&&value.length>0&&value.length<=240&&value.startsWith(".swarm/")&&!value.includes("..")}function scopeToken(scope){if(scope.kind==="task"){if(!/^\d+\.\d+(\.\d+)*$/.test(scope.taskId))throw Error("invalid task council scope");return`task-${sha2564(scope.taskId)}`}if(scope.kind==="phase"){if(!Number.isInteger(scope.phaseNumber)||scope.phaseNumber<1||scope.phaseNumber>1000)throw Error("invalid phase council scope");return`phase-${scope.phaseNumber}`}if(typeof scope.generation!=="string"||scope.generation.length===0||scope.generation.length>256)throw Error("invalid final council scope");return`final-${sha2564(scope.generation)}`}function auditScope(scope){if(scopeToken(scope),scope.kind==="task")return{kind:"task",scopeHash:sha2564(scope.taskId)};if(scope.kind==="phase")return{kind:"phase",phaseNumber:scope.phaseNumber};return{kind:"final",scopeHash:sha2564(scope.generation)}}function sameAuditScope(left,right){if(left.kind!==right.kind)return!1;if(left.kind==="phase"&&right.kind==="phase")return left.phaseNumber===right.phaseNumber;if(left.kind!=="phase"&&right.kind!=="phase")return left.scopeHash===right.scopeHash;return!1}function councilRoundStatePaths(directory,scope){let token=scopeToken(scope);return{state:join203(directory,".swarm","council","round-state",`${token}.json`),audit:join203(directory,".swarm","council","attempts",`${token}.jsonl`),lock:join203("council","round-state",`${token}.json`)}}function canonicalize2(value){if(Array.isArray(value))return value.map(canonicalize2);if(value&&typeof value==="object"){let result=Object.create(null);for(let key of Object.keys(value).sort()){if(key==="working_directory"||key==="roundNumber"||key==="provenanceAgentName"||key==="provenanceSessionId")continue;result[key]=canonicalize2(value[key])}return result}return value}function councilRequestDigest(request,round){return sha2564(JSON.stringify({round,request:canonicalize2(request)}))}function isSnapshot(value){if(!value||typeof value!=="object")return!1;let state=value;return state.version===VERSION&&isRound(state.currentRound)&&(state.status==="open"||state.status==="closed")&&typeof state.maxRoundsExhausted==="boolean"&&(state.lastAttemptId===void 0||isUuid2(state.lastAttemptId))&&(state.lastDigest===void 0||isDigest(state.lastDigest))&&state.lastAttemptId===void 0===(state.lastDigest===void 0)}function isTransition(value){return value==="stay"||value==="advance"||value==="close"}function isGateEffect(value){return value==="none"||value==="blocked"||value==="allowed"}function isVerdict(value){return value==="APPROVE"||value==="CONCERNS"||value==="REJECT"}function auditTransitionIsConsistent(record3){if(!record3.nextState||!record3.transition)return!1;if(record3.transition==="close")return record3.nextState.status==="closed"&&record3.nextState.currentRound===record3.authoritativeRound;if(record3.transition==="stay"){if(record3.nextState.status==="closed"&&!["duplicate_submission","council_round_closed","council_round_mismatch"].includes(record3.disposition))return!1;return(record3.nextState.status==="open"||record3.nextState.status==="closed")&&record3.nextState.currentRound===record3.authoritativeRound}return record3.nextState.status==="open"&&(record3.nextState.currentRound===record3.authoritativeRound+1&&record3.nextState.maxRoundsExhausted===!1||record3.nextState.currentRound===record3.authoritativeRound&&record3.nextState.maxRoundsExhausted===!0)}function recoverAuditHistory(tail2){let current=tail2.truncated?void 0:initialState(),awaiting,sawTransition=!1;for(let record3 of tail2.records){if(record3.event==="received"){if(awaiting)throw new CouncilRoundStateUncertainError("council audit contains overlapping attempts");if(current&&record3.authoritativeRound!==current.currentRound||!current&&!tail2.truncated&&record3.authoritativeRound!==1)throw new CouncilRoundStateUncertainError("council audit round history is not monotonic");awaiting=record3;continue}if(!record3.nextState||!record3.transition)throw new CouncilRoundStateUncertainError("council audit transition is incomplete");if(awaiting){if(awaiting.attemptId!==record3.attemptId||awaiting.digest!==record3.digest||awaiting.authoritativeRound!==record3.authoritativeRound)throw new CouncilRoundStateUncertainError("council audit attempt pairing is inconsistent");awaiting=void 0}else if(!tail2.truncated||sawTransition)throw new CouncilRoundStateUncertainError("council audit transition has no matching received record");if(current){if(record3.authoritativeRound!==current.currentRound)throw new CouncilRoundStateUncertainError("council audit transition regresses the authoritative round");if(record3.transition==="stay"&&record3.nextState.status!==current.status)throw new CouncilRoundStateUncertainError("council audit stay transition changes scope status");if((record3.transition==="stay"||record3.transition==="close")&&record3.nextState.maxRoundsExhausted!==current.maxRoundsExhausted)throw new CouncilRoundStateUncertainError("council audit changes exhaustion without advancing");if(current.status==="closed"&&(record3.transition!=="stay"||record3.nextState.status!=="closed"))throw new CouncilRoundStateUncertainError("council audit reopens a closed scope")}current=record3.nextState,sawTransition=!0}if(awaiting)throw new CouncilRoundStateUncertainError("council audit ends with an unresolved received attempt");return current}function pendingMatchesParent(state,pending){if(state.status!=="open"||pending.round!==state.currentRound)return!1;if(pending.nextState.lastAttemptId!==pending.attemptId||pending.nextState.lastDigest!==pending.digest)return!1;if(pending.transition==="stay")return pending.nextState.status==="open"&&pending.nextState.currentRound===state.currentRound&&pending.nextState.maxRoundsExhausted===state.maxRoundsExhausted;if(pending.transition==="close")return pending.nextState.status==="closed"&&pending.nextState.currentRound===state.currentRound&&pending.nextState.maxRoundsExhausted===state.maxRoundsExhausted;return pending.nextState.status==="open"&&(pending.nextState.currentRound===state.currentRound+1&&pending.nextState.maxRoundsExhausted===!1||pending.nextState.currentRound===state.currentRound&&pending.nextState.maxRoundsExhausted===!0)}function parseState(raw){let value;try{value=JSON.parse(raw)}catch{throw new CouncilRoundStateUncertainError("council round state is corrupt")}if(!isSnapshot(value))throw new CouncilRoundStateUncertainError("council round state is invalid");let state=value;if(state.pending){let pending=state.pending;if(!isUuid2(pending.attemptId)||!isDigest(pending.digest)||!isRound(pending.round)||!isSnapshot(pending.nextState)||!isTransition(pending.transition)||!isDisposition(pending.disposition)||!isGateEffect(pending.gateEffect)||typeof pending.evidenceExpected!=="boolean"||pending.evidenceExpected!==(pending.evidenceRef!==void 0)||pending.evidenceRef!==void 0&&!isEvidenceRef(pending.evidenceRef)||pending.verdict!==void 0&&!isVerdict(pending.verdict)||pending.quorumSize!==void 0&&(!Number.isInteger(pending.quorumSize)||pending.quorumSize<0||pending.quorumSize>5)||pending.verdict===void 0!==(pending.quorumSize===void 0)||!pendingMatchesParent(state,pending))throw new CouncilRoundStateUncertainError("pending council state is invalid")}return state}function parseAuditRecord(line,expectedScope){try{let record3=JSON.parse(line);if(record3.version!==VERSION||!["received","finalized","recovered"].includes(record3.event)||!isUuid2(record3.attemptId)||typeof record3.timestamp!=="string"||record3.timestamp.length>40||!Number.isFinite(Date.parse(record3.timestamp))||!sameAuditScope(record3.scope,expectedScope)||record3.clientRound!==void 0&&!isRound(record3.clientRound)||!isRound(record3.authoritativeRound)||!isDigest(record3.digest)||record3.sessionHash!==void 0&&!isDigest(record3.sessionHash)||!isDisposition(record3.disposition)||!Number.isInteger(record3.verdictCount)||record3.verdictCount<0||record3.verdictCount>5||!Array.isArray(record3.members)||record3.members.length>5||record3.members.some((member)=>typeof member!=="string"||member.length===0||member.length>32)||new Set(record3.members).size!==record3.members.length)throw Error("invalid");if(record3.event==="received"){if(record3.disposition!=="received"||record3.transition!==void 0||record3.gateEffect!==void 0||record3.nextState!==void 0||record3.evidenceRef!==void 0)throw Error("invalid")}else if(!isTransition(record3.transition)||!isGateEffect(record3.gateEffect)||!isSnapshot(record3.nextState)||record3.nextState.lastAttemptId!==record3.attemptId||record3.nextState.lastDigest!==record3.digest||!auditTransitionIsConsistent(record3))throw Error("invalid");if(record3.verdict!==void 0&&!isVerdict(record3.verdict))throw Error("invalid");if(record3.quorumSize!==void 0&&(!Number.isInteger(record3.quorumSize)||record3.quorumSize<0||record3.quorumSize>5))throw Error("invalid");if(record3.verdict===void 0!==(record3.quorumSize===void 0))throw Error("invalid");if(record3.evidenceRef!==void 0&&!isEvidenceRef(record3.evidenceRef))throw Error("invalid");return record3}catch{throw new CouncilRoundStateUncertainError("council attempt audit is corrupt")}}function appendAudit2(path254,record3){mkdirSync65(dirname103(path254),{recursive:!0});let descriptor=openSync21(path254,"a");try{writeSync2(descriptor,`${JSON.stringify(record3)}
6435
+ `,void 0,"utf8"),fsyncSync7(descriptor)}finally{closeSync21(descriptor)}}function readAuditTail(path254,scope){if(!existsSync130(path254))return{records:[],truncated:!1};let size=statSync53(path254).size;if(size===0)return{records:[],truncated:!1};let offset=Math.max(0,size-MAX_AUDIT_TAIL),length=size-offset,descriptor=openSync21(path254,"r"),buffer=Buffer.alloc(length);try{readSync14(descriptor,buffer,0,length,offset)}finally{closeSync21(descriptor)}let text=buffer.toString("utf8");if(!text.endsWith(`
6429
6436
  `))throw new CouncilRoundStateUncertainError("council attempt audit has a partial tail");if(offset>0){let firstNewline=text.indexOf(`
6430
6437
  `);if(firstNewline<0)throw new CouncilRoundStateUncertainError("council attempt audit tail is oversized");text=text.slice(firstNewline+1)}let expectedScope=auditScope(scope);return{records:text.split(`
6431
- `).filter(Boolean).map((line)=>parseAuditRecord(line,expectedScope)),truncated:offset>0}}function initialState(){return{version:VERSION,currentRound:1,status:"open",maxRoundsExhausted:!1}}function snapshot(state){return{version:VERSION,currentRound:state.currentRound,status:state.status,maxRoundsExhausted:state.maxRoundsExhausted,lastAttemptId:state.lastAttemptId,lastDigest:state.lastDigest}}function sameSnapshot(left,right){return left.version===right.version&&left.currentRound===right.currentRound&&left.status===right.status&&left.maxRoundsExhausted===right.maxRoundsExhausted&&left.lastAttemptId===right.lastAttemptId&&left.lastDigest===right.lastDigest}function pendingTerminalMatches(state,record3){let pending=state.pending;if(!pending||record3.attemptId!==pending.attemptId||record3.digest!==pending.digest||record3.authoritativeRound!==pending.round||!record3.nextState)return!1;if(record3.event==="finalized")return record3.disposition===pending.disposition&&record3.transition===pending.transition&&record3.gateEffect===pending.gateEffect&&record3.verdict===pending.verdict&&record3.quorumSize===pending.quorumSize&&record3.evidenceRef===pending.evidenceRef&&sameSnapshot(record3.nextState,pending.nextState);if(record3.event!=="recovered")return!1;if(record3.disposition==="pending_evidence_recovered")return record3.transition===pending.transition&&record3.gateEffect===pending.gateEffect&&record3.verdict===pending.verdict&&record3.quorumSize===pending.quorumSize&&record3.evidenceRef===pending.evidenceRef&&sameSnapshot(record3.nextState,pending.nextState);if(record3.disposition!=="orphan_recovered")return!1;return record3.transition==="stay"&&record3.gateEffect==="none"&&record3.verdict===pending.verdict&&record3.quorumSize===pending.quorumSize&&record3.evidenceRef===pending.evidenceRef&&sameSnapshot(record3.nextState,{...snapshot(state),lastAttemptId:pending.attemptId,lastDigest:pending.digest})}function transitionState(state,attemptId,digest3,transition,maxRounds){let configuredLimit=Math.max(1,Math.min(MAX_ROUND,maxRounds)),limit=Math.max(state.currentRound,configuredLimit),currentRound=state.currentRound,status="open",maxRoundsExhausted=state.maxRoundsExhausted;if(transition==="advance")if(currentRound<limit)currentRound++,maxRoundsExhausted=!1;else maxRoundsExhausted=!0;else if(transition==="close")status="closed";return{version:VERSION,currentRound,status,maxRoundsExhausted,lastAttemptId:attemptId,lastDigest:digest3}}async function writeState3(path254,state){mkdirSync65(dirname103(path254),{recursive:!0}),await _internals192.atomicWrite(path254,JSON.stringify(state,null,2))}function baseRecord(input,attemptId,digest3,round,disposition){return{version:VERSION,attemptId,timestamp:_internals192.now(),scope:auditScope(input.scope),clientRound:input.clientRound,authoritativeRound:round,digest:digest3,sessionHash:input.sessionID?sha2564(input.sessionID):void 0,disposition:disposition.slice(0,80),verdictCount:Math.max(0,Math.min(5,input.verdictCount)),members:input.members.slice(0,5).map((member)=>member.slice(0,32))}}function latestRecord(records,attemptId){for(let index=records.length-1;index>=0;index--)if(records[index]?.attemptId===attemptId)return records[index];return}async function loadState2(paths,scope){if(existsSync129(paths.state))return parseState(readFileSync101(paths.state,"utf8"));let tail2=_internals192.readAuditTail(paths.audit,scope),records=tail2.records,recovered=recoverAuditHistory(tail2);if(tail2.truncated&&!recovered)throw new CouncilRoundStateUncertainError("council state is missing and the bounded audit tail has no recoverable transition");if(!recovered&&records.length>0)throw new CouncilRoundStateUncertainError("council state is missing and the audit has no complete transition");let state=recovered??initialState();return await writeState3(paths.state,state),state}function persistenceFailure2(round,error93){return JSON.stringify({success:!1,reason:"council_round_state_persistence_failed",authoritativeRound:round,message:error93 instanceof Error?error93.message:String(error93)},null,2)}function uncertainFailure(error93){return JSON.stringify({success:!1,reason:"council_round_state_uncertain",message:error93 instanceof Error?error93.message:String(error93)},null,2)}async function runCouncilAttempt(input){let paths=councilRoundStatePaths(input.directory,input.scope),authoritativeRound=1;try{return await _internals192.withLock(input.directory,paths.lock,STATE_AGENT,scopeToken(input.scope),async()=>{let state=await loadState2(paths,input.scope);if(state.pending){let tail2=_internals192.readAuditTail(paths.audit,input.scope),latest=latestRecord(tail2.records,state.pending.attemptId);if(tail2.truncated&&!latest)throw new CouncilRoundStateUncertainError("pending council attempt is outside the bounded audit tail");if(!latest)throw new CouncilRoundStateUncertainError("pending council attempt has no matching audit record");if((latest.event==="finalized"||latest.event==="recovered")&&latest.nextState){if(!pendingTerminalMatches(state,latest))throw new CouncilRoundStateUncertainError("terminal council audit contradicts pending state");state=latest.nextState}else{let committed=state.pending.evidenceExpected&&input.probePendingEvidence?await input.probePendingEvidence(state.pending.attemptId,state.pending.round,state.pending.evidenceRef):!1,recovered=committed?state.pending.nextState:{...snapshot(state),lastAttemptId:state.pending.attemptId,lastDigest:state.pending.digest};_internals192.appendAudit(paths.audit,{...baseRecord(input,state.pending.attemptId,state.pending.digest,state.pending.round,committed?"pending_evidence_recovered":"orphan_recovered"),event:"recovered",transition:committed?state.pending.transition:"stay",gateEffect:committed?state.pending.gateEffect:"none",verdict:state.pending.verdict,quorumSize:state.pending.quorumSize,evidenceRef:state.pending.evidenceRef,nextState:recovered}),state=recovered}await writeState3(paths.state,state)}authoritativeRound=state.currentRound;let digest3=councilRequestDigest(input.request,authoritativeRound),attemptId=_internals192.uuid(),received=baseRecord(input,attemptId,digest3,authoritativeRound,"received");if(_internals192.appendAudit(paths.audit,{...received,event:"received"}),input.clientRound!==void 0&&input.clientRound!==authoritativeRound){let next2={...snapshot(state),lastAttemptId:attemptId,lastDigest:digest3};return _internals192.appendAudit(paths.audit,{...received,event:"finalized",disposition:"council_round_mismatch",transition:"stay",gateEffect:"none",nextState:next2}),await writeState3(paths.state,next2),JSON.stringify({success:!1,reason:"council_round_mismatch",authoritativeRound,submittedRound:input.clientRound},null,2)}if(state.status==="closed"){let disposition=state.lastDigest===digest3?"duplicate_submission":"council_round_closed",next2={...snapshot(state),lastAttemptId:attemptId,lastDigest:digest3};return _internals192.appendAudit(paths.audit,{...received,event:"finalized",disposition,transition:"stay",gateEffect:"none",nextState:next2}),await writeState3(paths.state,next2),JSON.stringify({success:!1,reason:disposition,authoritativeRound},null,2)}let evaluation;try{evaluation=await input.evaluate(authoritativeRound)}catch(error93){evaluation={disposition:"council_evaluation_failed",response:{success:!1,reason:"council_evaluation_failed",message:error93 instanceof Error?error93.message:String(error93)},transition:"stay",gateEffect:"none"}}let next=transitionState(state,attemptId,digest3,evaluation.transition,input.maxRounds),pending={attemptId,digest:digest3,round:authoritativeRound,transition:evaluation.transition,nextState:next,disposition:evaluation.disposition.slice(0,80),gateEffect:evaluation.gateEffect,evidenceExpected:Boolean(evaluation.evidence),evidenceRef:evaluation.evidence?.reference.slice(0,240),verdict:evaluation.verdict,quorumSize:evaluation.quorumSize};try{await writeState3(paths.state,{...snapshot(state),pending})}catch(error93){let failed={...snapshot(state),lastAttemptId:attemptId,lastDigest:digest3};_internals192.appendAudit(paths.audit,{...received,event:"finalized",disposition:"council_pending_state_write_failed",transition:"stay",gateEffect:"none",nextState:failed});try{await writeState3(paths.state,failed)}catch{}throw error93}await evaluation.evidence?.commit(attemptId),_internals192.appendAudit(paths.audit,{...received,event:"finalized",disposition:evaluation.disposition.slice(0,80),transition:evaluation.transition,gateEffect:evaluation.gateEffect,verdict:evaluation.verdict,quorumSize:evaluation.quorumSize,evidenceRef:evaluation.evidence?.reference.slice(0,240),nextState:next}),await writeState3(paths.state,next);try{await evaluation.afterCommit?.()}catch{}return JSON.stringify({...evaluation.response,authoritativeRound,nextRound:next.currentRound,maxRoundsExhausted:next.maxRoundsExhausted},null,2)})}catch(error93){if(await recordUnscopedCouncilAttempt(input.directory,input.scope.kind,error93 instanceof CouncilRoundStateUncertainError?"council_round_state_uncertain":"council_round_state_persistence_failed",input.request,[],input.sessionID),error93 instanceof CouncilRoundStateUncertainError)return uncertainFailure(error93);return persistenceFailure2(authoritativeRound,error93)}}async function recordUnscopedCouncilAttempt(directory,level,disposition,raw,issues,sessionID){let path254=join203(directory,".swarm","council","attempts","unscoped.jsonl"),known=raw&&typeof raw==="object"?raw:{},fingerprint2=sha2564(JSON.stringify({level,taskIdType:typeof known.taskId,phaseType:typeof known.phase,phaseNumberType:typeof known.phaseNumber,roundNumberType:typeof known.roundNumber,verdictCount:Array.isArray(known.verdicts)?Math.min(6,known.verdicts.length):-1,issues:issues.slice(0,20).map((issue3)=>({path:issue3.path.slice(0,8).map(String),code:issue3.code.slice(0,40)}))}));try{return await _internals192.withLock(directory,join203("council","attempts","unscoped.jsonl"),STATE_AGENT,"unscoped",async()=>{mkdirSync65(dirname103(path254),{recursive:!0});let descriptor=openSync21(path254,"a");try{writeSync2(descriptor,`${JSON.stringify({version:VERSION,event:"unscoped",attemptId:_internals192.uuid(),timestamp:_internals192.now(),level,disposition:disposition.slice(0,80),fingerprint:fingerprint2,sessionHash:sessionID?sha2564(sessionID):void 0})}
6438
+ `).filter(Boolean).map((line)=>parseAuditRecord(line,expectedScope)),truncated:offset>0}}function initialState(){return{version:VERSION,currentRound:1,status:"open",maxRoundsExhausted:!1}}function snapshot(state){return{version:VERSION,currentRound:state.currentRound,status:state.status,maxRoundsExhausted:state.maxRoundsExhausted,lastAttemptId:state.lastAttemptId,lastDigest:state.lastDigest}}function sameSnapshot(left,right){return left.version===right.version&&left.currentRound===right.currentRound&&left.status===right.status&&left.maxRoundsExhausted===right.maxRoundsExhausted&&left.lastAttemptId===right.lastAttemptId&&left.lastDigest===right.lastDigest}function pendingTerminalMatches(state,record3){let pending=state.pending;if(!pending||record3.attemptId!==pending.attemptId||record3.digest!==pending.digest||record3.authoritativeRound!==pending.round||!record3.nextState)return!1;if(record3.event==="finalized")return record3.disposition===pending.disposition&&record3.transition===pending.transition&&record3.gateEffect===pending.gateEffect&&record3.verdict===pending.verdict&&record3.quorumSize===pending.quorumSize&&record3.evidenceRef===pending.evidenceRef&&sameSnapshot(record3.nextState,pending.nextState);if(record3.event!=="recovered")return!1;if(record3.disposition==="pending_evidence_recovered")return record3.transition===pending.transition&&record3.gateEffect===pending.gateEffect&&record3.verdict===pending.verdict&&record3.quorumSize===pending.quorumSize&&record3.evidenceRef===pending.evidenceRef&&sameSnapshot(record3.nextState,pending.nextState);if(record3.disposition!=="orphan_recovered")return!1;return record3.transition==="stay"&&record3.gateEffect==="none"&&record3.verdict===pending.verdict&&record3.quorumSize===pending.quorumSize&&record3.evidenceRef===pending.evidenceRef&&sameSnapshot(record3.nextState,{...snapshot(state),lastAttemptId:pending.attemptId,lastDigest:pending.digest})}function transitionState(state,attemptId,digest3,transition,maxRounds){let configuredLimit=Math.max(1,Math.min(MAX_ROUND,maxRounds)),limit=Math.max(state.currentRound,configuredLimit),currentRound=state.currentRound,status="open",maxRoundsExhausted=state.maxRoundsExhausted;if(transition==="advance")if(currentRound<limit)currentRound++,maxRoundsExhausted=!1;else maxRoundsExhausted=!0;else if(transition==="close")status="closed";return{version:VERSION,currentRound,status,maxRoundsExhausted,lastAttemptId:attemptId,lastDigest:digest3}}async function writeState3(path254,state){mkdirSync65(dirname103(path254),{recursive:!0}),await _internals192.atomicWrite(path254,JSON.stringify(state,null,2))}function baseRecord(input,attemptId,digest3,round,disposition){return{version:VERSION,attemptId,timestamp:_internals192.now(),scope:auditScope(input.scope),clientRound:input.clientRound,authoritativeRound:round,digest:digest3,sessionHash:input.sessionID?sha2564(input.sessionID):void 0,disposition:disposition.slice(0,80),verdictCount:Math.max(0,Math.min(5,input.verdictCount)),members:input.members.slice(0,5).map((member)=>member.slice(0,32))}}function latestRecord(records,attemptId){for(let index=records.length-1;index>=0;index--)if(records[index]?.attemptId===attemptId)return records[index];return}async function loadState2(paths,scope){if(existsSync130(paths.state))return parseState(readFileSync101(paths.state,"utf8"));let tail2=_internals192.readAuditTail(paths.audit,scope),records=tail2.records,recovered=recoverAuditHistory(tail2);if(tail2.truncated&&!recovered)throw new CouncilRoundStateUncertainError("council state is missing and the bounded audit tail has no recoverable transition");if(!recovered&&records.length>0)throw new CouncilRoundStateUncertainError("council state is missing and the audit has no complete transition");let state=recovered??initialState();return await writeState3(paths.state,state),state}function persistenceFailure2(round,error93){return JSON.stringify({success:!1,reason:"council_round_state_persistence_failed",authoritativeRound:round,message:error93 instanceof Error?error93.message:String(error93)},null,2)}function uncertainFailure(error93){return JSON.stringify({success:!1,reason:"council_round_state_uncertain",message:error93 instanceof Error?error93.message:String(error93)},null,2)}async function runCouncilAttempt(input){let paths=councilRoundStatePaths(input.directory,input.scope),authoritativeRound=1;try{return await _internals192.withLock(input.directory,paths.lock,STATE_AGENT,scopeToken(input.scope),async()=>{let state=await loadState2(paths,input.scope);if(state.pending){let tail2=_internals192.readAuditTail(paths.audit,input.scope),latest=latestRecord(tail2.records,state.pending.attemptId);if(tail2.truncated&&!latest)throw new CouncilRoundStateUncertainError("pending council attempt is outside the bounded audit tail");if(!latest)throw new CouncilRoundStateUncertainError("pending council attempt has no matching audit record");if((latest.event==="finalized"||latest.event==="recovered")&&latest.nextState){if(!pendingTerminalMatches(state,latest))throw new CouncilRoundStateUncertainError("terminal council audit contradicts pending state");state=latest.nextState}else{let committed=state.pending.evidenceExpected&&input.probePendingEvidence?await input.probePendingEvidence(state.pending.attemptId,state.pending.round,state.pending.evidenceRef):!1,recovered=committed?state.pending.nextState:{...snapshot(state),lastAttemptId:state.pending.attemptId,lastDigest:state.pending.digest};_internals192.appendAudit(paths.audit,{...baseRecord(input,state.pending.attemptId,state.pending.digest,state.pending.round,committed?"pending_evidence_recovered":"orphan_recovered"),event:"recovered",transition:committed?state.pending.transition:"stay",gateEffect:committed?state.pending.gateEffect:"none",verdict:state.pending.verdict,quorumSize:state.pending.quorumSize,evidenceRef:state.pending.evidenceRef,nextState:recovered}),state=recovered}await writeState3(paths.state,state)}authoritativeRound=state.currentRound;let digest3=councilRequestDigest(input.request,authoritativeRound),attemptId=_internals192.uuid(),received=baseRecord(input,attemptId,digest3,authoritativeRound,"received");if(_internals192.appendAudit(paths.audit,{...received,event:"received"}),input.clientRound!==void 0&&input.clientRound!==authoritativeRound){let next2={...snapshot(state),lastAttemptId:attemptId,lastDigest:digest3};return _internals192.appendAudit(paths.audit,{...received,event:"finalized",disposition:"council_round_mismatch",transition:"stay",gateEffect:"none",nextState:next2}),await writeState3(paths.state,next2),JSON.stringify({success:!1,reason:"council_round_mismatch",authoritativeRound,submittedRound:input.clientRound},null,2)}if(state.status==="closed"){let disposition=state.lastDigest===digest3?"duplicate_submission":"council_round_closed",next2={...snapshot(state),lastAttemptId:attemptId,lastDigest:digest3};return _internals192.appendAudit(paths.audit,{...received,event:"finalized",disposition,transition:"stay",gateEffect:"none",nextState:next2}),await writeState3(paths.state,next2),JSON.stringify({success:!1,reason:disposition,authoritativeRound},null,2)}let evaluation;try{evaluation=await input.evaluate(authoritativeRound)}catch(error93){evaluation={disposition:"council_evaluation_failed",response:{success:!1,reason:"council_evaluation_failed",message:error93 instanceof Error?error93.message:String(error93)},transition:"stay",gateEffect:"none"}}let next=transitionState(state,attemptId,digest3,evaluation.transition,input.maxRounds),pending={attemptId,digest:digest3,round:authoritativeRound,transition:evaluation.transition,nextState:next,disposition:evaluation.disposition.slice(0,80),gateEffect:evaluation.gateEffect,evidenceExpected:Boolean(evaluation.evidence),evidenceRef:evaluation.evidence?.reference.slice(0,240),verdict:evaluation.verdict,quorumSize:evaluation.quorumSize};try{await writeState3(paths.state,{...snapshot(state),pending})}catch(error93){let failed={...snapshot(state),lastAttemptId:attemptId,lastDigest:digest3};_internals192.appendAudit(paths.audit,{...received,event:"finalized",disposition:"council_pending_state_write_failed",transition:"stay",gateEffect:"none",nextState:failed});try{await writeState3(paths.state,failed)}catch{}throw error93}await evaluation.evidence?.commit(attemptId),_internals192.appendAudit(paths.audit,{...received,event:"finalized",disposition:evaluation.disposition.slice(0,80),transition:evaluation.transition,gateEffect:evaluation.gateEffect,verdict:evaluation.verdict,quorumSize:evaluation.quorumSize,evidenceRef:evaluation.evidence?.reference.slice(0,240),nextState:next}),await writeState3(paths.state,next);try{await evaluation.afterCommit?.()}catch{}return JSON.stringify({...evaluation.response,authoritativeRound,nextRound:next.currentRound,maxRoundsExhausted:next.maxRoundsExhausted},null,2)})}catch(error93){if(await recordUnscopedCouncilAttempt(input.directory,input.scope.kind,error93 instanceof CouncilRoundStateUncertainError?"council_round_state_uncertain":"council_round_state_persistence_failed",input.request,[],input.sessionID),error93 instanceof CouncilRoundStateUncertainError)return uncertainFailure(error93);return persistenceFailure2(authoritativeRound,error93)}}async function recordUnscopedCouncilAttempt(directory,level,disposition,raw,issues,sessionID){let path254=join203(directory,".swarm","council","attempts","unscoped.jsonl"),known=raw&&typeof raw==="object"?raw:{},fingerprint2=sha2564(JSON.stringify({level,taskIdType:typeof known.taskId,phaseType:typeof known.phase,phaseNumberType:typeof known.phaseNumber,roundNumberType:typeof known.roundNumber,verdictCount:Array.isArray(known.verdicts)?Math.min(6,known.verdicts.length):-1,issues:issues.slice(0,20).map((issue3)=>({path:issue3.path.slice(0,8).map(String),code:issue3.code.slice(0,40)}))}));try{return await _internals192.withLock(directory,join203("council","attempts","unscoped.jsonl"),STATE_AGENT,"unscoped",async()=>{mkdirSync65(dirname103(path254),{recursive:!0});let descriptor=openSync21(path254,"a");try{writeSync2(descriptor,`${JSON.stringify({version:VERSION,event:"unscoped",attemptId:_internals192.uuid(),timestamp:_internals192.now(),level,disposition:disposition.slice(0,80),fingerprint:fingerprint2,sessionHash:sessionID?sha2564(sessionID):void 0})}
6432
6439
  `,void 0,"utf8"),fsyncSync7(descriptor)}finally{closeSync21(descriptor)}}),null}catch(error93){return persistenceFailure2(1,error93)}}var _internals192={now:()=>new Date().toISOString(),uuid:randomUUID27,appendAudit:appendAudit2,readAuditTail,atomicWrite:atomicWriteFile,withLock:withEvidenceLock};var COUNCIL_DEFAULTS={enabled:!1,maxRounds:3,parallelTimeoutMs:30000,vetoPriority:!0,requireAllMembers:!1,minimumMembers:3,phaseConcernsAllowComplete:!0};function synthesizeCouncilVerdicts(taskId,swarmId,verdicts,criteria,roundNumber,config3={}){let cfg={...COUNCIL_DEFAULTS,...config3},timestamp=new Date().toISOString(),quorumSize=new Set(verdicts.map((v)=>v.agent)).size,rejectingMembers=verdicts.filter((v)=>v.verdict==="REJECT").map((v)=>v.agent),overallVerdict;if(cfg.vetoPriority&&rejectingMembers.length>0)overallVerdict="REJECT";else if(verdicts.some((v)=>v.verdict==="CONCERNS")||!cfg.vetoPriority&&rejectingMembers.length>0)overallVerdict="CONCERNS";else overallVerdict="APPROVE";let unresolvedConflicts=detectConflicts2(verdicts),rejectingSet=new Set(rejectingMembers),vetoFindings=verdicts.filter((v)=>rejectingSet.has(v.agent)).flatMap((v)=>v.findings),requiredFixes=vetoFindings.filter((f)=>f.severity==="CRITICAL"||f.severity==="HIGH"||f.severity==="MEDIUM"),advisoryFindings=[...vetoFindings.filter((f)=>f.severity==="LOW"),...verdicts.filter((v)=>!rejectingSet.has(v.agent)).flatMap((v)=>v.findings)],blockingConcernsCount=promoteBlockingConcerns(verdicts,rejectingSet,requiredFixes,advisoryFindings),allAssessedIds=new Set(verdicts.flatMap((v)=>v.criteriaAssessed)),allUnmetIds=new Set(verdicts.flatMap((v)=>v.criteriaUnmet)),allCriteriaMet=[...new Set((criteria?.criteria??[]).filter((c)=>c.mandatory).map((c)=>c.id))].every((id)=>allAssessedIds.has(id)&&!allUnmetIds.has(id)),unifiedFeedbackMd=buildUnifiedFeedback(taskId,overallVerdict,rejectingMembers,requiredFixes,advisoryFindings,unresolvedConflicts,roundNumber,cfg.maxRounds,blockingConcernsCount);return{taskId,swarmId,timestamp,overallVerdict,vetoedBy:rejectingMembers.length>0?rejectingMembers:null,memberVerdicts:verdicts,unresolvedConflicts,requiredFixes,advisoryFindings,unifiedFeedbackMd,roundNumber,allCriteriaMet,quorumSize,blockingConcernsCount,...verdicts.length===0&&{emptyVerdictsWarning:!0}}}function promoteBlockingConcerns(verdicts,rejectingSet,requiredFixes,advisoryFindings){let blocking=verdicts.filter((v)=>v.verdict==="CONCERNS"&&!rejectingSet.has(v.agent)).flatMap((v)=>v.findings).filter((f)=>f.severity==="CRITICAL"||f.severity==="HIGH");if(blocking.length===0)return 0;requiredFixes.push(...blocking);let blockingSet=new Set(blocking);for(let i=advisoryFindings.length-1;i>=0;i--)if(blockingSet.has(advisoryFindings[i]))advisoryFindings.splice(i,1);return blocking.length}function detectConflicts2(verdicts){let conflicts=[],locationMap=new Map;for(let verdict of verdicts)for(let finding of verdict.findings){let key=finding.location.toLowerCase();if(!key)continue;let entries=locationMap.get(key);if(entries)entries.push({agent:verdict.agent,detail:finding.detail});else locationMap.set(key,[{agent:verdict.agent,detail:finding.detail}])}for(let[location,entries]of locationMap){if(entries.length<2)continue;let addDirectives=entries.filter((e)=>/\badd\b|\binclude\b|\binsert\b/i.test(e.detail)),removeDirectives=entries.filter((e)=>/\bremove\b|\bdelete\b|\beliminate\b/i.test(e.detail));if(addDirectives.length>0&&removeDirectives.length>0)conflicts.push(`Conflict at ${location}: ${addDirectives.map((e)=>`${e.agent} says "${e.detail}"`).join(", ")} vs ${removeDirectives.map((e)=>`${e.agent} says "${e.detail}"`).join(", ")}`)}return conflicts}function buildUnifiedFeedback(taskId,verdict,vetoedBy,requiredFixes,advisoryFindings,conflicts,roundNumber,maxRounds,blockingConcernsCount=0){let lines=[`## Work Complete Council — Round ${roundNumber}/${maxRounds}`,`**Task:** ${taskId} **Overall verdict:** ${verdict}`,""];if(vetoedBy.length>0)lines.push(`> ⛔ **BLOCKED** by: ${vetoedBy.join(", ")}`),lines.push("");if(blockingConcernsCount>0)lines.push(`> ⚠️ **BLOCKING CONCERNS**: ${blockingConcernsCount} HIGH/CRITICAL finding(s) from CONCERNS members require investigation and resolution before advancement.`),lines.push("");if(requiredFixes.length>0){lines.push("### Required Fixes (must resolve before re-submission)");for(let f of requiredFixes)lines.push(`- **[${f.severity}]** \`${f.location}\` — ${f.detail}`,` _Evidence:_ ${f.evidence}`);lines.push("")}if(conflicts.length>0){lines.push("### Conflicts to Resolve"),lines.push("_The following reviewers gave contradictory instructions. Architect must resolve before sending to coder._");for(let c of conflicts)lines.push(`- ${c}`);lines.push("")}if(advisoryFindings.length>0){lines.push("### Advisory Findings (non-blocking)");for(let f of advisoryFindings)lines.push(`- **[${f.severity}]** \`${f.location}\` — ${f.detail}`);lines.push("")}if(verdict==="APPROVE")lines.push("> ✅ **All council members approved.** Work may advance to `complete`.");else if(roundNumber>=maxRounds)lines.push(`> ⚠️ **Max rounds (${maxRounds}) reached.** Escalate to user — do not auto-advance.`);return lines.join(`
6433
6440
  `)}function synthesizePhaseCouncilAdvisory(phaseNumber,phaseSummary,verdicts,roundNumber,config3={},_workingDir){let cfg={...COUNCIL_DEFAULTS,...config3},timestamp=new Date().toISOString(),scope="phase",quorumSize=new Set(verdicts.map((v)=>v.agent)).size,rejectingMembers=verdicts.filter((v)=>v.verdict==="REJECT").map((v)=>v.agent),overallVerdict;if(cfg.vetoPriority&&rejectingMembers.length>0)overallVerdict="REJECT";else if(verdicts.some((v)=>v.verdict==="CONCERNS")||!cfg.vetoPriority&&rejectingMembers.length>0)overallVerdict="CONCERNS";else overallVerdict="APPROVE";let unresolvedConflicts=detectConflicts2(verdicts),rejectingSet=new Set(rejectingMembers),vetoFindings=verdicts.filter((v)=>rejectingSet.has(v.agent)).flatMap((v)=>v.findings),requiredFixes=vetoFindings.filter((f)=>f.severity==="CRITICAL"||f.severity==="HIGH"||f.severity==="MEDIUM"),advisoryFindings=[...vetoFindings.filter((f)=>f.severity==="LOW"),...verdicts.filter((v)=>!rejectingSet.has(v.agent)).flatMap((v)=>v.findings)],blockingConcernsCount=promoteBlockingConcerns(verdicts,rejectingSet,requiredFixes,advisoryFindings),advisoryNotes=[];if(advisoryFindings.length>0)advisoryNotes.push(`Phase ${phaseNumber} council found ${advisoryFindings.length} advisory finding(s). Review before proceeding to next phase.`);if(verdicts.length<3)advisoryNotes.push(`Phase council quorum is ${verdicts.length} members — consider convening additional members for broader review coverage.`);let allCriteriaMet=new Set(verdicts.flatMap((v)=>v.criteriaUnmet)).size===0&&verdicts.length>0,unifiedFeedbackMd=buildPhaseCouncilFeedback(phaseNumber,phaseSummary,overallVerdict,rejectingMembers,requiredFixes,advisoryFindings,unresolvedConflicts,roundNumber,cfg.maxRounds,blockingConcernsCount),evidencePath=`.swarm/evidence/${phaseNumber}/phase-council.json`;return{phaseNumber,scope:"phase",timestamp,overallVerdict,vetoedBy:rejectingMembers.length>0?rejectingMembers:null,memberVerdicts:verdicts,unresolvedConflicts,requiredFixes,advisoryFindings,advisoryNotes,unifiedFeedbackMd,roundNumber,allCriteriaMet,quorumSize,blockingConcernsCount,evidencePath,phaseSummary}}function buildPhaseCouncilFeedback(phaseNumber,phaseSummary,verdict,vetoedBy,requiredFixes,advisoryFindings,conflicts,roundNumber,maxRounds,blockingConcernsCount=0){let lines=[`## Phase Council Review — Round ${roundNumber}/${maxRounds}`,`**Phase:** ${phaseNumber} **Overall verdict:** ${verdict}`,""];if(phaseSummary)lines.push(`**Phase Summary:** ${phaseSummary}`),lines.push("");if(vetoedBy.length>0)lines.push(`> ⛔ **BLOCKED** by: ${vetoedBy.join(", ")}`),lines.push("");if(blockingConcernsCount>0)lines.push(`> ⚠️ **BLOCKING CONCERNS**: ${blockingConcernsCount} HIGH/CRITICAL finding(s) from CONCERNS members require investigation and resolution before phase completion.`),lines.push("");if(requiredFixes.length>0){lines.push("### Required Fixes (must resolve before re-submission)");for(let f of requiredFixes)lines.push(`- **[${f.severity}]** \`${f.location}\` — ${f.detail}`,` _Evidence:_ ${f.evidence}`);lines.push("")}if(conflicts.length>0){lines.push("### Conflicts to Resolve"),lines.push("_The following reviewers gave contradictory instructions. Architect must resolve before sending to coder._");for(let c of conflicts)lines.push(`- ${c}`);lines.push("")}if(advisoryFindings.length>0){lines.push("### Advisory Findings (non-blocking)");for(let f of advisoryFindings)lines.push(`- **[${f.severity}]** \`${f.location}\` — ${f.detail}`);lines.push("")}if(verdict==="APPROVE")lines.push("> ✅ **Phase council approved.** Phase may proceed to completion.");else if(roundNumber>=maxRounds)lines.push(`> ⚠️ **Max rounds (${maxRounds}) reached.** Escalate to user — do not auto-advance.`);return lines.join(`
6434
6441
  `)}function synthesizeFinalCouncilAdvisory(projectSummary,verdicts,roundNumber,config3={}){let cfg={...COUNCIL_DEFAULTS,...config3},timestamp=new Date().toISOString(),quorumSize=new Set(verdicts.map((v)=>v.agent)).size,rejectingMembers=verdicts.filter((v)=>v.verdict==="REJECT").map((v)=>v.agent),overallVerdict;if(cfg.vetoPriority&&rejectingMembers.length>0)overallVerdict="REJECT";else if(verdicts.some((v)=>v.verdict==="CONCERNS")||!cfg.vetoPriority&&rejectingMembers.length>0)overallVerdict="CONCERNS";else overallVerdict="APPROVE";let unresolvedConflicts=detectConflicts2(verdicts),rejectingSet=new Set(rejectingMembers),vetoFindings=verdicts.filter((v)=>rejectingSet.has(v.agent)).flatMap((v)=>v.findings),requiredFixes=vetoFindings.filter((f)=>f.severity==="CRITICAL"||f.severity==="HIGH"||f.severity==="MEDIUM"),advisoryFindings=[...vetoFindings.filter((f)=>f.severity==="LOW"),...verdicts.filter((v)=>!rejectingSet.has(v.agent)).flatMap((v)=>v.findings)],blockingConcernsCount=promoteBlockingConcerns(verdicts,rejectingSet,requiredFixes,advisoryFindings),advisoryNotes=[];if(advisoryFindings.length>0)advisoryNotes.push(`Final council found ${advisoryFindings.length} advisory finding(s). Review before project close.`);if(quorumSize<3)advisoryNotes.push(`Final council quorum is ${quorumSize} members - dispatch additional project-scoped council members before closing the project.`);let allCriteriaMet=new Set(verdicts.flatMap((v)=>v.criteriaUnmet)).size===0&&verdicts.length>0,unifiedFeedbackMd=buildFinalCouncilFeedback(projectSummary,overallVerdict,rejectingMembers,requiredFixes,advisoryFindings,unresolvedConflicts,roundNumber,cfg.maxRounds,blockingConcernsCount);return{scope:"project",timestamp,overallVerdict,vetoedBy:rejectingMembers.length>0?rejectingMembers:null,memberVerdicts:verdicts,unresolvedConflicts,requiredFixes,advisoryFindings,advisoryNotes,unifiedFeedbackMd,roundNumber,allCriteriaMet,quorumSize,evidencePath:".swarm/evidence/final-council.json",blockingConcernsCount,projectSummary}}function buildFinalCouncilFeedback(projectSummary,verdict,vetoedBy,requiredFixes,advisoryFindings,conflicts,roundNumber,maxRounds,blockingConcernsCount=0){let lines=[`## Final Council Review - Round ${roundNumber}/${maxRounds}`,`**Scope:** completed project **Overall verdict:** ${verdict}`,""];if(projectSummary)lines.push(`**Project Summary:** ${projectSummary}`),lines.push("");if(blockingConcernsCount>0)lines.push(`> ⚠️ **BLOCKING CONCERNS**: ${blockingConcernsCount} HIGH/CRITICAL finding(s) from CONCERNS members require investigation and resolution before project close.`),lines.push("");if(vetoedBy.length>0)lines.push(`> BLOCKED: project close is blocked by ${vetoedBy.join(", ")}`),lines.push("");if(requiredFixes.length>0){lines.push("### Required Fixes (must resolve before project close)");for(let f of requiredFixes)lines.push(`- **[${f.severity}]** \`${f.location}\` - ${f.detail}`,` _Evidence:_ ${f.evidence}`);lines.push("")}if(conflicts.length>0){lines.push("### Conflicts to Resolve"),lines.push("_The following council members gave contradictory project-close instructions. Architect must resolve before closing the project._");for(let c of conflicts)lines.push(`- ${c}`);lines.push("")}if(advisoryFindings.length>0){lines.push("### Advisory Findings (non-blocking)");for(let f of advisoryFindings)lines.push(`- **[${f.severity}]** \`${f.location}\` - ${f.detail}`);lines.push("")}if(verdict==="APPROVE")lines.push("> Final council approved. Project may proceed to close.");else if(roundNumber>=maxRounds)lines.push(`> Max rounds (${maxRounds}) reached. Escalate to user - do not close the project automatically.`);return lines.join(`
6435
- `)}init_zod();init_task_file();init_project_boundary();import{existsSync as existsSync130,mkdirSync as mkdirSync66,readFileSync as readFileSync102}from"node:fs";import{join as join204}from"node:path";var COUNCIL_DIR=".swarm/council",CouncilCriteriaSchema=exports_external.object({taskId:exports_external.string(),criteria:exports_external.array(exports_external.object({id:exports_external.string(),description:exports_external.string(),mandatory:exports_external.boolean()})),declaredAt:exports_external.string()});async function writeCriteria(workingDir,taskId,criteria){assertProjectRoot(workingDir);let dir=join204(workingDir,COUNCIL_DIR);mkdirSync66(dir,{recursive:!0});let payload={taskId,criteria,declaredAt:new Date().toISOString()};await atomicWriteFile(join204(dir,`${safeId(taskId)}.json`),JSON.stringify(payload,null,2))}function readCriteria(workingDir,taskId){let filePath=join204(workingDir,COUNCIL_DIR,`${safeId(taskId)}.json`);if(!existsSync130(filePath))return null;try{return CouncilCriteriaSchema.parse(JSON.parse(readFileSync102(filePath,"utf-8")))}catch{return null}}function safeId(id){return id.replace(/[^a-zA-Z0-9_-]/g,"_")}init_state2();init_create_tool();init_resolve_working_directory();var ALL_MEMBERS=["critic","reviewer","sme","test_engineer","explorer"],FindingSchema=exports_external.object({severity:exports_external.enum(["CRITICAL","HIGH","MEDIUM","LOW"]),category:exports_external.string().min(1),location:exports_external.string(),detail:exports_external.string(),evidence:exports_external.string()}),VerdictSchema=exports_external.object({agent:exports_external.enum(ALL_MEMBERS),verdict:exports_external.enum(["APPROVE","CONCERNS","REJECT"]),confidence:exports_external.number().min(0).max(1),findings:exports_external.array(FindingSchema),criteriaAssessed:exports_external.array(exports_external.string()),criteriaUnmet:exports_external.array(exports_external.string()),durationMs:exports_external.number().nonnegative()}),ArgsSchema=exports_external.object({taskId:exports_external.string().min(1).regex(/^\d+\.\d+(\.\d+)*$/,'Task ID must be in N.M or N.M.P format (e.g. "1.1")'),swarmId:exports_external.string().min(1),roundNumber:exports_external.number().int().min(1).max(10).optional(),verdicts:exports_external.array(VerdictSchema).min(1).max(5),working_directory:exports_external.string().optional()});function invalidResponse(issues){return JSON.stringify({success:!1,reason:"invalid arguments",errors:issues.map((issue3)=>({path:issue3.path.join("."),message:issue3.message}))},null,2)}var submit_council_verdicts=createSwarmTool({description:"Submit pre-collected council member verdicts for synthesis. PREREQUISITE — "+"dispatch critic, reviewer, sme, test_engineer, and explorer as separate Agent tasks, then submit their real verdicts here. The server owns the current council round; roundNumber is only an optional expectation. Architect-only and config-gated.",args:{taskId:ArgsSchema.shape.taskId.describe('Task ID, e.g. "1.1"'),swarmId:ArgsSchema.shape.swarmId.describe('Swarm identifier, e.g. "mega"'),roundNumber:ArgsSchema.shape.roundNumber.describe("Optional expected server round. Omit to use the authoritative current round."),verdicts:ArgsSchema.shape.verdicts.describe("Collected CouncilMemberVerdict objects from dispatched council members."),working_directory:ArgsSchema.shape.working_directory.describe("Explicit project root directory.")},async execute(args2,directory,ctx){let parsed=ArgsSchema.safeParse(args2);if(!parsed.success)return await recordUnscopedCouncilAttempt(directory,"task","invalid_arguments",args2,parsed.error.issues.map((issue3)=>({path:issue3.path,code:issue3.code})),ctx?.sessionID)??invalidResponse(parsed.error.issues);let input=parsed.data,resolved=resolveWorkingDirectory(input.working_directory,directory);if(!resolved.success)return await recordUnscopedCouncilAttempt(directory,"task","invalid_working_directory",input,[],ctx?.sessionID)??JSON.stringify({success:!1,reason:resolved.message},null,2);let workingDir=resolved.directory,councilConfig=loadPluginConfig(workingDir).council,distinctMembers=new Set(input.verdicts.map((verdict)=>verdict.agent)),membersVoted=[...distinctMembers],membersAbsent=ALL_MEMBERS.filter((member)=>!distinctMembers.has(member)),session=ctx?.sessionID?getAgentSession(ctx.sessionID):void 0,councilWorkflowGeneration=session?.taskCouncilWorkflowGeneration?.get(input.taskId);return runCouncilAttempt({directory:workingDir,scope:{kind:"task",taskId:input.taskId},clientRound:input.roundNumber,maxRounds:councilConfig?.maxRounds??3,sessionID:ctx?.sessionID,request:input,verdictCount:input.verdicts.length,members:membersVoted,probePendingEvidence:async(attemptId,round)=>hasCouncilEvidenceAttempt(workingDir,input.taskId,attemptId,round),evaluate:async(authoritativeRound)=>{if(!councilConfig?.enabled)return{disposition:"council_disabled",response:{success:!1,reason:"council feature is disabled — set council.enabled: true in .opencode/opencode-swarm.json to enable"},transition:"stay",gateEffect:"none"};let effectiveMinimum=councilConfig.requireAllMembers?5:councilConfig.minimumMembers??3,requirementKey=`${input.taskId}:${authoritativeRound}`;if(session&&!session.pendingCouncilRequirements)session.pendingCouncilRequirements=new Map;let required3=session?.pendingCouncilRequirements?.get(requirementKey),stillMissingMembers=required3?[...required3].filter((member)=>!distinctMembers.has(member)):[];if(stillMissingMembers.length>0)return{disposition:"cherry_pick_detected",response:{success:!1,reason:"cherry_pick_detected",message:`Incomplete re-dispatch: ${stillMissingMembers.join(", ")} were required from the previous insufficient_quorum response but are still absent. Dispatch ALL absent members in one parallel batch.`,stillMissingMembers,membersProvided:membersVoted},transition:"stay",gateEffect:"none"};if(membersVoted.length<effectiveMinimum)return session?.pendingCouncilRequirements?.set(requirementKey,new Set(membersAbsent)),{disposition:"insufficient_quorum",response:{success:!1,reason:"insufficient_quorum",message:`Council quorum not met: ${membersVoted.length} of ${effectiveMinimum} required members provided verdicts. Members voted: [${membersVoted.join(", ")}]. Members absent: [${membersAbsent.join(", ")}]. Dispatch the absent council members before resubmitting.`,membersVoted,membersAbsent,quorumRequired:effectiveMinimum},transition:"stay",gateEffect:"none"};let synthesis=synthesizeCouncilVerdicts(input.taskId,input.swarmId,input.verdicts,readCriteria(workingDir,input.taskId),authoritativeRound,councilConfig),dissenters=synthesis.memberVerdicts.filter((verdict)=>verdict.verdict==="CONCERNS"||verdict.verdict==="REJECT").map((verdict)=>verdict.agent),updateRequirements=(transition2)=>{if(!session?.pendingCouncilRequirements)return;if(session.pendingCouncilRequirements.delete(requirementKey),transition2==="advance"&&dissenters.length>0){let nextRequiredRound=Math.min(authoritativeRound+1,Math.max(authoritativeRound,councilConfig.maxRounds));session.pendingCouncilRequirements.set(`${input.taskId}:${nextRequiredRound}`,new Set(dissenters))}};if(synthesis.overallVerdict==="CONCERNS"&&synthesis.blockingConcernsCount>0)return{disposition:"blocking_concerns_unresolved",response:{success:!1,reason:"blocking_concerns_unresolved",overallVerdict:synthesis.overallVerdict,blockingConcernsCount:synthesis.blockingConcernsCount,requiredFixes:synthesis.requiredFixes,unifiedFeedbackMd:synthesis.unifiedFeedbackMd,message:`Council returned CONCERNS with ${synthesis.blockingConcernsCount} blocking finding(s). Address every requiredFix and resubmit.`},transition:"advance",gateEffect:"blocked",verdict:synthesis.overallVerdict,quorumSize:membersVoted.length,afterCommit:()=>updateRequirements("advance")};let transition=synthesis.overallVerdict==="REJECT"?"advance":"close";return{disposition:`evaluated_${synthesis.overallVerdict.toLowerCase()}`,response:{success:!0,overallVerdict:synthesis.overallVerdict,vetoedBy:synthesis.vetoedBy,roundNumber:synthesis.roundNumber,allCriteriaMet:synthesis.allCriteriaMet,requiredFixesCount:synthesis.requiredFixes.length,advisoryFindingsCount:synthesis.advisoryFindings.length,unresolvedConflictsCount:synthesis.unresolvedConflicts.length,membersVoted,membersAbsent,quorumSize:membersVoted.length,quorumMet:!0,unifiedFeedbackMd:synthesis.unifiedFeedbackMd},transition,gateEffect:transition==="close"?"allowed":"blocked",verdict:synthesis.overallVerdict,quorumSize:membersVoted.length,evidence:{reference:`.swarm/evidence/${input.taskId}.json`,commit:async(attemptId)=>{if(councilWorkflowGeneration===void 0)throw Error(`TASK_COUNCIL_GENERATION_REQUIRED: dispatch council members for task ${input.taskId} before submitting their verdicts`);await writeCouncilEvidence(workingDir,synthesis,attemptId,councilWorkflowGeneration)}},afterCommit:async()=>{updateRequirements(transition);try{if(ctx?.sessionID&&session)pushCouncilAdvisory(session,synthesis)}catch{}}}}})}});init_zod();init_loader();import*as fs144 from"node:fs";import*as path254 from"node:path";var ADVISORY_HEADER="[general_council] (advisory; not blocking)";function pushGeneralCouncilAdvisory(session,result){if(!session)return;let body=renderAdvisoryBody(result);if(!body)return;pushAdvisory(session,`${ADVISORY_HEADER}
6442
+ `)}init_zod();init_task_file();init_project_boundary();import{existsSync as existsSync131,mkdirSync as mkdirSync66,readFileSync as readFileSync102}from"node:fs";import{join as join204}from"node:path";var COUNCIL_DIR=".swarm/council",CouncilCriteriaSchema=exports_external.object({taskId:exports_external.string(),criteria:exports_external.array(exports_external.object({id:exports_external.string(),description:exports_external.string(),mandatory:exports_external.boolean()})),declaredAt:exports_external.string()});async function writeCriteria(workingDir,taskId,criteria){assertProjectRoot(workingDir);let dir=join204(workingDir,COUNCIL_DIR);mkdirSync66(dir,{recursive:!0});let payload={taskId,criteria,declaredAt:new Date().toISOString()};await atomicWriteFile(join204(dir,`${safeId(taskId)}.json`),JSON.stringify(payload,null,2))}function readCriteria(workingDir,taskId){let filePath=join204(workingDir,COUNCIL_DIR,`${safeId(taskId)}.json`);if(!existsSync131(filePath))return null;try{return CouncilCriteriaSchema.parse(JSON.parse(readFileSync102(filePath,"utf-8")))}catch{return null}}function safeId(id){return id.replace(/[^a-zA-Z0-9_-]/g,"_")}init_state2();init_create_tool();init_resolve_working_directory();var ALL_MEMBERS=["critic","reviewer","sme","test_engineer","explorer"],FindingSchema=exports_external.object({severity:exports_external.enum(["CRITICAL","HIGH","MEDIUM","LOW"]),category:exports_external.string().min(1),location:exports_external.string(),detail:exports_external.string(),evidence:exports_external.string()}),VerdictSchema=exports_external.object({agent:exports_external.enum(ALL_MEMBERS),verdict:exports_external.enum(["APPROVE","CONCERNS","REJECT"]),confidence:exports_external.number().min(0).max(1),findings:exports_external.array(FindingSchema),criteriaAssessed:exports_external.array(exports_external.string()),criteriaUnmet:exports_external.array(exports_external.string()),durationMs:exports_external.number().nonnegative()}),ArgsSchema=exports_external.object({taskId:exports_external.string().min(1).regex(/^\d+\.\d+(\.\d+)*$/,'Task ID must be in N.M or N.M.P format (e.g. "1.1")'),swarmId:exports_external.string().min(1),roundNumber:exports_external.number().int().min(1).max(10).optional(),verdicts:exports_external.array(VerdictSchema).min(1).max(5),working_directory:exports_external.string().optional()});function invalidResponse(issues){return JSON.stringify({success:!1,reason:"invalid arguments",errors:issues.map((issue3)=>({path:issue3.path.join("."),message:issue3.message}))},null,2)}var submit_council_verdicts=createSwarmTool({description:"Submit pre-collected council member verdicts for synthesis. PREREQUISITE — "+"dispatch critic, reviewer, sme, test_engineer, and explorer as separate Agent tasks, then submit their real verdicts here. The server owns the current council round; roundNumber is only an optional expectation. Architect-only and config-gated.",args:{taskId:ArgsSchema.shape.taskId.describe('Task ID, e.g. "1.1"'),swarmId:ArgsSchema.shape.swarmId.describe('Swarm identifier, e.g. "mega"'),roundNumber:ArgsSchema.shape.roundNumber.describe("Optional expected server round. Omit to use the authoritative current round."),verdicts:ArgsSchema.shape.verdicts.describe("Collected CouncilMemberVerdict objects from dispatched council members."),working_directory:ArgsSchema.shape.working_directory.describe("Explicit project root directory.")},async execute(args2,directory,ctx){let parsed=ArgsSchema.safeParse(args2);if(!parsed.success)return await recordUnscopedCouncilAttempt(directory,"task","invalid_arguments",args2,parsed.error.issues.map((issue3)=>({path:issue3.path,code:issue3.code})),ctx?.sessionID)??invalidResponse(parsed.error.issues);let input=parsed.data,resolved=resolveWorkingDirectory(input.working_directory,directory);if(!resolved.success)return await recordUnscopedCouncilAttempt(directory,"task","invalid_working_directory",input,[],ctx?.sessionID)??JSON.stringify({success:!1,reason:resolved.message},null,2);let workingDir=resolved.directory,councilConfig=loadPluginConfig(workingDir).council,distinctMembers=new Set(input.verdicts.map((verdict)=>verdict.agent)),membersVoted=[...distinctMembers],membersAbsent=ALL_MEMBERS.filter((member)=>!distinctMembers.has(member)),session=ctx?.sessionID?getAgentSession(ctx.sessionID):void 0,councilWorkflowGeneration=session?.taskCouncilWorkflowGeneration?.get(input.taskId);return runCouncilAttempt({directory:workingDir,scope:{kind:"task",taskId:input.taskId},clientRound:input.roundNumber,maxRounds:councilConfig?.maxRounds??3,sessionID:ctx?.sessionID,request:input,verdictCount:input.verdicts.length,members:membersVoted,probePendingEvidence:async(attemptId,round)=>hasCouncilEvidenceAttempt(workingDir,input.taskId,attemptId,round),evaluate:async(authoritativeRound)=>{if(!councilConfig?.enabled)return{disposition:"council_disabled",response:{success:!1,reason:"council feature is disabled — set council.enabled: true in .opencode/opencode-swarm.json to enable"},transition:"stay",gateEffect:"none"};let effectiveMinimum=councilConfig.requireAllMembers?5:councilConfig.minimumMembers??3,requirementKey=`${input.taskId}:${authoritativeRound}`;if(session&&!session.pendingCouncilRequirements)session.pendingCouncilRequirements=new Map;let required3=session?.pendingCouncilRequirements?.get(requirementKey),stillMissingMembers=required3?[...required3].filter((member)=>!distinctMembers.has(member)):[];if(stillMissingMembers.length>0)return{disposition:"cherry_pick_detected",response:{success:!1,reason:"cherry_pick_detected",message:`Incomplete re-dispatch: ${stillMissingMembers.join(", ")} were required from the previous insufficient_quorum response but are still absent. Dispatch ALL absent members in one parallel batch.`,stillMissingMembers,membersProvided:membersVoted},transition:"stay",gateEffect:"none"};if(membersVoted.length<effectiveMinimum)return session?.pendingCouncilRequirements?.set(requirementKey,new Set(membersAbsent)),{disposition:"insufficient_quorum",response:{success:!1,reason:"insufficient_quorum",message:`Council quorum not met: ${membersVoted.length} of ${effectiveMinimum} required members provided verdicts. Members voted: [${membersVoted.join(", ")}]. Members absent: [${membersAbsent.join(", ")}]. Dispatch the absent council members before resubmitting.`,membersVoted,membersAbsent,quorumRequired:effectiveMinimum},transition:"stay",gateEffect:"none"};let synthesis=synthesizeCouncilVerdicts(input.taskId,input.swarmId,input.verdicts,readCriteria(workingDir,input.taskId),authoritativeRound,councilConfig),dissenters=synthesis.memberVerdicts.filter((verdict)=>verdict.verdict==="CONCERNS"||verdict.verdict==="REJECT").map((verdict)=>verdict.agent),updateRequirements=(transition2)=>{if(!session?.pendingCouncilRequirements)return;if(session.pendingCouncilRequirements.delete(requirementKey),transition2==="advance"&&dissenters.length>0){let nextRequiredRound=Math.min(authoritativeRound+1,Math.max(authoritativeRound,councilConfig.maxRounds));session.pendingCouncilRequirements.set(`${input.taskId}:${nextRequiredRound}`,new Set(dissenters))}};if(synthesis.overallVerdict==="CONCERNS"&&synthesis.blockingConcernsCount>0)return{disposition:"blocking_concerns_unresolved",response:{success:!1,reason:"blocking_concerns_unresolved",overallVerdict:synthesis.overallVerdict,blockingConcernsCount:synthesis.blockingConcernsCount,requiredFixes:synthesis.requiredFixes,unifiedFeedbackMd:synthesis.unifiedFeedbackMd,message:`Council returned CONCERNS with ${synthesis.blockingConcernsCount} blocking finding(s). Address every requiredFix and resubmit.`},transition:"advance",gateEffect:"blocked",verdict:synthesis.overallVerdict,quorumSize:membersVoted.length,afterCommit:()=>updateRequirements("advance")};let transition=synthesis.overallVerdict==="REJECT"?"advance":"close";return{disposition:`evaluated_${synthesis.overallVerdict.toLowerCase()}`,response:{success:!0,overallVerdict:synthesis.overallVerdict,vetoedBy:synthesis.vetoedBy,roundNumber:synthesis.roundNumber,allCriteriaMet:synthesis.allCriteriaMet,requiredFixesCount:synthesis.requiredFixes.length,advisoryFindingsCount:synthesis.advisoryFindings.length,unresolvedConflictsCount:synthesis.unresolvedConflicts.length,membersVoted,membersAbsent,quorumSize:membersVoted.length,quorumMet:!0,unifiedFeedbackMd:synthesis.unifiedFeedbackMd},transition,gateEffect:transition==="close"?"allowed":"blocked",verdict:synthesis.overallVerdict,quorumSize:membersVoted.length,evidence:{reference:`.swarm/evidence/${input.taskId}.json`,commit:async(attemptId)=>{if(councilWorkflowGeneration===void 0)throw Error(`TASK_COUNCIL_GENERATION_REQUIRED: dispatch council members for task ${input.taskId} before submitting their verdicts`);await writeCouncilEvidence(workingDir,synthesis,attemptId,councilWorkflowGeneration)}},afterCommit:async()=>{updateRequirements(transition);try{if(ctx?.sessionID&&session)pushCouncilAdvisory(session,synthesis)}catch{}}}}})}});init_zod();init_loader();import*as fs144 from"node:fs";import*as path254 from"node:path";var ADVISORY_HEADER="[general_council] (advisory; not blocking)";function pushGeneralCouncilAdvisory(session,result){if(!session)return;let body=renderAdvisoryBody(result);if(!body)return;pushAdvisory(session,`${ADVISORY_HEADER}
6436
6443
  ${body}`)}function renderAdvisoryBody(result){return result.synthesis.trim()}var EXPLICIT_DISAGREEMENT_MARKERS=["i disagree with","i would push back on","contrary to","this contradicts","unlike "],STRONG_RECOMMENDATION_MARKERS=["recommend","best approach","should use","i suggest","the answer is","the right choice is"];function tokenize3(text){return text.toLowerCase().replace(/[^a-z0-9\s]/g," ").split(/\s+/).filter((t)=>t.length>=3)}function termOverlap(a,b){let tokensA=new Set(tokenize3(a)),tokensB=new Set(tokenize3(b));if(tokensA.size===0||tokensB.size===0)return 0;let intersection3=0;for(let t of tokensA)if(tokensB.has(t))intersection3++;let union3=tokensA.size+tokensB.size-intersection3;return union3===0?0:intersection3/union3}function extractMarkerSentence(response,markers){let lower=response.toLowerCase(),sentences=response.split(/(?<=[.!?])\s+/);for(let sentence of sentences){let sentLower=sentence.toLowerCase();if(markers.some((m)=>sentLower.includes(m)))return sentence.trim()}for(let marker of markers){let idx=lower.indexOf(marker);if(idx!==-1){let slice=response.slice(idx,idx+200);return slice.split(/\n/)[0]?.trim()??slice.trim()}}return null}function dedupeByTopic(disagreements){let result=[];for(let d of disagreements){let topicLower=d.topic.toLowerCase(),existing=result.find((r)=>r.topic.toLowerCase().includes(topicLower)||topicLower.includes(r.topic.toLowerCase()));if(existing){for(let pos of d.positions)if(!existing.positions.some((p)=>p.memberId===pos.memberId))existing.positions.push(pos)}else result.push(d)}return result}function detectExplicitMarkers(responses){let out=[];for(let member of responses){let markerSentence=extractMarkerSentence(member.response,EXPLICIT_DISAGREEMENT_MARKERS);if(!markerSentence)continue;let position={memberId:member.memberId,claim:markerSentence,evidence:member.sources[0]?.url??"(no source cited in marker sentence)"};out.push({topic:markerSentence.slice(0,80),positions:[position]})}return out}function extractRecommendation(response){return extractMarkerSentence(response,STRONG_RECOMMENDATION_MARKERS)}function detectClaimDivergence(responses){let recommendations=[];for(let member of responses){let rec=extractRecommendation(member.response);if(!rec)continue;recommendations.push({memberId:member.memberId,text:rec,evidence:member.sources[0]?.url??"(no source cited)"})}let out=[];for(let i=0;i<recommendations.length;i++)for(let j=i+1;j<recommendations.length;j++){let a=recommendations[i],b=recommendations[j];if(!a||!b)continue;let topicOverlap=termOverlap(a.text,b.text);if(topicOverlap>0.4)continue;if(topicOverlap>0&&topicOverlap<0.3){let topic=`${a.text.slice(0,50)} vs ${b.text.slice(0,50)}`;out.push({topic,positions:[{memberId:a.memberId,claim:a.text,evidence:a.evidence},{memberId:b.memberId,claim:b.text,evidence:b.evidence}]})}}return out}function detectDisagreements(responses){if(!Array.isArray(responses)||responses.length<2)return[];let safeResponses=responses.filter((r)=>typeof r?.memberId==="string"&&typeof r?.response==="string"),explicit=detectExplicitMarkers(safeResponses),divergent=detectClaimDivergence(safeResponses),combined=[...explicit,...divergent];return dedupeByTopic(combined).slice(0,10)}var CONSENSUS_WEIGHT_THRESHOLD=0.6;function tokenize4(text){return text.toLowerCase().replace(/[^a-z0-9\s]/g," ").split(/\s+/).filter((t)=>t.length>=4)}function similarity(a,b){let tokensA=new Set(tokenize4(a)),tokensB=new Set(tokenize4(b));if(tokensA.size===0||tokensB.size===0)return 0;let intersection3=0;for(let t of tokensA)if(tokensB.has(t))intersection3++;let union3=tokensA.size+tokensB.size-intersection3;return union3===0?0:intersection3/union3}function extractClaims(response){return response.split(/(?<=[.!?])\s+/).map((s)=>s.trim()).filter((s)=>s.length>=30&&s.length<=400)}function buildConsensusClusters(responses){if(responses.length<2)return[];let totalMembers=responses.length,clusters=[];for(let member of responses){let confidence=clamp012(member.confidence??0.5),claims=extractClaims(member.response??"");for(let claim of claims){let assigned=!1;for(let cluster of clusters)if(similarity(cluster.representative,claim)>=0.5){if(!cluster.memberIds.has(member.memberId))cluster.weightedAgreement+=confidence,cluster.memberIds.add(member.memberId);if(claim.length>cluster.representative.length)cluster.representative=claim;assigned=!0;break}if(!assigned)clusters.push({representative:claim,weightedAgreement:confidence,memberIds:new Set([member.memberId])})}}return clusters.filter((c)=>c.memberIds.size>=2&&c.weightedAgreement/totalMembers>=CONSENSUS_WEIGHT_THRESHOLD).sort((a,b)=>b.weightedAgreement-a.weightedAgreement||b.memberIds.size-a.memberIds.size).map((c)=>c.representative)}function clamp012(n){if(typeof n!=="number"||Number.isNaN(n))return 0;if(n<0)return 0;if(n>1)return 1;return n}function computePersistingDisagreements(disagreements,round2){if(disagreements.length===0)return[];if(round2.length===0)return disagreements;return disagreements.filter((d)=>{let disputants=new Set(d.positions.map((p)=>p.memberId));return!round2.some((r)=>{if(!disputants.has(r.memberId))return!1;if(!r.disagreementTopics?.includes(d.topic))return!1;return/\bconcede\b/i.test(r.response??"")})})}function dedupeSources(round1,round2){let seen=new Set,out=[],allSources=[...round1,...round2].flatMap((r)=>r.sources??[]);for(let src of allSources){if(!src?.url)continue;if(seen.has(src.url))continue;seen.add(src.url),out.push(src)}return out}function renderSynthesisMarkdown(question,mode,roundsCompleted,members,consensusPoints,persistingDisagreements,allSources){let memberLines=members.map((m)=>`- ${m.memberId} (${m.model}, ${m.role})`).join(`
6437
6444
  `),consensusBlock=consensusPoints.length>0?consensusPoints.map((c)=>`- ${c}`).join(`
6438
6445
  `):"_No consensus claims reached the weighted-agreement threshold._",disagreementsBlock=persistingDisagreements.length>0?persistingDisagreements.map((d)=>`- **${d.topic}**
@@ -6559,14 +6566,14 @@ ${scanResult.findings.filter((f)=>f.severity==="error").map((f)=>`- ${f.pattern}
6559
6566
 
6560
6567
  [Content follows with threats marked for LLM awareness]
6561
6568
 
6562
- ${scanResult.neutralized}`;return result}catch(error93){if(error93 instanceof DOMException&&(error93.name==="TimeoutError"||error93.name==="AbortError")){if(attempt>=GITINGEST_MAX_RETRIES)throw Error("gitingest request timed out");let backoff=200*2**attempt;await delay3(backoff);continue}if(error93 instanceof Error&&error93.message.startsWith("gitingest "))throw error93;if(attempt<GITINGEST_MAX_RETRIES){let backoff=200*2**attempt;await delay3(backoff);continue}throw error93}throw Error("gitingest request failed after retries")}var gitingest=createSwarmTool({description:"Fetch a GitHub repository's full content via gitingest.com. Returns summary, directory tree, and file contents optimized for LLM analysis. Use when you need to understand an external repository's structure or code.",args:{url:exports_external.string().describe("GitHub repository URL (e.g., https://github.com/owner/repo)"),maxFileSize:exports_external.number().optional().describe("Maximum file size in bytes to include (default: 50000)"),pattern:exports_external.string().optional().describe("Glob pattern to filter files (e.g., '*.ts' or 'src/**/*.py')"),patternType:exports_external.enum(["include","exclude"]).optional().describe("Whether pattern includes or excludes matching files (default: exclude)")},async execute(args2,_directory,_ctx){return fetchGitingest(args2)}});init_zod();init_create_tool();init_path_security();import*as fs155 from"node:fs";import*as path267 from"node:path";var MAX_FILE_PATH_LENGTH2=500,MAX_SYMBOL_LENGTH=256,MAX_FILE_SIZE_BYTES7=1048576,MAX_CONSUMERS=100,SUPPORTED_EXTENSIONS2=[".ts",".tsx",".js",".jsx",".mjs",".cjs"],BINARY_SIGNATURES2=[0,2303741511,4292411360,1195984440,626017350,1347093252],BINARY_PREFIX_BYTES2=4,BINARY_NULL_CHECK_BYTES2=8192,BINARY_NULL_THRESHOLD2=0.1;function validateFileInput(file3){if(!file3||file3.length===0)return"file is required";if(file3.length>MAX_FILE_PATH_LENGTH2)return`file exceeds maximum length of ${MAX_FILE_PATH_LENGTH2}`;if(containsControlChars(file3))return"file contains control characters";if(containsPathTraversal(file3))return"file contains path traversal";return null}function validateSymbolInput(symbol3){if(symbol3===void 0||symbol3==="")return null;if(symbol3.length>MAX_SYMBOL_LENGTH)return`symbol exceeds maximum length of ${MAX_SYMBOL_LENGTH}`;if(containsControlChars(symbol3))return"symbol contains control characters";if(containsPathTraversal(symbol3))return"symbol contains path traversal";return null}function isBinaryFile3(filePath,buffer){let ext=path267.extname(filePath).toLowerCase();if(ext===".json"||ext===".md"||ext===".txt")return!1;if(buffer.length>=BINARY_PREFIX_BYTES2){let uint323=buffer.subarray(0,BINARY_PREFIX_BYTES2).readUInt32BE(0);for(let sig of BINARY_SIGNATURES2)if(uint323===sig)return!0}let nullCount=0,checkLen=Math.min(buffer.length,BINARY_NULL_CHECK_BYTES2);for(let i=0;i<checkLen;i++)if(buffer[i]===0)nullCount++;return nullCount>checkLen*BINARY_NULL_THRESHOLD2}function parseImports(content,targetFile,targetSymbol){let imports=[],_resolvedTarget;try{_resolvedTarget=path267.resolve(targetFile)}catch{_resolvedTarget=targetFile}let targetBasename=path267.basename(targetFile,path267.extname(targetFile)),targetWithExt=targetFile,targetWithoutExt=targetFile.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i,""),normalizedTargetWithExt=path267.normalize(targetWithExt).replace(/\\/g,"/"),normalizedTargetWithoutExt=path267.normalize(targetWithoutExt).replace(/\\/g,"/"),importRegex=/import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;for(let match=importRegex.exec(content);match!==null;match=importRegex.exec(content)){let modulePath=match[1]||match[2]||match[3];if(!modulePath)continue;let lineNum=(content.substring(0,match.index).match(/\n/g)||[]).length+1,matchedString=match[0],importType="named";if(matchedString.includes("* as"))importType="namespace";else if(/^import\s+\{/.test(matchedString))importType="named";else if(/^import\s+\w+\s+from\s+['"`]/.test(matchedString))importType="default";else if(/^import\s+['"`]/m.test(matchedString))importType="sideeffect";else if(matchedString.includes("require("))importType="require";let _normalizedModule=modulePath.replace(/^\.\//,"").replace(/^\.\.\\/,"../"),isMatch=!1,_targetDir=path267.dirname(targetFile),targetExt=path267.extname(targetFile),targetBasenameNoExt=path267.basename(targetFile,targetExt),moduleNormalized=modulePath.replace(/\\/g,"/").replace(/^\.\//,""),moduleName=modulePath.split(/[/\\]/).pop()||"",moduleNameNoExt=moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i,"");if(modulePath===targetBasename||modulePath===targetBasenameNoExt||modulePath===`./${targetBasename}`||modulePath===`./${targetBasenameNoExt}`||modulePath===`../${targetBasename}`||modulePath===`../${targetBasenameNoExt}`||moduleNormalized===normalizedTargetWithExt||moduleNormalized===normalizedTargetWithoutExt||modulePath.endsWith(`/${targetBasename}`)||modulePath.endsWith(`\\${targetBasename}`)||modulePath.endsWith(`/${targetBasenameNoExt}`)||modulePath.endsWith(`\\${targetBasenameNoExt}`)||moduleNameNoExt===targetBasenameNoExt||`./${moduleNameNoExt}`===targetBasenameNoExt||moduleName===targetBasename||moduleName===targetBasenameNoExt)isMatch=!0;if(isMatch&&targetSymbol)if(importType==="namespace"||importType==="sideeffect")isMatch=!1;else{let namedMatch=matchedString.match(/import\s+\{([\s\S]*?)\}\s+from/);if(namedMatch)isMatch=namedMatch[1].split(",").map((s)=>{let parts=s.trim().split(/\s+as\s+/i),originalName=parts[0].trim(),aliasName=parts[1]?.trim();return{original:originalName,alias:aliasName}}).some(({original,alias})=>original===targetSymbol||alias===targetSymbol);else if(importType==="default"){let defaultMatch=matchedString.match(/^import\s+(\w+)\s+from/m);if(defaultMatch)isMatch=defaultMatch[1]===targetSymbol}}if(isMatch)imports.push({line:lineNum,imports:modulePath,importType,raw:matchedString.trim()})}return imports}var SKIP_DIRECTORIES4=new Set(["node_modules",".git","dist","build","out","coverage",".next",".nuxt",".cache","vendor",".svn",".hg"]);function findSourceFiles2(dir,files=[],stats2={skippedDirs:[],skippedFiles:0,fileErrors:[]}){let entries;try{entries=fs155.readdirSync(dir)}catch(e){return stats2.fileErrors.push({path:dir,reason:e instanceof Error?e.message:"readdir failed"}),files}entries.sort((a,b)=>a.toLowerCase().localeCompare(b.toLowerCase()));for(let entry of entries){if(SKIP_DIRECTORIES4.has(entry)){stats2.skippedDirs.push(path267.join(dir,entry));continue}let fullPath=path267.join(dir,entry),stat21;try{stat21=fs155.statSync(fullPath)}catch(e){stats2.fileErrors.push({path:fullPath,reason:e instanceof Error?e.message:"stat failed"});continue}if(stat21.isDirectory())findSourceFiles2(fullPath,files,stats2);else if(stat21.isFile()){let ext=path267.extname(fullPath).toLowerCase();if(SUPPORTED_EXTENSIONS2.includes(ext))files.push(fullPath)}}return files}var imports=createSwarmTool({description:"Find all reverse dependencies (consumers) that import from a given file. Returns JSON with file path, line numbers, and import metadata for each consumer. Use this to understand who depends on a module before refactoring.",args:{file:exports_external.string().describe('Source file path to find importers for (e.g., "./src/utils.ts")'),symbol:exports_external.string().optional().describe('Optional specific symbol to filter imports (e.g., "MyClass")')},async execute(args2,_directory,_ctx){let typedArgs=args2,file3,symbol3;try{if(typedArgs&&typeof typedArgs==="object")file3=typedArgs.file,symbol3=typedArgs.symbol}catch{}if(file3===void 0)return JSON.stringify({error:"invalid arguments: file is required",target:"",symbol:void 0,consumers:[],count:0},null,2);let fileValidationError=validateFileInput(file3);if(fileValidationError){let errorResult={error:`invalid file: ${fileValidationError}`,target:file3,symbol:symbol3,consumers:[],count:0};return JSON.stringify(errorResult,null,2)}let symbolValidationError=validateSymbolInput(symbol3);if(symbolValidationError){let errorResult={error:`invalid symbol: ${symbolValidationError}`,target:file3,symbol:symbol3,consumers:[],count:0};return JSON.stringify(errorResult,null,2)}try{let targetFile=path267.resolve(file3);if(!fs155.existsSync(targetFile)){let errorResult={error:`target file not found: ${file3}`,target:file3,symbol:symbol3,consumers:[],count:0};return JSON.stringify(errorResult,null,2)}if(!fs155.statSync(targetFile).isFile())return JSON.stringify({error:"target must be a file, not a directory",target:file3,symbol:symbol3,consumers:[],count:0},null,2);let baseDir=path267.dirname(targetFile),filesToScan=findSourceFiles2(baseDir,[],{skippedDirs:[],skippedFiles:0,fileErrors:[]}).filter((f)=>f!==targetFile).sort((a,b)=>a.toLowerCase().localeCompare(b.toLowerCase())).slice(0,MAX_CONSUMERS*10),consumers=[],skippedFileCount=0,totalMatchesFound=0;for(let filePath of filesToScan){if(consumers.length>=MAX_CONSUMERS)break;try{if(fs155.statSync(filePath).size>MAX_FILE_SIZE_BYTES7){skippedFileCount++;continue}let buffer=fs155.readFileSync(filePath);if(isBinaryFile3(filePath,buffer)){skippedFileCount++;continue}let content=buffer.toString("utf-8"),fileImports=parseImports(content,targetFile,symbol3);for(let imp of fileImports){if(totalMatchesFound++,consumers.length>=MAX_CONSUMERS)continue;if(consumers.some((c)=>c.file===filePath&&c.line===imp.line))continue;consumers.push({file:filePath,line:imp.line,imports:imp.imports,importType:imp.importType,raw:imp.raw})}}catch(_e){skippedFileCount++}}let result={target:file3,symbol:symbol3,consumers,count:consumers.length},parts=[];if(filesToScan.length>=MAX_CONSUMERS*10)parts.push(`Scanned ${filesToScan.length} files`);if(skippedFileCount>0)parts.push(`${skippedFileCount} skipped (size/binary/errors)`);if(consumers.length>=MAX_CONSUMERS){let hidden=totalMatchesFound-consumers.length;if(hidden>0)parts.push(`Results limited to ${MAX_CONSUMERS} consumers (${hidden} hidden)`);else parts.push(`Results limited to ${MAX_CONSUMERS} consumers`)}if(parts.length>0)result.message=`${parts.join("; ")}.`;return JSON.stringify(result,null,2)}catch(e){let errorResult={error:e instanceof Error?`scan failed: ${e.message||"internal error"}`:"scan failed: unknown error",target:file3,symbol:symbol3,consumers:[],count:0};return JSON.stringify(errorResult,null,2)}}});init_zod();init_config();init_knowledge_reinforcement();init_knowledge_store();init_knowledge_types();init_knowledge_validator();init_cohort_identity();init_worktree_identity();init_manager();init_create_tool();import{randomUUID as randomUUID30}from"node:crypto";var VALID_CATEGORIES2=["process","architecture","tooling","security","testing","debugging","performance","integration","todo","other"],KNOWLEDGE_ADD_FIELD_CAP=20;function mergeLessonTags(tagsInput,lesson){return dedupeCapped([...Array.isArray(tagsInput)?tagsInput:[],...inferTags(lesson)],{cap:KNOWLEDGE_ADD_FIELD_CAP})}function strArray(v){return Array.isArray(v)?dedupeCapped(v,{cap:KNOWLEDGE_ADD_FIELD_CAP}):void 0}var knowledge_add=createSwarmTool({allowWorkingDirectoryOverride:!0,description:"Store a new lesson in the knowledge base for future reference. The lesson will be available for retrieval via knowledge_recall.",args:{lesson:exports_external.string().min(15).max(280).describe("The lesson to store (15-280 characters)"),category:exports_external.enum(VALID_CATEGORIES2).describe("Knowledge category for the lesson"),tags:exports_external.array(exports_external.string()).optional().describe("Optional tags for better searchability"),scope:exports_external.string().optional().describe("Scope of the lesson (global or stack:<name>)"),applies_to_agents:exports_external.array(exports_external.string()).optional().describe('Agent roles this lesson applies to (e.g. ["coder"]). REQUIRED (or applies_to_tools) for the lesson to become active.'),applies_to_tools:exports_external.array(exports_external.string()).optional().describe('Tool names this lesson applies to (e.g. ["edit","bash"]). REQUIRED (or applies_to_agents) for the lesson to become active.'),required_actions:exports_external.array(exports_external.string()).optional().describe("Concrete actions to always take. At least one predicate field (required_actions / forbidden_actions / verification_checks) is REQUIRED for the lesson to become active."),forbidden_actions:exports_external.array(exports_external.string()).optional().describe("Concrete actions to never take."),verification_checks:exports_external.array(exports_external.string()).optional().describe("Checks a reviewer can run to verify compliance.")},execute:async(args2,directory)=>{let lessonInput,categoryInput,tagsInput,scopeInput;try{if(args2&&typeof args2==="object"){let obj2=args2;lessonInput=obj2.lesson,categoryInput=obj2.category,tagsInput=obj2.tags,scopeInput=obj2.scope}}catch{}if(typeof lessonInput!=="string")return JSON.stringify({success:!1,error:"lesson must be a string"});let lesson=lessonInput;if(lesson.length<15||lesson.length>280)return JSON.stringify({success:!1,error:"lesson must be between 15 and 280 characters"});if(typeof categoryInput!=="string")return JSON.stringify({success:!1,error:"category must be a string"});let category=categoryInput;if(!VALID_CATEGORIES2.includes(category))return JSON.stringify({success:!1,error:`category must be one of: ${VALID_CATEGORIES2.join(", ")}`});let tags=mergeLessonTags(tagsInput,lesson),scope=typeof scopeInput==="string"&&scopeInput.length>0?scopeInput:"global",obj=args2&&typeof args2==="object"?args2:{},actionable={applies_to_agents:strArray(obj.applies_to_agents),applies_to_tools:strArray(obj.applies_to_tools),required_actions:strArray(obj.required_actions),forbidden_actions:strArray(obj.forbidden_actions),verification_checks:strArray(obj.verification_checks)},shape=validateActionableFields(actionable);if(!shape.valid)return JSON.stringify({success:!1,error:`invalid actionability fields: ${shape.errors.join("; ")}`});let project_name="",phase_number=1;try{let plan=await loadPlan(directory);if(project_name=plan?.title??"",typeof plan?.current_phase==="number")phase_number=plan.current_phase}catch{}let producer=null;try{let[worktreeId,cohort]=await Promise.all([resolveWorktreeId(directory),resolveCohortId(directory)]);producer={cohort_id:cohort.cohortId,worktree_id:worktreeId}}catch{}let nowIso2=new Date().toISOString(),entry={id:randomUUID30(),tier:"swarm",lesson,category,tags,scope,confidence:0.5,status:"candidate",confirmed_by:[],project_name,retrieval_outcomes:{applied_count:0,succeeded_after_count:0,failed_after_count:0},schema_version:KNOWLEDGE_SCHEMA_VERSION,producer,revision:1,content_hash:computeContentHash(lesson),created_at:nowIso2,updated_at:nowIso2,auto_generated:!1,hive_eligible:!1,...actionable},config3,dedupThreshold=0.6;try{if(config3=loadPluginConfigWithMeta(directory).config,dedupThreshold=config3.knowledge?.dedup_threshold??0.6,config3.knowledge?.validation_enabled!==!1){let validation2=validateLesson(lesson,[],{category,scope,confidence:0.5});if(!validation2.valid)return JSON.stringify({success:!1,error:`Validation failed: ${validation2.reason}`})}}catch{}let actionability=validateActionability(entry);if(!actionability.actionable){try{await appendUnactionable(directory,entry,actionability.reason??"unactionable")}catch{}return JSON.stringify({success:!1,quarantined:!0,id:entry.id,reason:actionability.reason,hint:"Provide at least one of required_actions/forbidden_actions/verification_checks AND at least one of applies_to_agents/applies_to_tools, then retry."})}try{let maxEntries=config3?.knowledge?.swarm_max_entries??100,duplicateResponse;if(await transactKnowledge(resolveSwarmKnowledgePath(directory),(existingEntries)=>{let activeDuplicate=findActiveSwarmNearDuplicate(lesson,existingEntries,dedupThreshold);if(activeDuplicate){let result=reinforceSwarmKnowledgeEntry(activeDuplicate,{phase_number,confirmed_at:new Date().toISOString(),project_name});return duplicateResponse={id:activeDuplicate.id,reinforced:result.reinforced,idempotent:result.reason==="already_confirmed_phase",inactive:!1},result.reinforced?existingEntries:null}let inactiveDuplicate=findNearDuplicate(lesson,existingEntries,dedupThreshold);if(inactiveDuplicate)return duplicateResponse={id:inactiveDuplicate.id,reinforced:!1,idempotent:!1,inactive:!0},null;let updated=[...existingEntries,entry];if(updated.length>maxEntries)return updated.slice(updated.length-maxEntries);return updated}),duplicateResponse){if(duplicateResponse.inactive)return JSON.stringify({success:!1,id:duplicateResponse.id,message:"near-duplicate of inactive existing entry"});return JSON.stringify({success:!0,id:duplicateResponse.id,reinforced:duplicateResponse.reinforced,idempotent:duplicateResponse.idempotent,message:duplicateResponse.reinforced?"near-duplicate reinforced existing entry":"near-duplicate already confirmed for this phase"})}}catch(err){let message=err instanceof Error?err.message:"Unknown error";return JSON.stringify({success:!1,error:message})}return JSON.stringify({success:!0,id:entry.id,category})}});init_zod();init_knowledge_store();init_knowledge_validator();init_skill_invalidator();init_curation_policy();init_logger();init_create_tool();var MODES2=["archive","quarantine","purge"],TIERS=["swarm","hive"];async function loadConfigForPolicy(directory){let{KnowledgeConfigSchema:KnowledgeConfigSchema2}=await Promise.resolve().then(() => (init_schema(),exports_schema)),{loadPluginConfigWithMeta:loadPluginConfigWithMeta2}=await Promise.resolve().then(() => (init_config(),exports_config)),{config:loaded}=loadPluginConfigWithMeta2(directory);return KnowledgeConfigSchema2.parse(loaded.knowledge??{})}var knowledge_archive=createSwarmTool({allowWorkingDirectoryOverride:!0,description:"Archive (default), quarantine, or purge a swarm or hive knowledge entry by ID, appending an immutable audit tombstone. 'archive'/'quarantine' set the entry status reversibly and hide it from recall; 'purge' hard-deletes and requires allow_purge:true.",args:{id:exports_external.string().min(1).describe("UUID of the knowledge entry"),tier:exports_external.enum(TIERS).optional().describe("Knowledge tier to modify; default 'swarm'"),reason:exports_external.string().min(1).max(500).describe("Why the entry is being archived/quarantined/purged"),evidence:exports_external.string().max(1000).optional().describe('Supporting evidence (e.g. "ignored 8 times, contradicted by tests")'),mode:exports_external.enum(MODES2).optional().describe("Default 'archive'"),allow_purge:exports_external.boolean().optional().describe("Admin flag required when mode='purge'")},execute:async(args2,directory,ctx)=>{let a=args2??{},id=typeof a.id==="string"?a.id:"";if(!id)return JSON.stringify({success:!1,error:"id must be a non-empty string"});let reason=typeof a.reason==="string"?a.reason:"";if(!reason)return JSON.stringify({success:!1,error:"reason is required"});let evidence2=typeof a.evidence==="string"?a.evidence:void 0,tier=a.tier==="hive"?"hive":"swarm",mode=a.mode==="quarantine"||a.mode==="purge"?a.mode:"archive";if(mode==="purge"&&a.allow_purge!==!0)return JSON.stringify({success:!1,error:"purge requires allow_purge:true (admin flag)"});if(mode==="quarantine"){if(tier==="hive")return JSON.stringify({success:!1,error:"quarantine via the archive tool is swarm-only; use tier:'swarm' or the /swarm knowledge quarantine command"});try{let target=(await readKnowledge(resolveSwarmKnowledgePath(directory))).find((e)=>e.id===id);if(!target)return JSON.stringify({success:!1,message:"entry not found"});let reportedBy=ctx?.agent==="architect"?"architect":"user",curationInput={directory,action:"quarantine",entryId:id,reason,evidenceScope:"cohort-wide",actorRole:ctx?.agent},curationContext={config:await loadConfigForPolicy(directory),entry:target};await quarantineEntry(directory,id,reason,reportedBy,{input:curationInput,context:curationContext})}catch(err){return JSON.stringify({success:!1,error:err instanceof Error?err.message:"Unknown error during quarantine"})}return JSON.stringify({success:!0,id,tier,mode,status:"quarantined"})}let knowledgePath=tier==="hive"?resolveHiveKnowledgePath2():resolveSwarmKnowledgePath(directory),found=!1,previousStatus,now2=new Date().toISOString(),resultStatus,casExpectedRevision,casExpectedContentHash;if(tier==="swarm"){let preEntries;try{preEntries=await readKnowledge(knowledgePath)}catch(err){let message=err instanceof Error?err.message:"Unknown error";return JSON.stringify({success:!1,error:message})}let preTarget=preEntries.find((e)=>e.id===id)??null;if(preTarget){let curationInput={directory,action:mode,entryId:id,reason,evidenceScope:"cohort-wide",actorRole:ctx?.agent},curationContext={config:await loadConfigForPolicy(directory),entry:preTarget},decision=await authorizeCuration(curationInput,curationContext);if(!decision.authorized)return JSON.stringify({success:!1,error:`Cohort-safety policy blocked this ${mode}: ${decision.detail}`,basis:decision.basis});casExpectedRevision=preTarget.revision,casExpectedContentHash=preTarget.content_hash}}if(tier==="swarm"&&mode==="archive"){let casResult;try{casResult=await transactKnowledgeWithCas(directory,knowledgePath,id,casExpectedRevision,casExpectedContentHash,(entry)=>{if(found=!0,previousStatus=entry.status,entry.status==="archived")return resultStatus="archived",null;return resultStatus="archived",{mutated:{...entry,status:"archived",archived_from:entry.status,archived_at:now2,updated_at:now2}}})}catch(err){return JSON.stringify({success:!1,error:err instanceof Error?err.message:"Unknown error"})}if(casResult.casFailed)return JSON.stringify({success:!1,error:"entry changed since authorization (revision/content-hash mismatch); stale archive plan rejected"})}else try{await transactKnowledge(knowledgePath,(entries)=>{let target=entries.find((e)=>e.id===id);if(!target)return null;if(found=!0,previousStatus=target.status,mode==="purge")return warn(`[knowledge_archive] PURGE: hard-deleting ${tier} entry id=${id} actor=${ctx?.agent??"unknown"} reason=${reason}`),resultStatus="purged",entries.filter((e)=>e.id!==id);if(target.status==="archived")return resultStatus="archived",entries;return resultStatus="archived",entries.map((e)=>e.id===id?{...e,status:"archived",archived_from:target.status,archived_at:now2,updated_at:now2}:e)})}catch(err){return JSON.stringify({success:!1,error:err instanceof Error?err.message:"Unknown error"})}if(!found)return JSON.stringify({success:!1,message:"entry not found"});return await writeArchiveTombstoneAndInvalidateSkills({directory,entryId:id,tier,actor:ctx?.agent??"unknown",reason,mode,evidence:evidence2,previousStatus,sourceLabel:"knowledge-archive"}),JSON.stringify({success:!0,id,tier,mode,previous_status:previousStatus,status:resultStatus})}});init_zod();init_config();init_knowledge_store();init_create_tool();import{existsSync as existsSync137}from"node:fs";var DEFAULT_LIMIT=10,MAX_LESSON_LENGTH=200,VALID_CATEGORIES3=["process","architecture","tooling","security","testing","debugging","performance","integration","todo","other"],VALID_STATUSES=["candidate","established","promoted","archived"],DEFAULT_QUERY_STATUSES=new Set(["established","promoted"]),VALID_TIERS=["swarm","hive","all"];function validateTierInput(tier){if(typeof tier!=="string")return null;let normalized=tier.toLowerCase().trim();if(VALID_TIERS.includes(normalized))return normalized;return null}function validateStatusInput(status){if(typeof status!=="string")return null;let normalized=status.toLowerCase().trim();if(VALID_STATUSES.includes(normalized))return normalized;return null}function validateCategoryInput(category){if(typeof category!=="string")return null;let normalized=category.toLowerCase().trim();if(VALID_CATEGORIES3.includes(normalized))return normalized;return null}function validateMinScore(score){if(typeof score==="number"&&!Number.isNaN(score))return Math.max(0,Math.min(1,score));if(typeof score==="string"){let parsed=Number.parseFloat(score);if(!Number.isNaN(parsed))return Math.max(0,Math.min(1,parsed))}return null}function validateLimit(limit){if(typeof limit==="number"&&!Number.isNaN(limit)&&limit>0)return Math.min(limit,100);if(typeof limit==="string"){let parsed=Number.parseInt(limit,10);if(!Number.isNaN(parsed)&&parsed>0)return Math.min(parsed,100)}return DEFAULT_LIMIT}async function readSwarmKnowledge(directory){let swarmPath3=resolveSwarmKnowledgePath(directory);if(!existsSync137(swarmPath3))return[];return readKnowledge(swarmPath3)}async function readHiveKnowledge(){let hivePath=resolveHiveKnowledgePath2();if(!existsSync137(hivePath))return[];return readKnowledge(hivePath)}function filterSwarmEntries(entries,filters,suppressedLessons,scopeFilter){return entries.filter((entry)=>{if(filters.status){if(entry.status!==filters.status)return!1}else if(!DEFAULT_QUERY_STATUSES.has(entry.status))return!1;if(filters.category&&entry.category!==filters.category)return!1;if(filters.minScore!==void 0&&entry.confidence<filters.minScore)return!1;if(scopeFilter&&scopeFilter.length>0){let entryScope=entry.scope??"global";if(!scopeFilter.some((pattern)=>entryScope===pattern))return!1}if(suppressedLessons.has(normalize5(entry.lesson)))return!1;return!0})}function filterHiveEntries(entries,filters,suppressedLessons,scopeFilter){return entries.filter((entry)=>{if(filters.status){if(entry.status!==filters.status)return!1}else if(!DEFAULT_QUERY_STATUSES.has(entry.status))return!1;if(filters.category&&entry.category!==filters.category)return!1;if(filters.minScore!==void 0&&entry.confidence<filters.minScore)return!1;if(scopeFilter&&scopeFilter.length>0){let entryScope=entry.scope??"global";if(!scopeFilter.some((pattern)=>entryScope===pattern))return!1}if(suppressedLessons.has(normalize5(entry.lesson)))return!1;return!0})}function truncateLesson3(lesson,maxLength){if(lesson.length<=maxLength)return lesson;return`${lesson.slice(0,maxLength-3)}...`}function formatSwarmEntry(entry){let lines=[];return lines.push(`[${entry.tier.toUpperCase()}] ${entry.id}`),lines.push(` Lesson: ${truncateLesson3(entry.lesson,MAX_LESSON_LENGTH)}`),lines.push(` Category: ${entry.category}`),lines.push(` Status: ${entry.status}`),lines.push(` Confidence: ${entry.confidence.toFixed(2)}`),lines.push(` Confirmed by: ${entry.confirmed_by.length} phase(s)`),lines.push(` Project: ${entry.project_name}`),lines.join(`
6569
+ ${scanResult.neutralized}`;return result}catch(error93){if(error93 instanceof DOMException&&(error93.name==="TimeoutError"||error93.name==="AbortError")){if(attempt>=GITINGEST_MAX_RETRIES)throw Error("gitingest request timed out");let backoff=200*2**attempt;await delay3(backoff);continue}if(error93 instanceof Error&&error93.message.startsWith("gitingest "))throw error93;if(attempt<GITINGEST_MAX_RETRIES){let backoff=200*2**attempt;await delay3(backoff);continue}throw error93}throw Error("gitingest request failed after retries")}var gitingest=createSwarmTool({description:"Fetch a GitHub repository's full content via gitingest.com. Returns summary, directory tree, and file contents optimized for LLM analysis. Use when you need to understand an external repository's structure or code.",args:{url:exports_external.string().describe("GitHub repository URL (e.g., https://github.com/owner/repo)"),maxFileSize:exports_external.number().optional().describe("Maximum file size in bytes to include (default: 50000)"),pattern:exports_external.string().optional().describe("Glob pattern to filter files (e.g., '*.ts' or 'src/**/*.py')"),patternType:exports_external.enum(["include","exclude"]).optional().describe("Whether pattern includes or excludes matching files (default: exclude)")},async execute(args2,_directory,_ctx){return fetchGitingest(args2)}});init_zod();init_create_tool();init_path_security();import*as fs155 from"node:fs";import*as path267 from"node:path";var MAX_FILE_PATH_LENGTH2=500,MAX_SYMBOL_LENGTH=256,MAX_FILE_SIZE_BYTES7=1048576,MAX_CONSUMERS=100,SUPPORTED_EXTENSIONS2=[".ts",".tsx",".js",".jsx",".mjs",".cjs"],BINARY_SIGNATURES2=[0,2303741511,4292411360,1195984440,626017350,1347093252],BINARY_PREFIX_BYTES2=4,BINARY_NULL_CHECK_BYTES2=8192,BINARY_NULL_THRESHOLD2=0.1;function validateFileInput(file3){if(!file3||file3.length===0)return"file is required";if(file3.length>MAX_FILE_PATH_LENGTH2)return`file exceeds maximum length of ${MAX_FILE_PATH_LENGTH2}`;if(containsControlChars(file3))return"file contains control characters";if(containsPathTraversal(file3))return"file contains path traversal";return null}function validateSymbolInput(symbol3){if(symbol3===void 0||symbol3==="")return null;if(symbol3.length>MAX_SYMBOL_LENGTH)return`symbol exceeds maximum length of ${MAX_SYMBOL_LENGTH}`;if(containsControlChars(symbol3))return"symbol contains control characters";if(containsPathTraversal(symbol3))return"symbol contains path traversal";return null}function isBinaryFile3(filePath,buffer){let ext=path267.extname(filePath).toLowerCase();if(ext===".json"||ext===".md"||ext===".txt")return!1;if(buffer.length>=BINARY_PREFIX_BYTES2){let uint323=buffer.subarray(0,BINARY_PREFIX_BYTES2).readUInt32BE(0);for(let sig of BINARY_SIGNATURES2)if(uint323===sig)return!0}let nullCount=0,checkLen=Math.min(buffer.length,BINARY_NULL_CHECK_BYTES2);for(let i=0;i<checkLen;i++)if(buffer[i]===0)nullCount++;return nullCount>checkLen*BINARY_NULL_THRESHOLD2}function parseImports(content,targetFile,targetSymbol){let imports=[],_resolvedTarget;try{_resolvedTarget=path267.resolve(targetFile)}catch{_resolvedTarget=targetFile}let targetBasename=path267.basename(targetFile,path267.extname(targetFile)),targetWithExt=targetFile,targetWithoutExt=targetFile.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i,""),normalizedTargetWithExt=path267.normalize(targetWithExt).replace(/\\/g,"/"),normalizedTargetWithoutExt=path267.normalize(targetWithoutExt).replace(/\\/g,"/"),importRegex=/import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;for(let match=importRegex.exec(content);match!==null;match=importRegex.exec(content)){let modulePath=match[1]||match[2]||match[3];if(!modulePath)continue;let lineNum=(content.substring(0,match.index).match(/\n/g)||[]).length+1,matchedString=match[0],importType="named";if(matchedString.includes("* as"))importType="namespace";else if(/^import\s+\{/.test(matchedString))importType="named";else if(/^import\s+\w+\s+from\s+['"`]/.test(matchedString))importType="default";else if(/^import\s+['"`]/m.test(matchedString))importType="sideeffect";else if(matchedString.includes("require("))importType="require";let _normalizedModule=modulePath.replace(/^\.\//,"").replace(/^\.\.\\/,"../"),isMatch=!1,_targetDir=path267.dirname(targetFile),targetExt=path267.extname(targetFile),targetBasenameNoExt=path267.basename(targetFile,targetExt),moduleNormalized=modulePath.replace(/\\/g,"/").replace(/^\.\//,""),moduleName=modulePath.split(/[/\\]/).pop()||"",moduleNameNoExt=moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i,"");if(modulePath===targetBasename||modulePath===targetBasenameNoExt||modulePath===`./${targetBasename}`||modulePath===`./${targetBasenameNoExt}`||modulePath===`../${targetBasename}`||modulePath===`../${targetBasenameNoExt}`||moduleNormalized===normalizedTargetWithExt||moduleNormalized===normalizedTargetWithoutExt||modulePath.endsWith(`/${targetBasename}`)||modulePath.endsWith(`\\${targetBasename}`)||modulePath.endsWith(`/${targetBasenameNoExt}`)||modulePath.endsWith(`\\${targetBasenameNoExt}`)||moduleNameNoExt===targetBasenameNoExt||`./${moduleNameNoExt}`===targetBasenameNoExt||moduleName===targetBasename||moduleName===targetBasenameNoExt)isMatch=!0;if(isMatch&&targetSymbol)if(importType==="namespace"||importType==="sideeffect")isMatch=!1;else{let namedMatch=matchedString.match(/import\s+\{([\s\S]*?)\}\s+from/);if(namedMatch)isMatch=namedMatch[1].split(",").map((s)=>{let parts=s.trim().split(/\s+as\s+/i),originalName=parts[0].trim(),aliasName=parts[1]?.trim();return{original:originalName,alias:aliasName}}).some(({original,alias})=>original===targetSymbol||alias===targetSymbol);else if(importType==="default"){let defaultMatch=matchedString.match(/^import\s+(\w+)\s+from/m);if(defaultMatch)isMatch=defaultMatch[1]===targetSymbol}}if(isMatch)imports.push({line:lineNum,imports:modulePath,importType,raw:matchedString.trim()})}return imports}var SKIP_DIRECTORIES4=new Set(["node_modules",".git","dist","build","out","coverage",".next",".nuxt",".cache","vendor",".svn",".hg"]);function findSourceFiles2(dir,files=[],stats2={skippedDirs:[],skippedFiles:0,fileErrors:[]}){let entries;try{entries=fs155.readdirSync(dir)}catch(e){return stats2.fileErrors.push({path:dir,reason:e instanceof Error?e.message:"readdir failed"}),files}entries.sort((a,b)=>a.toLowerCase().localeCompare(b.toLowerCase()));for(let entry of entries){if(SKIP_DIRECTORIES4.has(entry)){stats2.skippedDirs.push(path267.join(dir,entry));continue}let fullPath=path267.join(dir,entry),stat21;try{stat21=fs155.statSync(fullPath)}catch(e){stats2.fileErrors.push({path:fullPath,reason:e instanceof Error?e.message:"stat failed"});continue}if(stat21.isDirectory())findSourceFiles2(fullPath,files,stats2);else if(stat21.isFile()){let ext=path267.extname(fullPath).toLowerCase();if(SUPPORTED_EXTENSIONS2.includes(ext))files.push(fullPath)}}return files}var imports=createSwarmTool({description:"Find all reverse dependencies (consumers) that import from a given file. Returns JSON with file path, line numbers, and import metadata for each consumer. Use this to understand who depends on a module before refactoring.",args:{file:exports_external.string().describe('Source file path to find importers for (e.g., "./src/utils.ts")'),symbol:exports_external.string().optional().describe('Optional specific symbol to filter imports (e.g., "MyClass")')},async execute(args2,_directory,_ctx){let typedArgs=args2,file3,symbol3;try{if(typedArgs&&typeof typedArgs==="object")file3=typedArgs.file,symbol3=typedArgs.symbol}catch{}if(file3===void 0)return JSON.stringify({error:"invalid arguments: file is required",target:"",symbol:void 0,consumers:[],count:0},null,2);let fileValidationError=validateFileInput(file3);if(fileValidationError){let errorResult={error:`invalid file: ${fileValidationError}`,target:file3,symbol:symbol3,consumers:[],count:0};return JSON.stringify(errorResult,null,2)}let symbolValidationError=validateSymbolInput(symbol3);if(symbolValidationError){let errorResult={error:`invalid symbol: ${symbolValidationError}`,target:file3,symbol:symbol3,consumers:[],count:0};return JSON.stringify(errorResult,null,2)}try{let targetFile=path267.resolve(file3);if(!fs155.existsSync(targetFile)){let errorResult={error:`target file not found: ${file3}`,target:file3,symbol:symbol3,consumers:[],count:0};return JSON.stringify(errorResult,null,2)}if(!fs155.statSync(targetFile).isFile())return JSON.stringify({error:"target must be a file, not a directory",target:file3,symbol:symbol3,consumers:[],count:0},null,2);let baseDir=path267.dirname(targetFile),filesToScan=findSourceFiles2(baseDir,[],{skippedDirs:[],skippedFiles:0,fileErrors:[]}).filter((f)=>f!==targetFile).sort((a,b)=>a.toLowerCase().localeCompare(b.toLowerCase())).slice(0,MAX_CONSUMERS*10),consumers=[],skippedFileCount=0,totalMatchesFound=0;for(let filePath of filesToScan){if(consumers.length>=MAX_CONSUMERS)break;try{if(fs155.statSync(filePath).size>MAX_FILE_SIZE_BYTES7){skippedFileCount++;continue}let buffer=fs155.readFileSync(filePath);if(isBinaryFile3(filePath,buffer)){skippedFileCount++;continue}let content=buffer.toString("utf-8"),fileImports=parseImports(content,targetFile,symbol3);for(let imp of fileImports){if(totalMatchesFound++,consumers.length>=MAX_CONSUMERS)continue;if(consumers.some((c)=>c.file===filePath&&c.line===imp.line))continue;consumers.push({file:filePath,line:imp.line,imports:imp.imports,importType:imp.importType,raw:imp.raw})}}catch(_e){skippedFileCount++}}let result={target:file3,symbol:symbol3,consumers,count:consumers.length},parts=[];if(filesToScan.length>=MAX_CONSUMERS*10)parts.push(`Scanned ${filesToScan.length} files`);if(skippedFileCount>0)parts.push(`${skippedFileCount} skipped (size/binary/errors)`);if(consumers.length>=MAX_CONSUMERS){let hidden=totalMatchesFound-consumers.length;if(hidden>0)parts.push(`Results limited to ${MAX_CONSUMERS} consumers (${hidden} hidden)`);else parts.push(`Results limited to ${MAX_CONSUMERS} consumers`)}if(parts.length>0)result.message=`${parts.join("; ")}.`;return JSON.stringify(result,null,2)}catch(e){let errorResult={error:e instanceof Error?`scan failed: ${e.message||"internal error"}`:"scan failed: unknown error",target:file3,symbol:symbol3,consumers:[],count:0};return JSON.stringify(errorResult,null,2)}}});init_zod();init_config();init_knowledge_reinforcement();init_knowledge_store();init_knowledge_types();init_knowledge_validator();init_cohort_identity();init_worktree_identity();init_manager();init_create_tool();import{randomUUID as randomUUID30}from"node:crypto";var VALID_CATEGORIES2=["process","architecture","tooling","security","testing","debugging","performance","integration","todo","other"],KNOWLEDGE_ADD_FIELD_CAP=20;function mergeLessonTags(tagsInput,lesson){return dedupeCapped([...Array.isArray(tagsInput)?tagsInput:[],...inferTags(lesson)],{cap:KNOWLEDGE_ADD_FIELD_CAP})}function strArray(v){return Array.isArray(v)?dedupeCapped(v,{cap:KNOWLEDGE_ADD_FIELD_CAP}):void 0}var knowledge_add=createSwarmTool({allowWorkingDirectoryOverride:!0,description:"Store a new lesson in the knowledge base for future reference. The lesson will be available for retrieval via knowledge_recall.",args:{lesson:exports_external.string().min(15).max(280).describe("The lesson to store (15-280 characters)"),category:exports_external.enum(VALID_CATEGORIES2).describe("Knowledge category for the lesson"),tags:exports_external.array(exports_external.string()).optional().describe("Optional tags for better searchability"),scope:exports_external.string().optional().describe("Scope of the lesson (global or stack:<name>)"),applies_to_agents:exports_external.array(exports_external.string()).optional().describe('Agent roles this lesson applies to (e.g. ["coder"]). REQUIRED (or applies_to_tools) for the lesson to become active.'),applies_to_tools:exports_external.array(exports_external.string()).optional().describe('Tool names this lesson applies to (e.g. ["edit","bash"]). REQUIRED (or applies_to_agents) for the lesson to become active.'),required_actions:exports_external.array(exports_external.string()).optional().describe("Concrete actions to always take. At least one predicate field (required_actions / forbidden_actions / verification_checks) is REQUIRED for the lesson to become active."),forbidden_actions:exports_external.array(exports_external.string()).optional().describe("Concrete actions to never take."),verification_checks:exports_external.array(exports_external.string()).optional().describe("Checks a reviewer can run to verify compliance.")},execute:async(args2,directory)=>{let lessonInput,categoryInput,tagsInput,scopeInput;try{if(args2&&typeof args2==="object"){let obj2=args2;lessonInput=obj2.lesson,categoryInput=obj2.category,tagsInput=obj2.tags,scopeInput=obj2.scope}}catch{}if(typeof lessonInput!=="string")return JSON.stringify({success:!1,error:"lesson must be a string"});let lesson=lessonInput;if(lesson.length<15||lesson.length>280)return JSON.stringify({success:!1,error:"lesson must be between 15 and 280 characters"});if(typeof categoryInput!=="string")return JSON.stringify({success:!1,error:"category must be a string"});let category=categoryInput;if(!VALID_CATEGORIES2.includes(category))return JSON.stringify({success:!1,error:`category must be one of: ${VALID_CATEGORIES2.join(", ")}`});let tags=mergeLessonTags(tagsInput,lesson),scope=typeof scopeInput==="string"&&scopeInput.length>0?scopeInput:"global",obj=args2&&typeof args2==="object"?args2:{},actionable={applies_to_agents:strArray(obj.applies_to_agents),applies_to_tools:strArray(obj.applies_to_tools),required_actions:strArray(obj.required_actions),forbidden_actions:strArray(obj.forbidden_actions),verification_checks:strArray(obj.verification_checks)},shape=validateActionableFields(actionable);if(!shape.valid)return JSON.stringify({success:!1,error:`invalid actionability fields: ${shape.errors.join("; ")}`});let project_name="",phase_number=1;try{let plan=await loadPlan(directory);if(project_name=plan?.title??"",typeof plan?.current_phase==="number")phase_number=plan.current_phase}catch{}let producer=null;try{let[worktreeId,cohort]=await Promise.all([resolveWorktreeId(directory),resolveCohortId(directory)]);producer={cohort_id:cohort.cohortId,worktree_id:worktreeId}}catch{}let nowIso2=new Date().toISOString(),entry={id:randomUUID30(),tier:"swarm",lesson,category,tags,scope,confidence:0.5,status:"candidate",confirmed_by:[],project_name,retrieval_outcomes:{applied_count:0,succeeded_after_count:0,failed_after_count:0},schema_version:KNOWLEDGE_SCHEMA_VERSION,producer,revision:1,content_hash:computeContentHash(lesson),created_at:nowIso2,updated_at:nowIso2,auto_generated:!1,hive_eligible:!1,...actionable},config3,dedupThreshold=0.6;try{if(config3=loadPluginConfigWithMeta(directory).config,dedupThreshold=config3.knowledge?.dedup_threshold??0.6,config3.knowledge?.validation_enabled!==!1){let validation2=validateLesson(lesson,[],{category,scope,confidence:0.5});if(!validation2.valid)return JSON.stringify({success:!1,error:`Validation failed: ${validation2.reason}`})}}catch{}let actionability=validateActionability(entry);if(!actionability.actionable){try{await appendUnactionable(directory,entry,actionability.reason??"unactionable")}catch{}return JSON.stringify({success:!1,quarantined:!0,id:entry.id,reason:actionability.reason,hint:"Provide at least one of required_actions/forbidden_actions/verification_checks AND at least one of applies_to_agents/applies_to_tools, then retry."})}try{let maxEntries=config3?.knowledge?.swarm_max_entries??100,duplicateResponse;if(await transactKnowledge(resolveSwarmKnowledgePath(directory),(existingEntries)=>{let activeDuplicate=findActiveSwarmNearDuplicate(lesson,existingEntries,dedupThreshold);if(activeDuplicate){let result=reinforceSwarmKnowledgeEntry(activeDuplicate,{phase_number,confirmed_at:new Date().toISOString(),project_name});return duplicateResponse={id:activeDuplicate.id,reinforced:result.reinforced,idempotent:result.reason==="already_confirmed_phase",inactive:!1},result.reinforced?existingEntries:null}let inactiveDuplicate=findNearDuplicate(lesson,existingEntries,dedupThreshold);if(inactiveDuplicate)return duplicateResponse={id:inactiveDuplicate.id,reinforced:!1,idempotent:!1,inactive:!0},null;let updated=[...existingEntries,entry];if(updated.length>maxEntries)return updated.slice(updated.length-maxEntries);return updated}),duplicateResponse){if(duplicateResponse.inactive)return JSON.stringify({success:!1,id:duplicateResponse.id,message:"near-duplicate of inactive existing entry"});return JSON.stringify({success:!0,id:duplicateResponse.id,reinforced:duplicateResponse.reinforced,idempotent:duplicateResponse.idempotent,message:duplicateResponse.reinforced?"near-duplicate reinforced existing entry":"near-duplicate already confirmed for this phase"})}}catch(err){let message=err instanceof Error?err.message:"Unknown error";return JSON.stringify({success:!1,error:message})}return JSON.stringify({success:!0,id:entry.id,category})}});init_zod();init_knowledge_store();init_knowledge_validator();init_skill_invalidator();init_curation_policy();init_logger();init_create_tool();var MODES2=["archive","quarantine","purge"],TIERS=["swarm","hive"];async function loadConfigForPolicy(directory){let{KnowledgeConfigSchema:KnowledgeConfigSchema2}=await Promise.resolve().then(() => (init_schema(),exports_schema)),{loadPluginConfigWithMeta:loadPluginConfigWithMeta2}=await Promise.resolve().then(() => (init_config(),exports_config)),{config:loaded}=loadPluginConfigWithMeta2(directory);return KnowledgeConfigSchema2.parse(loaded.knowledge??{})}var knowledge_archive=createSwarmTool({allowWorkingDirectoryOverride:!0,description:"Archive (default), quarantine, or purge a swarm or hive knowledge entry by ID, appending an immutable audit tombstone. 'archive'/'quarantine' set the entry status reversibly and hide it from recall; 'purge' hard-deletes and requires allow_purge:true.",args:{id:exports_external.string().min(1).describe("UUID of the knowledge entry"),tier:exports_external.enum(TIERS).optional().describe("Knowledge tier to modify; default 'swarm'"),reason:exports_external.string().min(1).max(500).describe("Why the entry is being archived/quarantined/purged"),evidence:exports_external.string().max(1000).optional().describe('Supporting evidence (e.g. "ignored 8 times, contradicted by tests")'),mode:exports_external.enum(MODES2).optional().describe("Default 'archive'"),allow_purge:exports_external.boolean().optional().describe("Admin flag required when mode='purge'")},execute:async(args2,directory,ctx)=>{let a=args2??{},id=typeof a.id==="string"?a.id:"";if(!id)return JSON.stringify({success:!1,error:"id must be a non-empty string"});let reason=typeof a.reason==="string"?a.reason:"";if(!reason)return JSON.stringify({success:!1,error:"reason is required"});let evidence2=typeof a.evidence==="string"?a.evidence:void 0,tier=a.tier==="hive"?"hive":"swarm",mode=a.mode==="quarantine"||a.mode==="purge"?a.mode:"archive";if(mode==="purge"&&a.allow_purge!==!0)return JSON.stringify({success:!1,error:"purge requires allow_purge:true (admin flag)"});if(mode==="quarantine"){if(tier==="hive")return JSON.stringify({success:!1,error:"quarantine via the archive tool is swarm-only; use tier:'swarm' or the /swarm knowledge quarantine command"});try{let target=(await readKnowledge(resolveSwarmKnowledgePath(directory))).find((e)=>e.id===id);if(!target)return JSON.stringify({success:!1,message:"entry not found"});let reportedBy=ctx?.agent==="architect"?"architect":"user",curationInput={directory,action:"quarantine",entryId:id,reason,evidenceScope:"cohort-wide",actorRole:ctx?.agent},curationContext={config:await loadConfigForPolicy(directory),entry:target};await quarantineEntry(directory,id,reason,reportedBy,{input:curationInput,context:curationContext})}catch(err){return JSON.stringify({success:!1,error:err instanceof Error?err.message:"Unknown error during quarantine"})}return JSON.stringify({success:!0,id,tier,mode,status:"quarantined"})}let knowledgePath=tier==="hive"?resolveHiveKnowledgePath2():resolveSwarmKnowledgePath(directory),found=!1,previousStatus,now2=new Date().toISOString(),resultStatus,casExpectedRevision,casExpectedContentHash;if(tier==="swarm"){let preEntries;try{preEntries=await readKnowledge(knowledgePath)}catch(err){let message=err instanceof Error?err.message:"Unknown error";return JSON.stringify({success:!1,error:message})}let preTarget=preEntries.find((e)=>e.id===id)??null;if(preTarget){let curationInput={directory,action:mode,entryId:id,reason,evidenceScope:"cohort-wide",actorRole:ctx?.agent},curationContext={config:await loadConfigForPolicy(directory),entry:preTarget},decision=await authorizeCuration(curationInput,curationContext);if(!decision.authorized)return JSON.stringify({success:!1,error:`Cohort-safety policy blocked this ${mode}: ${decision.detail}`,basis:decision.basis});casExpectedRevision=preTarget.revision,casExpectedContentHash=preTarget.content_hash}}if(tier==="swarm"&&mode==="archive"){let casResult;try{casResult=await transactKnowledgeWithCas(directory,knowledgePath,id,casExpectedRevision,casExpectedContentHash,(entry)=>{if(found=!0,previousStatus=entry.status,entry.status==="archived")return resultStatus="archived",null;return resultStatus="archived",{mutated:{...entry,status:"archived",archived_from:entry.status,archived_at:now2,updated_at:now2}}})}catch(err){return JSON.stringify({success:!1,error:err instanceof Error?err.message:"Unknown error"})}if(casResult.casFailed)return JSON.stringify({success:!1,error:"entry changed since authorization (revision/content-hash mismatch); stale archive plan rejected"})}else try{await transactKnowledge(knowledgePath,(entries)=>{let target=entries.find((e)=>e.id===id);if(!target)return null;if(found=!0,previousStatus=target.status,mode==="purge")return warn(`[knowledge_archive] PURGE: hard-deleting ${tier} entry id=${id} actor=${ctx?.agent??"unknown"} reason=${reason}`),resultStatus="purged",entries.filter((e)=>e.id!==id);if(target.status==="archived")return resultStatus="archived",entries;return resultStatus="archived",entries.map((e)=>e.id===id?{...e,status:"archived",archived_from:target.status,archived_at:now2,updated_at:now2}:e)})}catch(err){return JSON.stringify({success:!1,error:err instanceof Error?err.message:"Unknown error"})}if(!found)return JSON.stringify({success:!1,message:"entry not found"});return await writeArchiveTombstoneAndInvalidateSkills({directory,entryId:id,tier,actor:ctx?.agent??"unknown",reason,mode,evidence:evidence2,previousStatus,sourceLabel:"knowledge-archive"}),JSON.stringify({success:!0,id,tier,mode,previous_status:previousStatus,status:resultStatus})}});init_zod();init_config();init_knowledge_store();init_create_tool();import{existsSync as existsSync138}from"node:fs";var DEFAULT_LIMIT=10,MAX_LESSON_LENGTH=200,VALID_CATEGORIES3=["process","architecture","tooling","security","testing","debugging","performance","integration","todo","other"],VALID_STATUSES=["candidate","established","promoted","archived"],DEFAULT_QUERY_STATUSES=new Set(["established","promoted"]),VALID_TIERS=["swarm","hive","all"];function validateTierInput(tier){if(typeof tier!=="string")return null;let normalized=tier.toLowerCase().trim();if(VALID_TIERS.includes(normalized))return normalized;return null}function validateStatusInput(status){if(typeof status!=="string")return null;let normalized=status.toLowerCase().trim();if(VALID_STATUSES.includes(normalized))return normalized;return null}function validateCategoryInput(category){if(typeof category!=="string")return null;let normalized=category.toLowerCase().trim();if(VALID_CATEGORIES3.includes(normalized))return normalized;return null}function validateMinScore(score){if(typeof score==="number"&&!Number.isNaN(score))return Math.max(0,Math.min(1,score));if(typeof score==="string"){let parsed=Number.parseFloat(score);if(!Number.isNaN(parsed))return Math.max(0,Math.min(1,parsed))}return null}function validateLimit(limit){if(typeof limit==="number"&&!Number.isNaN(limit)&&limit>0)return Math.min(limit,100);if(typeof limit==="string"){let parsed=Number.parseInt(limit,10);if(!Number.isNaN(parsed)&&parsed>0)return Math.min(parsed,100)}return DEFAULT_LIMIT}async function readSwarmKnowledge(directory){let swarmPath3=resolveSwarmKnowledgePath(directory);if(!existsSync138(swarmPath3))return[];return readKnowledge(swarmPath3)}async function readHiveKnowledge(){let hivePath=resolveHiveKnowledgePath2();if(!existsSync138(hivePath))return[];return readKnowledge(hivePath)}function filterSwarmEntries(entries,filters,suppressedLessons,scopeFilter){return entries.filter((entry)=>{if(filters.status){if(entry.status!==filters.status)return!1}else if(!DEFAULT_QUERY_STATUSES.has(entry.status))return!1;if(filters.category&&entry.category!==filters.category)return!1;if(filters.minScore!==void 0&&entry.confidence<filters.minScore)return!1;if(scopeFilter&&scopeFilter.length>0){let entryScope=entry.scope??"global";if(!scopeFilter.some((pattern)=>entryScope===pattern))return!1}if(suppressedLessons.has(normalize5(entry.lesson)))return!1;return!0})}function filterHiveEntries(entries,filters,suppressedLessons,scopeFilter){return entries.filter((entry)=>{if(filters.status){if(entry.status!==filters.status)return!1}else if(!DEFAULT_QUERY_STATUSES.has(entry.status))return!1;if(filters.category&&entry.category!==filters.category)return!1;if(filters.minScore!==void 0&&entry.confidence<filters.minScore)return!1;if(scopeFilter&&scopeFilter.length>0){let entryScope=entry.scope??"global";if(!scopeFilter.some((pattern)=>entryScope===pattern))return!1}if(suppressedLessons.has(normalize5(entry.lesson)))return!1;return!0})}function truncateLesson3(lesson,maxLength){if(lesson.length<=maxLength)return lesson;return`${lesson.slice(0,maxLength-3)}...`}function formatSwarmEntry(entry){let lines=[];return lines.push(`[${entry.tier.toUpperCase()}] ${entry.id}`),lines.push(` Lesson: ${truncateLesson3(entry.lesson,MAX_LESSON_LENGTH)}`),lines.push(` Category: ${entry.category}`),lines.push(` Status: ${entry.status}`),lines.push(` Confidence: ${entry.confidence.toFixed(2)}`),lines.push(` Confirmed by: ${entry.confirmed_by.length} phase(s)`),lines.push(` Project: ${entry.project_name}`),lines.join(`
6563
6570
  `)}function formatHiveEntry(entry){let lines=[];return lines.push(`[${entry.tier.toUpperCase()}] ${entry.id}`),lines.push(` Lesson: ${truncateLesson3(entry.lesson,MAX_LESSON_LENGTH)}`),lines.push(` Category: ${entry.category}`),lines.push(` Status: ${entry.status}`),lines.push(` Confidence: ${entry.confidence.toFixed(2)}`),lines.push(` Encounter Score: ${entry.encounter_score?.toFixed(2)??"N/A"}`),lines.push(` Source Project: ${entry.source_project}`),lines.push(` Confirmed by: ${entry.confirmed_by.length} project(s)`),lines.join(`
6564
6571
  `)}var knowledge_query=createSwarmTool({allowWorkingDirectoryOverride:!0,description:"Performs structured filter-based retrieval of swarm knowledge (project-level) or hive knowledge (cross-project). Returns formatted text for human inspection. This is the tool to use when the user knows the CATEGORY, STATUS, or SCORE they want to filter by. For semantic natural-language search, use `knowledge_recall` instead.",args:{tier:exports_external.string().optional().describe("Knowledge tier to query: 'swarm', 'hive', or 'all' (default: 'all')"),status:exports_external.string().optional().describe("Filter by status: 'candidate', 'established', 'promoted', or 'archived'"),category:exports_external.string().optional().describe("Filter by category: 'process', 'architecture', 'tooling', 'security', 'testing', 'debugging', 'performance', 'integration', 'todo', or 'other'"),min_score:exports_external.number().optional().describe("Minimum confidence score filter (0.0-1.0)"),limit:exports_external.number().optional().describe(`Maximum number of results to return (default: ${DEFAULT_LIMIT}, max: 100)`)},async execute(args2,directory){let tierInput,statusInput,categoryInput,minScoreInput,limitInput;try{if(args2&&typeof args2==="object"){let obj=args2;tierInput=obj.tier,statusInput=obj.status,categoryInput=obj.category,minScoreInput=obj.min_score,limitInput=obj.limit}}catch{}let tier=validateTierInput(tierInput)??"all",status=validateStatusInput(statusInput)??null,category=validateCategoryInput(categoryInput)??null,minScore=validateMinScore(minScoreInput)??null,limit=validateLimit(limitInput),filters={status:status??void 0,category:category??void 0,minScore:minScore??void 0},retractionRecords=await readRetractionRecords(directory),suppressedLessons=new Set(retractionRecords.map((record3)=>record3.normalized_lesson).filter((value)=>typeof value==="string"&&value.length>0)),results=[],scopeFilter;try{let{config:config3}=loadPluginConfigWithMeta(directory);scopeFilter=config3.knowledge?.scope_filter}catch{}if(tier==="swarm"||tier==="all"){let swarmEntries=await readSwarmKnowledge(directory),filtered=filterSwarmEntries(swarmEntries,filters,suppressedLessons,scopeFilter);for(let entry of filtered)results.push({entry,tier:"swarm"})}if(tier==="hive"||tier==="all"){let hiveEntries=await readHiveKnowledge(),filtered=filterHiveEntries(hiveEntries,filters,suppressedLessons,scopeFilter);for(let entry of filtered)results.push({entry,tier:"hive"})}let limitedResults=results.slice(0,limit);if(limitedResults.length===0){let tierDesc=tier==="all"?"swarm or hive":tier,filterParts=[];if(status)filterParts.push(`status=${status}`);if(category)filterParts.push(`category=${category}`);if(minScore!==null)filterParts.push(`min_score=${minScore}`);let filterDesc=filterParts.length>0?` with filters: ${filterParts.join(", ")}`:"";return`No knowledge entries found for tier '${tierDesc}'${filterDesc}.`}let outputLines=[];outputLines.push(`=== Knowledge Query Results (${limitedResults.length} of ${results.length} shown) ===`),outputLines.push("");for(let{entry,tier:entryTier}of limitedResults){if(entryTier==="hive")outputLines.push(formatHiveEntry(entry));else outputLines.push(formatSwarmEntry(entry));outputLines.push("")}if(outputLines.push("---"),outputLines.push(`Total matched: ${results.length} | Tier: ${tier} | Limit: ${limit}`),status)outputLines.push(`Status filter: ${status}`);if(category)outputLines.push(`Category filter: ${category}`);if(minScore!==null)outputLines.push(`Min score filter: ${minScore}`);return outputLines.join(`
6565
6572
  `)}});init_knowledge_recall();init_zod();init_config();init_schema();init_knowledge_events();init_knowledge_link();init_promotion_evidence_store();init_logger();init_create_tool();async function readLinkPointerSafe(directory){try{return readLinkPointer(directory)?.linkId}catch{return}}var IGNORE_REASONS=["stale","superseded","unsafe","too_generic","already_satisfied","other"],PROPOSED_ACTIONS=["archive","revise","quarantine"],VERIFIED_BY=["reviewer","test_engineer","architect"],appliedItem=exports_external.object({id:exports_external.string().min(1),how:exports_external.string().min(1).max(500),evidence_files:exports_external.array(exports_external.string()).optional(),evidence_commands:exports_external.array(exports_external.string()).optional(),verified_by:exports_external.enum(VERIFIED_BY).optional()}),ignoredItem=exports_external.object({id:exports_external.string().min(1),reason:exports_external.enum(IGNORE_REASONS),note:exports_external.string().max(500).optional()}),notApplicableItem=exports_external.object({id:exports_external.string().min(1),reason:exports_external.string().trim().min(1).max(500)}),contradictedItem=exports_external.object({id:exports_external.string().min(1),evidence:exports_external.string().min(1).max(500),proposed_action:exports_external.enum(PROPOSED_ACTIONS)}),newLessonItem=exports_external.object({lesson:exports_external.string().min(15).max(280),category:exports_external.string().min(1),evidence:exports_external.string().max(500).optional(),applies_to_agents:exports_external.array(exports_external.string()).optional(),applies_to_tools:exports_external.array(exports_external.string()).optional(),required_actions:exports_external.array(exports_external.string()).optional(),forbidden_actions:exports_external.array(exports_external.string()).optional(),verification_checks:exports_external.array(exports_external.string()).optional()});function receiptSourceForAgent(agent){let base=stripKnownSwarmPrefix(agent.trim());if(!base||base==="unknown")return"unknown";if(base==="reviewer")return"reviewer";if(base==="test_engineer")return"test_engineer";if(base==="architect")return"architect";return"delegate"}var knowledge_receipt=createSwarmTool({allowWorkingDirectoryOverride:!0,description:"File a receipt for knowledge surfaced by a retrieval (by trace_id): which entries were applied (with evidence), ignored with a reason (relevant but deliberately not followed — counts against the entry), marked n_a with a reason (not applicable to this task — neutral), or contradicted (with proposed remediation), plus any new lessons. Each item is recorded as an immutable knowledge event. Set no_relevant_knowledge:true when a retrieval surfaced nothing useful.",args:{trace_id:exports_external.string().min(1).describe("trace_id from a prior knowledge_recall/injection, or 'none' if no retrieval occurred"),task_id:exports_external.string().min(1).optional(),phase:exports_external.string().optional(),applied:exports_external.array(appliedItem).optional(),ignored:exports_external.array(ignoredItem).optional().describe("entries you judged relevant but deliberately did not follow (counts against the entry). NOT for not-applicable entries — file those under n_a"),n_a:exports_external.array(notApplicableItem).optional().describe("entries that did not apply to this task (neutral; reasoned). Replaces the removed not_relevant ignore reason"),contradicted:exports_external.array(contradictedItem).optional(),new_lessons:exports_external.array(newLessonItem).optional(),no_relevant_knowledge:exports_external.boolean().optional()},execute:async(args2,directory,ctx)=>{let a=args2??{},traceId=typeof a.trace_id==="string"?a.trace_id:"";if(!traceId)return JSON.stringify({recorded:!1,error:'trace_id is required (use "none" if no retrieval occurred)'});let taskId=typeof a.task_id==="string"&&a.task_id.trim()?a.task_id.trim():void 0,phase=typeof a.phase==="string"?a.phase:void 0,applied=Array.isArray(a.applied)?a.applied:[],ignored=Array.isArray(a.ignored)?a.ignored:[],notApplicable=Array.isArray(a.n_a)?a.n_a:[],contradicted=Array.isArray(a.contradicted)?a.contradicted:[],newLessons=Array.isArray(a.new_lessons)?a.new_lessons:[],noRelevant=a.no_relevant_knowledge===!0;if(applied.length===0&&ignored.length===0&&notApplicable.length===0&&contradicted.length===0&&newLessons.length===0&&!noRelevant)return JSON.stringify({recorded:!1,error:"empty receipt: provide at least one applied/ignored/n_a/contradicted entry, a new lesson, or set no_relevant_knowledge:true"});let sessionId=ctx?.sessionID??"unknown",agent=ctx?.agent??"unknown",receiptSource=receiptSourceForAgent(agent),knowledgeConfig=KnowledgeConfigSchema.parse({});try{let{config:config3}=loadPluginConfigWithMeta(directory);knowledgeConfig=KnowledgeConfigSchema.parse(config3.knowledge??{})}catch{}let base={trace_id:traceId,session_id:sessionId,phase,task_id:taskId,agent,source:receiptSource},recordedEventIds=[],diagnosticEventIds=[],emit3=async(event)=>{let id=(await recordKnowledgeEvent(directory,event))?.event_id??"";if(id)diagnosticEventIds.push(id);return id},eventIdByKnowledgeId=new Map,validationItems=[...applied.map((i)=>({id:i.id,outcome:"applied",reason:i.how})),...ignored.map((i)=>({id:i.id,outcome:"ignored",reason:i.note?`${i.reason}: ${i.note}`:i.reason})),...notApplicable.map((i)=>({id:i.id,outcome:"n_a",reason:i.reason})),...contradicted.map((i)=>({id:i.id,outcome:"contradicted",reason:`${i.proposed_action}: ${i.evidence}`}))],needsValidation=validationItems.length>0||noRelevant,acceptedIds=new Set,closesNoRelevant=!1,acceptedItems=[],authoritativeEventIds={},cohortId,linkId;if(needsValidation){try{cohortId=await ensureCohortIdCached(directory,sessionId),linkId=await readLinkPointerSafe(directory)}catch{}let validation2=await validateReceipt({directory,trace_id:traceId,session_id:sessionId,task_id:taskId,phase,agent,source:receiptSource,cohort_id:cohortId,source_link_id:linkId,items:validationItems,no_relevant_knowledge:noRelevant,grace_days:knowledgeConfig.receipt_close_grace_days});if(!validation2.ok)return JSON.stringify({recorded:!1,rejected:!0,reason:validation2.reason,detail:validation2.detail,rejected_items:validation2.rejected_items});if(acceptedIds=new Set(validation2.accepted.map((i)=>i.id)),closesNoRelevant=validation2.closes_no_relevant,acceptedItems=validation2.accepted,authoritativeEventIds=validation2.authoritative_event_ids,recordedEventIds.push(...Object.values(authoritativeEventIds)),validation2.no_relevant_event_id)recordedEventIds.push(validation2.no_relevant_event_id)}if(closesNoRelevant)await emit3({type:"no_relevant",...base,reason:"no relevant knowledge surfaced by the trace"});for(let item of applied){if(!acceptedIds.has(item.id))continue;await emit3({type:"applied",...base,knowledge_id:item.id,reason:item.how,evidence:{files:item.evidence_files,commands:item.evidence_commands,summary:item.verified_by?`verified_by=${item.verified_by}`:void 0}});let eid=authoritativeEventIds[item.id];if(eid)eventIdByKnowledgeId.set(item.id,eid)}for(let item of ignored){if(!acceptedIds.has(item.id))continue;await emit3({type:"ignored",...base,knowledge_id:item.id,reason:item.note?`${item.reason}: ${item.note}`:item.reason})}for(let item of notApplicable){if(!acceptedIds.has(item.id))continue;await emit3({type:"n_a",...base,knowledge_id:item.id,reason:item.reason})}for(let item of contradicted){if(!acceptedIds.has(item.id))continue;await emit3({type:"contradicted",...base,knowledge_id:item.id,reason:`${item.proposed_action}: ${item.evidence}`,evidence:{summary:item.evidence}});let eid=authoritativeEventIds[item.id];if(eid)eventIdByKnowledgeId.set(item.id,eid)}if(acceptedItems.length>0)try{let now2=new Date().toISOString(),evidenceRecords=[];for(let item of acceptedItems){if(item.outcome!=="applied"&&item.outcome!=="contradicted")continue;let receiptEventId=eventIdByKnowledgeId.get(item.id);if(!cohortId||!receiptEventId)continue;evidenceRecords.push({cohort_id:cohortId,source_link_id:linkId,entry_id:item.id,retrieval_trace_id:traceId,receipt_outcome:item.outcome==="applied"?"applied":"contradicted",receipt_source:receiptSource,receipt_event_id:receiptEventId,phase,timestamp:now2})}await appendPromotionEvidence(directory,evidenceRecords)}catch{}let newLessonResults=[];for(let item of newLessons){let raw=await knowledge_add.execute({lesson:item.lesson,category:item.category,applies_to_agents:item.applies_to_agents,applies_to_tools:item.applies_to_tools,required_actions:item.required_actions,forbidden_actions:item.forbidden_actions,verification_checks:item.verification_checks},ctx);try{let output=typeof raw==="string"?raw:typeof raw==="object"&&raw!==null&&("output"in raw)&&typeof raw.output==="string"?raw.output:"";newLessonResults.push(JSON.parse(output))}catch{newLessonResults.push({success:!1})}}return log("[knowledge_receipt] completed",{agent,source:receiptSource,session_id:sessionId,trace_id:traceId,applied:applied.length,ignored:ignored.length,n_a:notApplicable.length,contradicted:contradicted.length,new_lessons:newLessonResults.length,no_relevant_knowledge:noRelevant,event_count:recordedEventIds.length,diagnostic_event_count:diagnosticEventIds.length}),JSON.stringify({recorded:!0,trace_id:traceId,applied:applied.length,ignored:ignored.length,n_a:notApplicable.length,contradicted:contradicted.length,new_lessons:newLessonResults,no_relevant_knowledge:noRelevant,event_ids:recordedEventIds})}});init_zod();init_knowledge_store();init_skill_invalidator();init_curation_policy();init_create_tool();async function loadConfigForPolicy2(directory){let{KnowledgeConfigSchema:KnowledgeConfigSchema2}=await Promise.resolve().then(() => (init_schema(),exports_schema));try{let{loadPluginConfigWithMeta:loadPluginConfigWithMeta2}=await Promise.resolve().then(() => (init_config(),exports_config)),{config:loadedConfig}=loadPluginConfigWithMeta2(directory);return KnowledgeConfigSchema2.parse(loadedConfig.knowledge??{})}catch{return KnowledgeConfigSchema2.parse({})}}var _internals208={transactKnowledge,writeArchiveTombstoneAndInvalidateSkills},knowledge_remove=createSwarmTool({allowWorkingDirectoryOverride:!0,description:"Delete an outdated swarm knowledge entry by ID (swarm tier only — does not affect hive). Promoted entries cannot be deleted. Double-deletion is idempotent — removing a non-existent entry returns a clear message without error.",args:{id:exports_external.string().min(1).describe("UUID of the knowledge entry to remove")},execute:async(args2,directory)=>{let idInput;try{if(args2&&typeof args2==="object")idInput=args2.id}catch{}if(typeof idInput!=="string"||idInput.length<1)return JSON.stringify({success:!1,error:"id must be a non-empty string"});let id=idInput,swarmPath3=resolveSwarmKnowledgePath(directory),preEntries;try{preEntries=await readKnowledge(swarmPath3)}catch(err){let message=err instanceof Error?err.message:"Unknown error";return JSON.stringify({success:!1,error:message})}let preTarget=preEntries.find((e)=>e.id===id)??null;if(preTarget){let curationInput={directory,action:"remove",entryId:id,reason:"hard-delete via knowledge_remove tool",evidenceScope:"cohort-wide"},curationContext={config:await loadConfigForPolicy2(directory),entry:preTarget},decision=await authorizeCuration(curationInput,curationContext);if(!decision.authorized)return JSON.stringify({success:!1,error:`Cohort-safety policy blocked removal: ${decision.detail}`,basis:decision.basis})}let found=!1,remaining=0,isPromoted=!1;try{await _internals208.transactKnowledge(swarmPath3,(entries)=>{let entryToDelete=entries.find((entry)=>entry.id===id);if(!entryToDelete)return null;if(entryToDelete.status==="promoted")return isPromoted=!0,null;let filtered=entries.filter((entry)=>entry.id!==id);if(filtered.length===entries.length)return null;return found=!0,remaining=filtered.length,filtered})}catch(err){let message=err instanceof Error?err.message:"Unknown error";return JSON.stringify({success:!1,error:message})}if(isPromoted)return JSON.stringify({success:!1,message:"cannot delete promoted entry — this entry has been promoted to cross-project consensus"});if(!found)return JSON.stringify({success:!1,message:"entry not found"});return await _internals208.writeArchiveTombstoneAndInvalidateSkills({directory,entryId:id,tier:"swarm",actor:"knowledge_remove",reason:"hard-delete via knowledge_remove tool",mode:"purge",skipTombstone:!0,sourceLabel:"knowledge-remove"}),JSON.stringify({success:!0,removed:1,remaining})}});init_zod();init_file_locks();init_create_tool();async function executeLeanTurboAcquireLocks(args2){let{directory,laneId,files,agent,taskId,sessionID}=args2;try{let result=await acquireLaneLocks(directory,laneId,files,agent,taskId,sessionID);if(result.acquired)return{success:!0,locks:result.locks};else return{success:!1,conflicts:result.conflicts}}catch(error93){return{success:!1,errors:[error93 instanceof Error?error93.message:String(error93)]}}}var lean_turbo_acquire_locks=createSwarmTool({description:"Acquire file locks for all files in a lane (all-or-nothing). Wraps acquireLaneLocks from src/parallel/file-locks. If any file is already locked, releases all previously acquired locks.",args:{directory:exports_external.string().describe("Project root directory"),laneId:exports_external.string().describe('Unique lane identifier (e.g., "lane-1")'),files:exports_external.array(exports_external.string().min(1)).min(1).describe("Array of file paths to lock"),agent:exports_external.string().describe("Agent name acquiring the locks"),taskId:exports_external.string().describe('Task ID (e.g., "4.1")'),sessionID:exports_external.string().describe("Session ID for the Lean Turbo run")},execute:async(args2,_directory)=>{return JSON.stringify(await executeLeanTurboAcquireLocks({...args2,directory:_directory}),null,2)}});init_zod();init_constants();import*as fs156 from"node:fs";import*as path268 from"node:path";init_create_tool();function readPlanJson2(directory){let planPath=path268.join(directory,".swarm","plan.json");if(!fs156.existsSync(planPath))return null;try{return JSON.parse(fs156.readFileSync(planPath,"utf-8"))}catch{return null}}async function executeLeanTurboPlanLanes(args2){let{directory,phase,scopes}=args2,plan=readPlanJson2(directory);if(!plan)return{success:!1,errors:["plan.json not found in .swarm directory"]};let defaultConfig={...DEFAULT_LEAN_TURBO_CONFIG};try{let lanePlan=planLeanTurboLanes(directory,phase,plan,defaultConfig,scopes);return{success:!0,plan:lanePlan,lanes:lanePlan.lanes,degradedTasks:lanePlan.degradedTasks,serializedTasks:lanePlan.serializedTasks}}catch(error93){return{success:!1,errors:[error93 instanceof Error?error93.message:String(error93)]}}}var lean_turbo_plan_lanes=createSwarmTool({description:"Partition phase tasks into parallel lanes based on file-scope conflicts. Wraps planLeanTurboLanes for Lean Turbo lane planning.",args:{directory:exports_external.string().describe("Project root directory where .swarm/plan.json is located"),phase:exports_external.number().int().positive().describe("Phase number to plan"),scopes:exports_external.record(exports_external.string(),exports_external.array(exports_external.string())).optional().describe("Optional pre-loaded scopes map (taskId -> file paths)")},execute:async(args2,_directory)=>{return JSON.stringify(await executeLeanTurboPlanLanes({...args2,directory:_directory}),null,2)}});init_zod();init_state4();init_create_tool();async function executeLeanTurboRunnerStatus(args2){let{directory,sessionID}=args2;try{let runState=loadLeanTurboRunState(directory,sessionID);if(!runState)return{success:!1,errors:["No Lean Turbo run state found for this session"]};return{success:!0,status:runState.status,phase:runState.phase,lanes:runState.lanes,degradedTasks:runState.degradedTasks,maxParallelCoders:runState.maxParallelCoders,sessionID:runState.sessionID,strategy:runState.strategy}}catch(error93){return{success:!1,errors:[error93 instanceof Error?error93.message:String(error93)]}}}var lean_turbo_runner_status=createSwarmTool({description:"Read Lean Turbo run state from .swarm/turbo-state.json. Returns status, phase, lanes, degraded tasks, and max parallel coders.",args:{directory:exports_external.string().describe("Project root directory where .swarm/turbo-state.json is located"),sessionID:exports_external.string().describe("Session ID for the Lean Turbo run")},execute:async(args2,_directory)=>{return JSON.stringify(await executeLeanTurboRunnerStatus({...args2,directory:_directory}),null,2)}});init_zod();init_constants();init_state4();init_create_tool();async function executeLeanTurboStatus(args2){let{directory,sessionID}=args2;try{let runState=loadLeanTurboRunState(directory,sessionID),defaultConfig={max_parallel_coders:DEFAULT_LEAN_TURBO_CONFIG.max_parallel_coders,require_declared_scope:DEFAULT_LEAN_TURBO_CONFIG.require_declared_scope,degrade_on_risk:DEFAULT_LEAN_TURBO_CONFIG.degrade_on_risk,conflict_policy:DEFAULT_LEAN_TURBO_CONFIG.conflict_policy};if(runState)return{success:!0,strategy:"lean",leanActive:runState.status==="running",config:defaultConfig,status:runState.status,phase:runState.phase,lanes:runState.lanes.length,degradedTasks:runState.degradedTasks.length};return{success:!0,strategy:"lean",leanActive:!1,config:defaultConfig,status:"idle",phase:void 0,lanes:0,degradedTasks:0}}catch(error93){return{success:!1,errors:[error93 instanceof Error?error93.message:String(error93)]}}}var lean_turbo_status=createSwarmTool({description:"Returns Lean Turbo configuration and active status for the current session. Shows whether lean turbo is active, current status, and configuration values.",args:{directory:exports_external.string().describe("Project root directory"),sessionID:exports_external.string().describe("Session ID to check status for")},execute:async(args2,_directory)=>{return JSON.stringify(await executeLeanTurboStatus({...args2,directory:_directory}),null,2)}});init_lint();init_spec_schema();init_effective_spec();init_create_tool();var OBLIGATION_KEYWORDS=["MUST","SHALL","SHOULD","MAY"],FR_ID_PATTERN2=/\bFR-(?!000)\d{3}\b/,OBLIGATION_PATTERN2=/\b(MUST|SHALL|SHOULD|MAY)\b/g,SCENARIO_PATTERN=/^##\s+Scenario\s*:/gm,GIVEN_WHEN_THEN_PATTERN=/\b(Given|When|Then|And|But)[:\s]/gi;function countRequirementsByObligation(content){let counts={MUST:0,SHALL:0,SHOULD:0,MAY:0},lines=content.replace(/```[\s\S]*?```/g,"").replace(/`[^`]*`/g,"").split(`
6566
6573
  `);for(let line of lines){if(!line.match(FR_ID_PATTERN2))continue;let matches=line.matchAll(OBLIGATION_PATTERN2);for(let match of matches){let keyword=match[1];if(OBLIGATION_KEYWORDS.includes(keyword))counts[keyword]++}}return counts}function countScenarios(content){let scenarioCount=0,scenarioMatches=content.match(SCENARIO_PATTERN);if(scenarioMatches)scenarioCount+=scenarioMatches.length;let givenWhenThenMatches=content.match(GIVEN_WHEN_THEN_PATTERN);if(givenWhenThenMatches&&givenWhenThenMatches.length>0){if(scenarioCount===0)scenarioCount=(content.match(/\bWhen\s+/gi)||[]).length}return scenarioCount}var lint_spec=createSwarmTool({description:"Reads .swarm/spec.md, lints markdown spec for FR-IDs, obligations, and structure, and returns requirement counts by obligation level, scenario count, and any errors or warnings found.",args:{},async execute(_args,directory){let errors5=[],warnings=[],spec=readEffectiveSpecSync(directory);if(!spec)return JSON.stringify({valid:!1,specMtime:null,requirementCount:{MUST:0,SHALL:0,SHOULD:0,MAY:0,total:0},scenarioCount:0,errors:["spec.md not found and no valid OpenSpec-compatible projection available"],warnings:[]},null,2);let{mtime:specMtime,content}=spec,contentValidation=validateSpecContent(content);if(!contentValidation.valid)for(let issue3 of contentValidation.issues)errors5.push(`Line ${issue3.line}: ${issue3.message}`);let obligationCounts=countRequirementsByObligation(content),totalRequirements=Object.values(obligationCounts).reduce((sum,count)=>sum+count,0),scenarioCount=countScenarios(content),result={valid:errors5.length===0,specMtime,requirementCount:{...obligationCounts,total:totalRequirements},scenarioCount,errors:errors5,warnings:[...warnings,...spec.warnings]};return JSON.stringify(result,null,2)}});init_zod();init_engine();import*as fs157 from"node:fs";import*as path269 from"node:path";var _internals209={evaluateMutationGate,buildTestImprovementPrompt,buildMessage};function evaluateMutationGate(report,passThreshold=0.8,warnThreshold=0.6){if(passThreshold<warnThreshold)throw Error(`Invalid thresholds: passThreshold (${passThreshold}) must be >= warnThreshold (${warnThreshold})`);let adjustedKillRate=report.adjustedKillRate,survivedMutants=report.results.filter((result)=>result.outcome==="survived"),verdict;if(adjustedKillRate>=passThreshold)verdict="pass";else if(adjustedKillRate>=warnThreshold)verdict="warn";else verdict="fail";let testImprovementPrompt=_internals209.buildTestImprovementPrompt(report,passThreshold,verdict),message=_internals209.buildMessage(verdict,adjustedKillRate,report.killed,report.totalMutants,report.equivalent,warnThreshold);return{verdict,killRate:report.killRate,adjustedKillRate,totalMutants:report.totalMutants,killed:report.killed,survived:report.survived,threshold:passThreshold,warnThreshold,message,survivedMutants,testImprovementPrompt}}function buildTestImprovementPrompt(report,passThreshold,verdict){if(verdict==="pass")return"";let lowKillRateFunctions=[];for(let[key,stats2]of report.perFunction)if(stats2.killRate<passThreshold){let lastColon=key.lastIndexOf(":");if(lastColon===-1)continue;let filePath=key.substring(0,lastColon),functionName=key.substring(lastColon+1);lowKillRateFunctions.push(` - ${functionName} in ${filePath}: ${Math.round(stats2.killRate*100)}% kill rate (${stats2.killed}/${stats2.total} killed)`)}if(lowKillRateFunctions.length===0)return"";return`The following functions have low mutation kill rates and need stronger tests:
6567
6574
  `+lowKillRateFunctions.join(`
6568
6575
  `)}function buildMessage(verdict,adjustedKillRate,killed,totalMutants,equivalent,warnThreshold){let killRatePercent=Math.round(adjustedKillRate*100),effectiveTotal=totalMutants-equivalent;switch(verdict){case"pass":return`Mutation gate PASSED: ${killRatePercent}% kill rate (${killed}/${effectiveTotal} mutants killed)`;case"warn":return`Mutation gate WARNING: ${killRatePercent}% kill rate (${killed}/${effectiveTotal} mutants killed). Test improvement recommended.`;case"fail":return`Mutation gate FAILED: ${killRatePercent}% kill rate (${killed}/${effectiveTotal} mutants killed). Below minimum threshold of ${Math.round(warnThreshold*100)}%.`}}init_create_tool();init_resolve_working_directory();var mutation_test=createSwarmTool({description:"Execute mutation testing with pre-generated patches — applies each mutant patch, runs tests, and evaluates kill rate against quality gate thresholds. Returns verdict (pass/warn/fail) with per-function kill rates and survived mutant details.",args:{patches:exports_external.array(exports_external.object({id:exports_external.string().describe("Unique identifier for the mutation patch"),filePath:exports_external.string().describe("File path to apply the patch to"),functionName:exports_external.string().describe("Function being mutated"),mutationType:exports_external.string().describe("Type of mutation (e.g., off_by_one, null_substitution)"),patch:exports_external.string().describe("Unified diff patch content"),lineNumber:exports_external.number().optional().describe("Line number of the mutation")})).describe("Array of MutationPatch objects — pre-generated mutation patches to execute"),files:exports_external.array(exports_external.string()).describe("Array of test file paths to run against mutants"),test_command:exports_external.array(exports_external.string()).describe('Test command as array of strings (e.g., ["npx", "vitest", "--run"])'),pass_threshold:exports_external.number().optional().describe("Kill rate threshold for pass verdict (default: 0.80)"),warn_threshold:exports_external.number().optional().describe("Kill rate threshold for warn verdict (default: 0.60)"),working_directory:exports_external.string().optional().describe("Project root directory. Defaults to current working directory.")},async execute(args2,directory,_ctx){let typedArgs=args2;try{if(!typedArgs.files||!Array.isArray(typedArgs.files)||typedArgs.files.length===0)return JSON.stringify({error:"files must be a non-empty array of file paths",success:!1},null,2);if(!typedArgs.test_command||!Array.isArray(typedArgs.test_command)||typedArgs.test_command.length===0)return JSON.stringify({error:"test_command must be a non-empty array of strings",success:!1},null,2);if(!typedArgs.test_command.every((c)=>typeof c==="string"))return JSON.stringify({error:"test_command must contain only strings",success:!1},null,2);let cmdValidationError=validateTestCommand(typedArgs.test_command);if(cmdValidationError)return JSON.stringify({error:cmdValidationError,success:!1},null,2);if(!typedArgs.patches||!Array.isArray(typedArgs.patches)||typedArgs.patches.length===0)return JSON.stringify({error:"patches must be a non-empty array of MutationPatch objects",success:!1},null,2);let resolved=resolveWorkingDirectory(typedArgs.working_directory,directory);if(!resolved.success)return JSON.stringify({success:!1,error:resolved.message},null,2);let cwd=resolved.directory,passThreshold=typedArgs.pass_threshold??0.8,warnThreshold=typedArgs.warn_threshold??0.6,sourceFiles=new Map,uniquePaths=[...new Set(typedArgs.patches.map((p)=>p.filePath))];for(let filePath of uniquePaths)try{let resolvedPath=path269.resolve(cwd,filePath);sourceFiles.set(filePath,fs157.readFileSync(resolvedPath,"utf-8"))}catch{}let report=await executeMutationSuite(typedArgs.patches,typedArgs.test_command,typedArgs.files,cwd,void 0,void 0,sourceFiles.size>0?sourceFiles:void 0),result=evaluateMutationGate(report,passThreshold,warnThreshold);return JSON.stringify(result,null,2)}catch(e){return JSON.stringify({error:e instanceof Error?`mutation_test failed: ${e.message}`:"mutation_test failed: unknown error",success:!1},null,2)}}});init_zod();init_external_tool_runner();init_path_security();init_create_tool();import*as fs158 from"node:fs";import*as path270 from"node:path";var OSV_TIMEOUT_MS=60000,OSV_MAX_STDOUT_BYTES=12582912,OSV_MAX_STDERR_BYTES=262144,DEFAULT_MAX_RESULTS3=200,HARD_CAP_RESULTS3=2000;function resolveOsvScannerBinary(){return _internals210.resolveExecutableFromPath(["osv-scanner"])}function normalizeScanPath(value,workspace){let raw=typeof value==="string"&&value.trim()?value.trim():".";if(containsControlChars(raw)||containsPathTraversal(raw))return null;if(path270.isAbsolute(raw)||/^[A-Za-z]:[/\\]/.test(raw))return null;try{let realWorkspace=fs158.realpathSync(workspace),resolved=path270.resolve(realWorkspace,raw),realTarget=fs158.realpathSync(resolved),relative65=path270.relative(realWorkspace,realTarget);if(relative65.startsWith("..")||path270.isAbsolute(relative65))return null;return relative65?relative65.split(path270.sep).join("/"):"."}catch{return null}}function firstString(value){return typeof value==="string"&&value?value:void 0}function collectReferences(vuln){let urls=(Array.isArray(vuln.references)?vuln.references:[]).map((ref)=>ref&&typeof ref==="object"?firstString(ref.url):void 0).filter((url3)=>Boolean(url3));return urls.length>0?urls.slice(0,10):void 0}function parseOsvOutput(stdout,maxResults){let parsed;try{parsed=JSON.parse(stdout)}catch{return{findings:[],total:0,parseError:!0}}let findings=[],total=0,results=Array.isArray(parsed?.results)?parsed.results:[];for(let result of results){let resultObj=result,packages=Array.isArray(resultObj.packages)?resultObj.packages:[];for(let pkg of packages){let pkgObj=pkg,pkgInfo=pkgObj.package??{},vulnerabilities=Array.isArray(pkgObj.vulnerabilities)?pkgObj.vulnerabilities:[];for(let vulnerability of vulnerabilities){let vuln=vulnerability;if(total++,findings.length>=maxResults)continue;let fixedVersion=(Array.isArray(vuln.groups)?vuln.groups:[]).flatMap((group)=>Array.isArray(group.fixed)?group.fixed:[]).map(firstString).find(Boolean);findings.push({id:firstString(vuln.id)??firstString(vuln.osv)??"UNKNOWN",summary:firstString(vuln.summary),packageName:firstString(pkgInfo.name)??firstString(pkgObj.name)??firstString(pkgObj.package),ecosystem:firstString(pkgInfo.ecosystem),installedVersion:firstString(pkgInfo.version)??firstString(pkgObj.version),fixedVersion,aliases:Array.isArray(vuln.aliases)?vuln.aliases.filter((a)=>typeof a==="string"):void 0,references:collectReferences(vuln)})}}}return{findings,total,parseError:!1}}function sanitizeMaxResults2(value){let numeric=typeof value==="number"&&Number.isFinite(value)?value:DEFAULT_MAX_RESULTS3;return Math.min(Math.max(0,numeric),HARD_CAP_RESULTS3)}var osv_scan=createSwarmTool({description:"Run OSV-Scanner against a workspace path and return structured dependency vulnerability findings. Read-only; resolves osv-scanner lazily.",args:{scan_path:exports_external.string().default(".").describe('Workspace-relative path to scan, default "."'),max_results:exports_external.number().default(DEFAULT_MAX_RESULTS3).describe("Maximum vulnerabilities to return")},execute:async(args2,directory)=>{let obj=typeof args2==="object"&&args2!==null?args2:{},scanPath=normalizeScanPath(obj.scan_path,directory);if(!scanPath)return JSON.stringify({error:!0,type:"path-escape",message:"scan_path must be an existing workspace-relative path"},null,2);let maxResults=sanitizeMaxResults2(obj.max_results),executable=_internals210.resolveOsvScannerBinary();if(!executable)return JSON.stringify({error:!0,type:"osv-scanner-not-found",message:"osv-scanner executable not found. Install OSV-Scanner and ensure osv-scanner is on PATH."},null,2);let osvArgs=["scan","--format","json",scanPath==="."?".":`./${scanPath}`],run=await _internals210.runExternalTool({executable,args:osvArgs,cwd:directory,timeoutMs:OSV_TIMEOUT_MS,maxStdoutBytes:OSV_MAX_STDOUT_BYTES,maxStderrBytes:OSV_MAX_STDERR_BYTES});if(run.status==="timeout")return JSON.stringify({error:!0,type:"timeout",message:`osv-scanner timed out after ${OSV_TIMEOUT_MS}ms`},null,2);if(run.status==="spawn-error")return JSON.stringify({error:!0,type:"unknown",message:run.message??"osv-scanner failed to start"},null,2);let{findings,total,parseError}=parseOsvOutput(run.stdout,maxResults);if(parseError)return JSON.stringify({error:!0,type:"unknown",message:run.stdoutTruncated||run.stderrTruncated?"osv-scanner JSON output was truncated and could not be parsed":"osv-scanner output was not valid JSON"},null,2);if(run.exitCode!==0&&findings.length===0&&run.stderr)return JSON.stringify({error:!0,type:"unknown",message:run.stderr.split(`
6569
- `)[0]},null,2);return JSON.stringify({clean:total===0&&!run.stdoutTruncated&&!run.stderrTruncated,findings,total,truncated:total>maxResults||run.stdoutTruncated||run.stderrTruncated,command:["osv-scanner",...osvArgs],scanPath,outputTruncated:run.stdoutTruncated||run.stderrTruncated,note:run.exitCode!==0&&total>0?`osv-scanner exited ${run.exitCode} after finding vulnerabilities`:run.stdoutTruncated||run.stderrTruncated?"osv-scanner output was truncated; result is incomplete.":void 0},null,2)}}),_internals210={resolveExecutableFromPath,resolveOsvScannerBinary,runExternalTool,parseOsvOutput};init_zod();init_candidate_contract();init_candidate_parser();init_lane_output_store();init_utils2();init_create_tool();import{existsSync as existsSync139}from"node:fs";import*as path271 from"node:path";var ParseLaneCandidatesArgsShape={output_ref:exports_external.string().min(1).describe("Opaque lane output ref returned as output_ref by dispatch_lanes or collect_lane_results."),accept_partial:exports_external.boolean().default(!1).describe("Accept sources where transcriptIncomplete is true (partial transcripts)."),accept_degraded:exports_external.boolean().default(!1).describe("Accept sources where the artifact storage was degraded (output_degraded)."),degraded:exports_external.boolean().default(!1).describe("Passed through from DispatchLaneResult.output_degraded by the orchestrator."),row_format_version:exports_external.number().int().nonnegative().default(1).describe("Row format version; currently only version 1 is supported."),producer:exports_external.string().optional().default("swarm-pr-review").describe("Producer label for cross-skill filtering in the sidecar."),expected_family:exports_external.enum(["base_explorer","micro_lane"]).optional().describe("Assert the row family for this dispatch batch. A recognizable conflicting header is refused."),expected_lane:exports_external.string().trim().min(1).max(120).optional().describe("Assert the base-explorer lane linked to this dispatch provenance. Requires expected_family=base_explorer; mismatched base CLEAN attestations are refused."),expected_lanes:exports_external.array(exports_external.string().trim().min(1).max(120)).min(1).max(11).optional().describe("Full owned base-explorer lane set for a consolidated batch. Requires expected_family=base_explorer and expected_lane; owned-but-not-expected lanes are skipped as out-of-scope for this per-lane call instead of refused, while foreign lanes are still refused."),expected_micro_lane:exports_external.string().trim().min(1).max(120).optional().describe("Assert the micro-lane label linked to this dispatch provenance. Requires expected_family=micro_lane; mismatched candidates and CLEAN attestations are refused."),expected_micro_lanes:exports_external.array(exports_external.string().trim().min(1).max(120)).min(1).max(11).optional().describe("Full owned family set of a consolidated depth-tier lane. Requires expected_family=micro_lane and expected_micro_lane; rows for owned-but-not-expected families are skipped as out-of-scope for this per-family call instead of refused, while families outside the set are still refused."),use_lockfile:exports_external.boolean().default(!1).describe("When true, use proper-lockfile for concurrency-safe sidecar writes."),project_root:exports_external.string().optional().describe("Project root directory where .swarm/ lives. Defaults to the injected working directory.")},ParseLaneCandidatesArgsSchema=exports_external.object(ParseLaneCandidatesArgsShape).strict().superRefine((value,context)=>{for(let issue3 of analyzeCandidateLaneContext(value))context.addIssue({code:exports_external.ZodIssueCode.custom,path:[issue3.field],message:issue3.message})}),REF_RE2=/^L1:[a-f0-9]{64}:[a-f0-9]{64}:[a-f0-9]{64}$/;function laneOutputRelativePath2(ref){let parts=ref.split(":");if(parts.length!==4)return"";let[,batchDigest,laneDigest,outputDigest]=parts;return path271.join("lane-results",batchDigest,laneDigest,`${outputDigest}.json`)}var parse_lane_candidates=createSwarmTool({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.",args:{output_ref:ParseLaneCandidatesArgsShape.output_ref,accept_partial:ParseLaneCandidatesArgsShape.accept_partial,accept_degraded:ParseLaneCandidatesArgsShape.accept_degraded,degraded:ParseLaneCandidatesArgsShape.degraded,row_format_version:ParseLaneCandidatesArgsShape.row_format_version,producer:ParseLaneCandidatesArgsShape.producer,expected_family:ParseLaneCandidatesArgsShape.expected_family,expected_lane:ParseLaneCandidatesArgsShape.expected_lane,expected_lanes:ParseLaneCandidatesArgsShape.expected_lanes,expected_micro_lane:ParseLaneCandidatesArgsShape.expected_micro_lane,expected_micro_lanes:ParseLaneCandidatesArgsShape.expected_micro_lanes,use_lockfile:ParseLaneCandidatesArgsShape.use_lockfile,project_root:ParseLaneCandidatesArgsShape.project_root},async execute(args2,directory){let parsed=ParseLaneCandidatesArgsSchema.safeParse(args2);if(!parsed.success)return JSON.stringify({success:!1,failure_class:"invalid_args",message:"Invalid parse_lane_candidates arguments",errors:parsed.error.issues.map((issue3)=>`${issue3.path.join(".")}: ${issue3.message}`)},null,2);let{output_ref,accept_partial,accept_degraded,degraded,row_format_version,producer,expected_family,expected_lane,expected_lanes,expected_micro_lane,expected_micro_lanes,use_lockfile,project_root}=parsed.data;if(project_root!==void 0){let absRoot=path271.resolve(project_root),absDir=path271.resolve(directory),rel=path271.relative(absDir,absRoot);if(rel===".."||rel.startsWith(`..${path271.sep}`)||path271.isAbsolute(rel))return JSON.stringify({success:!1,failure_class:"invalid_args",message:"project_root must resolve within the injected working directory",errors:[`project_root: ${project_root} is outside the project root ${directory}`]},null,2)}let loaded;try{loaded=readLaneOutput(directory,output_ref)}catch{loaded=null}if(!loaded){let relPath=REF_RE2.test(output_ref)?laneOutputRelativePath2(output_ref):"",absPath=relPath?validateSwarmPath(directory,relPath):"",artifactStatus=(absPath?existsSync139(absPath):!1)?"artifact-corrupted":"ref-not-found",refParts=output_ref.split(":"),hasValidRef=REF_RE2.test(output_ref)&&refParts.length===4,syntheticBatchId=hasValidRef?refParts[1]:"unknown",syntheticLaneId=hasValidRef?refParts[2]:"unknown",syntheticDigest="0".repeat(64),artifactInput2={output_ref,batchId:syntheticBatchId,laneId:syntheticLaneId,agent:"unknown",role:"unknown",digest:syntheticDigest,text:"",artifact_status:artifactStatus,source:"dispatch_lanes",produced_at:new Date().toISOString()},flags2={accept_partial,accept_degraded,degraded,row_format_version,...producer?{producer}:{},...expected_family?{expected_family}:{},...expected_lane?{expected_lane}:{},...expected_lanes?{expected_lanes}:{},...expected_micro_lane?{expected_micro_lane}:{},...expected_micro_lanes?{expected_micro_lanes}:{}},result2=parseAndPersist(artifactInput2,flags2,{projectRoot:project_root??directory,useLockfile:use_lockfile,batchDigest:syntheticBatchId});return JSON.stringify(result2,null,2)}let artifact=loaded.artifact,artifactInput={output_ref:artifact.ref,batchId:artifact.batchId,laneId:artifact.laneId,agent:artifact.agent,role:artifact.role,...artifact.sessionId!==void 0?{sessionId:artifact.sessionId}:{},...artifact.parentSessionId!==void 0?{parentSessionId:artifact.parentSessionId}:{},digest:artifact.digest,text:artifact.text,transcriptIncomplete:artifact.transcriptIncomplete,artifact_status:"ok",source:artifact.source,produced_at:artifact.createdAt??artifact.updatedAt},flags={accept_partial,accept_degraded,degraded,row_format_version,...producer?{producer}:{},...expected_family?{expected_family}:{},...expected_lane?{expected_lane}:{},...expected_lanes?{expected_lanes}:{},...expected_micro_lane?{expected_micro_lane}:{},...expected_micro_lanes?{expected_micro_lanes}:{}},result=parseAndPersist(artifactInput,flags,{projectRoot:project_root??directory,useLockfile:use_lockfile});return JSON.stringify(result,null,2)}});init_zod();init_config();init_plan_schema();init_schema();init_manager2();import*as fs168 from"node:fs";import*as path281 from"node:path";init_task_file();init_utils2();init_logger();init_state3();import*as fs159 from"node:fs";import*as path272 from"node:path";var APPROVAL_TTL_MS=86400000;function readEvidenceDir(directory,phase){try{let dirPath=validateSwarmPath(directory,path272.posix.join("evidence",String(phase)));if(!fs159.existsSync(dirPath))return[];return fs159.readdirSync(dirPath).filter((e)=>e.startsWith("full-auto-")&&e.endsWith(".json")).map((e)=>path272.join(dirPath,e))}catch{return[]}}function parseEvidence(filePath){try{let raw=fs159.readFileSync(filePath,"utf-8");return JSON.parse(raw)}catch(error93){warn(`[full-auto/phase-approval] failed to parse ${filePath}: ${error93 instanceof Error?error93.message:String(error93)}`);return}}function verifyFullAutoPhaseApproval(directory,sessionID,phase,config3){let fullAutoConfig=config3.full_auto;if(!sessionID)return{ok:!0,reason:"no sessionID — gate skipped"};if(!isFullAutoRunActive(directory,sessionID))return{ok:!0,reason:"no active Full-Auto run"};let failClosed=fullAutoConfig?.fail_closed!==!1,files=readEvidenceDir(directory,phase);if(files.length===0)return failClosed?{ok:!1,reason:`Full-Auto v2 active but no full-auto oversight evidence found at .swarm/evidence/${phase}/`}:{ok:!0,reason:"no evidence and fail_closed=false"};let phaseBoundary=files.map((f)=>parseEvidence(f)).filter((e)=>Boolean(e)).filter((e)=>e.phase===phase&&e.trigger_source==="phase_boundary"&&(e.verdict??"").toUpperCase()==="APPROVED");if(phaseBoundary.length===0)return failClosed?{ok:!1,reason:`Full-Auto v2 active but no phase-boundary oversight record found for phase ${phase}`}:{ok:!0,reason:"no phase-boundary record and fail_closed=false"};phaseBoundary.sort((a,b)=>{let ta=a.timestamp?Date.parse(a.timestamp):0;return(b.timestamp?Date.parse(b.timestamp):0)-ta});let latest=phaseBoundary[0],verdict=latest.verdict?.toUpperCase()??"";if(verdict!=="APPROVED")return{ok:!1,reason:`Full-Auto oversight verdict for phase ${phase} is ${verdict||"MISSING"} (required: APPROVED)`,evidence:latest};let FORWARD_SKEW_MS=300000,ts=latest.timestamp?Date.parse(latest.timestamp):0,age=Date.now()-ts;if(!ts||age<-FORWARD_SKEW_MS||age>APPROVAL_TTL_MS)return{ok:!1,reason:age<-FORWARD_SKEW_MS?`Full-Auto oversight evidence for phase ${phase} has a future timestamp (${latest.timestamp}); rejected as forged or clock-skewed`:`Full-Auto oversight evidence for phase ${phase} is stale (>24h)`,evidence:latest};if((Array.isArray(latest.evidence_checked)?latest.evidence_checked:[]).length===0){let exception=phaseIsExplicitlyNonCode(directory,phase),runState=loadFullAutoRunState(directory,sessionID),codeWorkObserved=(runState?.counters.coderDelegations??0)>0||(runState?.counters.toolCalls??0)>0;if(!exception||codeWorkObserved)return{ok:!1,reason:!exception?`Full-Auto oversight evidence for phase ${phase} has empty evidence_checked and the phase is not declared non-code in plan.json (required: at least one verification source)`:`Full-Auto oversight evidence for phase ${phase} has empty evidence_checked while run counters indicate code work was performed`,evidence:latest};return{ok:!0,reason:`Full-Auto oversight APPROVED at ${latest.timestamp} (non-code phase exception)`,evidence:latest}}return{ok:!0,reason:`Full-Auto oversight APPROVED at ${latest.timestamp}`,evidence:latest}}function phaseIsExplicitlyNonCode(directory,phase){try{let planPath=validateSwarmPath(directory,"plan.json");if(!fs159.existsSync(planPath))return!1;let raw=fs159.readFileSync(planPath,"utf-8"),plan=JSON.parse(raw),entry=(Array.isArray(plan.phases)?plan.phases:[]).find((p)=>p.id===phase||p.phase===phase);if(!entry)return!1;if(entry.non_code===!0)return!0;let kindOrType=(entry.kind??entry.type??"").toString().toLowerCase();return["docs","documentation","spec","specification","research","planning","plan","non_code","non-code","noncode"].includes(kindOrType)}catch(error93){return warn(`[full-auto/phase-approval] plan.json inspection failed: ${error93 instanceof Error?error93.message:String(error93)}`),!1}}init_gate_evidence();init_curator();init_curator_llm_factory();init_extractors();init_knowledge_curator();init_knowledge_reader();init_knowledge_receipt_ledger();init_knowledge_store();init_knowledge_events();init_knowledge_receipt_ledger();async function evaluatePhaseCriticalDirectives(params){try{if(!params.phaseLabel?.trim())throw Error("directive gate requires exact phase identity");let state=await queryLiveMemberships(params.directory,{phase:params.phaseLabel,session_id:params.sessionId?.trim()||void 0,include_terminal:!0,include_phase_closed:!1});if(!state.ok)throw Error(state.detail);let criticals=state.memberships.filter((membership)=>membership.critical);if(!params.sessionId?.trim()&&criticals.length>0)throw Error("directive gate requires exact session identity");if(criticals.length===0)return{blocked:!1,unresolved:[],overridden:[],failedClosed:!1};let unresolved=[],overridden=[];for(let membership of criticals){let terminal=membership.terminal;if(terminal?.authorized_transition){overridden.push(membership.entry_id);continue}if(terminal?.outcome==="applied")continue;if((terminal?.outcome==="ignored"||terminal?.outcome==="n_a")&&terminal.reason?.trim())continue;unresolved.push({id:membership.entry_id,trace_id:membership.trace_id,reason:terminal?.outcome==="violated"||terminal?.outcome==="contradicted"?"unremediated_violation":"no_verdict"})}return{blocked:unresolved.length>0,unresolved,overridden,failedClosed:!1}}catch{return{blocked:!0,unresolved:[],overridden:[],failedClosed:!0}}}async function recordDirectiveOverrides(directory,ids,justification,sessionId,phaseLabel){if(!justification.trim())throw Error("directive override requires a written justification");if(!sessionId?.trim()||!phaseLabel?.trim())throw Error("directive override requires exact session and phase identity");let state=await queryLiveMemberships(directory,{phase:phaseLabel,session_id:sessionId,include_terminal:!0,include_phase_closed:!1});if(!state.ok)throw Error(state.detail);let criticals=state.memberships.filter((membership)=>membership.critical),selected=ids.map((requested)=>{let exact=criticals.filter((membership)=>`${membership.trace_id}/${membership.entry_id}`===requested);if(exact.length===1)return exact[0];let byEntry=criticals.filter((membership)=>membership.entry_id===requested);if(byEntry.length!==1)throw Error(byEntry.length===0?`unknown directive override target: ${requested}`:`ambiguous directive override target; use trace_id/entry_id: ${requested}`);return byEntry[0]});for(let membership of selected){let outcome=membership.terminal?.outcome??"n_a",committed=await validateAndCommitTerminalBatch(directory,{trace_id:membership.trace_id,session_id:sessionId,phase:phaseLabel,task_id:membership.task_id,items:[{entry_id:membership.entry_id,outcome,source:"phase_override",reason:justification}],authorization:{actor:"phase-override",reason:justification,expected_event_id:membership.terminal?.event_id??""}});if(!committed.ok||committed.rejected.length>0)throw Error("failed to persist authoritative directive override");try{await recordKnowledgeEvent(directory,{type:"override",trace_id:membership.trace_id,knowledge_id:membership.entry_id,session_id:sessionId,agent:"architect",source:"phase_override",reason:`override: ${justification}`.slice(0,280)})}catch{}}}function formatDirectiveBlockMessage(unresolved){return["PHASE_COMPLETE_BLOCKED: unresolved critical knowledge directive(s):",...unresolved.map((u)=>{let why=u.reason==="no_verdict"?"no terminal verdict (applied/verified/ignored+reason/n_a+reason)":"violated with no subsequent applied/verified remediation";return` - ${u.trace_id?`${u.trace_id}/${u.id}`:u.id}: ${why}`}),"Resolve each by applying/verifying the directive, recording an explicit","ignored/n_a with a reason, or (architect only) accept_violations with a","written justification."].join(`
6576
+ `)[0]},null,2);return JSON.stringify({clean:total===0&&!run.stdoutTruncated&&!run.stderrTruncated,findings,total,truncated:total>maxResults||run.stdoutTruncated||run.stderrTruncated,command:["osv-scanner",...osvArgs],scanPath,outputTruncated:run.stdoutTruncated||run.stderrTruncated,note:run.exitCode!==0&&total>0?`osv-scanner exited ${run.exitCode} after finding vulnerabilities`:run.stdoutTruncated||run.stderrTruncated?"osv-scanner output was truncated; result is incomplete.":void 0},null,2)}}),_internals210={resolveExecutableFromPath,resolveOsvScannerBinary,runExternalTool,parseOsvOutput};init_zod();init_candidate_contract();init_candidate_parser();init_lane_output_store();init_utils2();init_create_tool();import{existsSync as existsSync140}from"node:fs";import*as path271 from"node:path";var ParseLaneCandidatesArgsShape={output_ref:exports_external.string().min(1).describe("Opaque lane output ref returned as output_ref by dispatch_lanes or collect_lane_results."),accept_partial:exports_external.boolean().default(!1).describe("Accept sources where transcriptIncomplete is true (partial transcripts)."),accept_degraded:exports_external.boolean().default(!1).describe("Accept sources where the artifact storage was degraded (output_degraded)."),degraded:exports_external.boolean().default(!1).describe("Passed through from DispatchLaneResult.output_degraded by the orchestrator."),row_format_version:exports_external.number().int().nonnegative().default(1).describe("Row format version; currently only version 1 is supported."),producer:exports_external.string().optional().default("swarm-pr-review").describe("Producer label for cross-skill filtering in the sidecar."),expected_family:exports_external.enum(["base_explorer","micro_lane"]).optional().describe("Assert the row family for this dispatch batch. A recognizable conflicting header is refused."),expected_lane:exports_external.string().trim().min(1).max(120).optional().describe("Assert the base-explorer lane linked to this dispatch provenance. Requires expected_family=base_explorer; mismatched base CLEAN attestations are refused."),expected_lanes:exports_external.array(exports_external.string().trim().min(1).max(120)).min(1).max(11).optional().describe("Full owned base-explorer lane set for a consolidated batch. Requires expected_family=base_explorer and expected_lane; owned-but-not-expected lanes are skipped as out-of-scope for this per-lane call instead of refused, while foreign lanes are still refused."),expected_micro_lane:exports_external.string().trim().min(1).max(120).optional().describe("Assert the micro-lane label linked to this dispatch provenance. Requires expected_family=micro_lane; mismatched candidates and CLEAN attestations are refused."),expected_micro_lanes:exports_external.array(exports_external.string().trim().min(1).max(120)).min(1).max(11).optional().describe("Full owned family set of a consolidated depth-tier lane. Requires expected_family=micro_lane and expected_micro_lane; rows for owned-but-not-expected families are skipped as out-of-scope for this per-family call instead of refused, while families outside the set are still refused."),use_lockfile:exports_external.boolean().default(!1).describe("When true, use proper-lockfile for concurrency-safe sidecar writes."),project_root:exports_external.string().optional().describe("Project root directory where .swarm/ lives. Defaults to the injected working directory.")},ParseLaneCandidatesArgsSchema=exports_external.object(ParseLaneCandidatesArgsShape).strict().superRefine((value,context)=>{for(let issue3 of analyzeCandidateLaneContext(value))context.addIssue({code:exports_external.ZodIssueCode.custom,path:[issue3.field],message:issue3.message})}),REF_RE2=/^L1:[a-f0-9]{64}:[a-f0-9]{64}:[a-f0-9]{64}$/;function laneOutputRelativePath2(ref){let parts=ref.split(":");if(parts.length!==4)return"";let[,batchDigest,laneDigest,outputDigest]=parts;return path271.join("lane-results",batchDigest,laneDigest,`${outputDigest}.json`)}var parse_lane_candidates=createSwarmTool({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.",args:{output_ref:ParseLaneCandidatesArgsShape.output_ref,accept_partial:ParseLaneCandidatesArgsShape.accept_partial,accept_degraded:ParseLaneCandidatesArgsShape.accept_degraded,degraded:ParseLaneCandidatesArgsShape.degraded,row_format_version:ParseLaneCandidatesArgsShape.row_format_version,producer:ParseLaneCandidatesArgsShape.producer,expected_family:ParseLaneCandidatesArgsShape.expected_family,expected_lane:ParseLaneCandidatesArgsShape.expected_lane,expected_lanes:ParseLaneCandidatesArgsShape.expected_lanes,expected_micro_lane:ParseLaneCandidatesArgsShape.expected_micro_lane,expected_micro_lanes:ParseLaneCandidatesArgsShape.expected_micro_lanes,use_lockfile:ParseLaneCandidatesArgsShape.use_lockfile,project_root:ParseLaneCandidatesArgsShape.project_root},async execute(args2,directory){let parsed=ParseLaneCandidatesArgsSchema.safeParse(args2);if(!parsed.success)return JSON.stringify({success:!1,failure_class:"invalid_args",message:"Invalid parse_lane_candidates arguments",errors:parsed.error.issues.map((issue3)=>`${issue3.path.join(".")}: ${issue3.message}`)},null,2);let{output_ref,accept_partial,accept_degraded,degraded,row_format_version,producer,expected_family,expected_lane,expected_lanes,expected_micro_lane,expected_micro_lanes,use_lockfile,project_root}=parsed.data;if(project_root!==void 0){let absRoot=path271.resolve(project_root),absDir=path271.resolve(directory),rel=path271.relative(absDir,absRoot);if(rel===".."||rel.startsWith(`..${path271.sep}`)||path271.isAbsolute(rel))return JSON.stringify({success:!1,failure_class:"invalid_args",message:"project_root must resolve within the injected working directory",errors:[`project_root: ${project_root} is outside the project root ${directory}`]},null,2)}let loaded;try{loaded=readLaneOutput(directory,output_ref)}catch{loaded=null}if(!loaded){let relPath=REF_RE2.test(output_ref)?laneOutputRelativePath2(output_ref):"",absPath=relPath?validateSwarmPath(directory,relPath):"",artifactStatus=(absPath?existsSync140(absPath):!1)?"artifact-corrupted":"ref-not-found",refParts=output_ref.split(":"),hasValidRef=REF_RE2.test(output_ref)&&refParts.length===4,syntheticBatchId=hasValidRef?refParts[1]:"unknown",syntheticLaneId=hasValidRef?refParts[2]:"unknown",syntheticDigest="0".repeat(64),artifactInput2={output_ref,batchId:syntheticBatchId,laneId:syntheticLaneId,agent:"unknown",role:"unknown",digest:syntheticDigest,text:"",artifact_status:artifactStatus,source:"dispatch_lanes",produced_at:new Date().toISOString()},flags2={accept_partial,accept_degraded,degraded,row_format_version,...producer?{producer}:{},...expected_family?{expected_family}:{},...expected_lane?{expected_lane}:{},...expected_lanes?{expected_lanes}:{},...expected_micro_lane?{expected_micro_lane}:{},...expected_micro_lanes?{expected_micro_lanes}:{}},result2=parseAndPersist(artifactInput2,flags2,{projectRoot:project_root??directory,useLockfile:use_lockfile,batchDigest:syntheticBatchId});return JSON.stringify(result2,null,2)}let artifact=loaded.artifact,artifactInput={output_ref:artifact.ref,batchId:artifact.batchId,laneId:artifact.laneId,agent:artifact.agent,role:artifact.role,...artifact.sessionId!==void 0?{sessionId:artifact.sessionId}:{},...artifact.parentSessionId!==void 0?{parentSessionId:artifact.parentSessionId}:{},digest:artifact.digest,text:artifact.text,transcriptIncomplete:artifact.transcriptIncomplete,artifact_status:"ok",source:artifact.source,produced_at:artifact.createdAt??artifact.updatedAt},flags={accept_partial,accept_degraded,degraded,row_format_version,...producer?{producer}:{},...expected_family?{expected_family}:{},...expected_lane?{expected_lane}:{},...expected_lanes?{expected_lanes}:{},...expected_micro_lane?{expected_micro_lane}:{},...expected_micro_lanes?{expected_micro_lanes}:{}},result=parseAndPersist(artifactInput,flags,{projectRoot:project_root??directory,useLockfile:use_lockfile});return JSON.stringify(result,null,2)}});init_zod();init_config();init_plan_schema();init_schema();init_manager2();import*as fs168 from"node:fs";import*as path281 from"node:path";init_task_file();init_utils2();init_logger();init_state3();import*as fs159 from"node:fs";import*as path272 from"node:path";var APPROVAL_TTL_MS=86400000;function readEvidenceDir(directory,phase){try{let dirPath=validateSwarmPath(directory,path272.posix.join("evidence",String(phase)));if(!fs159.existsSync(dirPath))return[];return fs159.readdirSync(dirPath).filter((e)=>e.startsWith("full-auto-")&&e.endsWith(".json")).map((e)=>path272.join(dirPath,e))}catch{return[]}}function parseEvidence(filePath){try{let raw=fs159.readFileSync(filePath,"utf-8");return JSON.parse(raw)}catch(error93){warn(`[full-auto/phase-approval] failed to parse ${filePath}: ${error93 instanceof Error?error93.message:String(error93)}`);return}}function verifyFullAutoPhaseApproval(directory,sessionID,phase,config3){let fullAutoConfig=config3.full_auto;if(!sessionID)return{ok:!0,reason:"no sessionID — gate skipped"};if(!isFullAutoRunActive(directory,sessionID))return{ok:!0,reason:"no active Full-Auto run"};let failClosed=fullAutoConfig?.fail_closed!==!1,files=readEvidenceDir(directory,phase);if(files.length===0)return failClosed?{ok:!1,reason:`Full-Auto v2 active but no full-auto oversight evidence found at .swarm/evidence/${phase}/`}:{ok:!0,reason:"no evidence and fail_closed=false"};let phaseBoundary=files.map((f)=>parseEvidence(f)).filter((e)=>Boolean(e)).filter((e)=>e.phase===phase&&e.trigger_source==="phase_boundary"&&(e.verdict??"").toUpperCase()==="APPROVED");if(phaseBoundary.length===0)return failClosed?{ok:!1,reason:`Full-Auto v2 active but no phase-boundary oversight record found for phase ${phase}`}:{ok:!0,reason:"no phase-boundary record and fail_closed=false"};phaseBoundary.sort((a,b)=>{let ta=a.timestamp?Date.parse(a.timestamp):0;return(b.timestamp?Date.parse(b.timestamp):0)-ta});let latest=phaseBoundary[0],verdict=latest.verdict?.toUpperCase()??"";if(verdict!=="APPROVED")return{ok:!1,reason:`Full-Auto oversight verdict for phase ${phase} is ${verdict||"MISSING"} (required: APPROVED)`,evidence:latest};let FORWARD_SKEW_MS=300000,ts=latest.timestamp?Date.parse(latest.timestamp):0,age=Date.now()-ts;if(!ts||age<-FORWARD_SKEW_MS||age>APPROVAL_TTL_MS)return{ok:!1,reason:age<-FORWARD_SKEW_MS?`Full-Auto oversight evidence for phase ${phase} has a future timestamp (${latest.timestamp}); rejected as forged or clock-skewed`:`Full-Auto oversight evidence for phase ${phase} is stale (>24h)`,evidence:latest};if((Array.isArray(latest.evidence_checked)?latest.evidence_checked:[]).length===0){let exception=phaseIsExplicitlyNonCode(directory,phase),runState=loadFullAutoRunState(directory,sessionID),codeWorkObserved=(runState?.counters.coderDelegations??0)>0||(runState?.counters.toolCalls??0)>0;if(!exception||codeWorkObserved)return{ok:!1,reason:!exception?`Full-Auto oversight evidence for phase ${phase} has empty evidence_checked and the phase is not declared non-code in plan.json (required: at least one verification source)`:`Full-Auto oversight evidence for phase ${phase} has empty evidence_checked while run counters indicate code work was performed`,evidence:latest};return{ok:!0,reason:`Full-Auto oversight APPROVED at ${latest.timestamp} (non-code phase exception)`,evidence:latest}}return{ok:!0,reason:`Full-Auto oversight APPROVED at ${latest.timestamp}`,evidence:latest}}function phaseIsExplicitlyNonCode(directory,phase){try{let planPath=validateSwarmPath(directory,"plan.json");if(!fs159.existsSync(planPath))return!1;let raw=fs159.readFileSync(planPath,"utf-8"),plan=JSON.parse(raw),entry=(Array.isArray(plan.phases)?plan.phases:[]).find((p)=>p.id===phase||p.phase===phase);if(!entry)return!1;if(entry.non_code===!0)return!0;let kindOrType=(entry.kind??entry.type??"").toString().toLowerCase();return["docs","documentation","spec","specification","research","planning","plan","non_code","non-code","noncode"].includes(kindOrType)}catch(error93){return warn(`[full-auto/phase-approval] plan.json inspection failed: ${error93 instanceof Error?error93.message:String(error93)}`),!1}}init_gate_evidence();init_curator();init_curator_llm_factory();init_extractors();init_knowledge_curator();init_knowledge_reader();init_knowledge_receipt_ledger();init_knowledge_store();init_knowledge_events();init_knowledge_receipt_ledger();async function evaluatePhaseCriticalDirectives(params){try{if(!params.phaseLabel?.trim())throw Error("directive gate requires exact phase identity");let state=await queryLiveMemberships(params.directory,{phase:params.phaseLabel,session_id:params.sessionId?.trim()||void 0,include_terminal:!0,include_phase_closed:!1});if(!state.ok)throw Error(state.detail);let criticals=state.memberships.filter((membership)=>membership.critical);if(!params.sessionId?.trim()&&criticals.length>0)throw Error("directive gate requires exact session identity");if(criticals.length===0)return{blocked:!1,unresolved:[],overridden:[],failedClosed:!1};let unresolved=[],overridden=[];for(let membership of criticals){let terminal=membership.terminal;if(terminal?.authorized_transition){overridden.push(membership.entry_id);continue}if(terminal?.outcome==="applied")continue;if((terminal?.outcome==="ignored"||terminal?.outcome==="n_a")&&terminal.reason?.trim())continue;unresolved.push({id:membership.entry_id,trace_id:membership.trace_id,reason:terminal?.outcome==="violated"||terminal?.outcome==="contradicted"?"unremediated_violation":"no_verdict"})}return{blocked:unresolved.length>0,unresolved,overridden,failedClosed:!1}}catch{return{blocked:!0,unresolved:[],overridden:[],failedClosed:!0}}}async function recordDirectiveOverrides(directory,ids,justification,sessionId,phaseLabel){if(!justification.trim())throw Error("directive override requires a written justification");if(!sessionId?.trim()||!phaseLabel?.trim())throw Error("directive override requires exact session and phase identity");let state=await queryLiveMemberships(directory,{phase:phaseLabel,session_id:sessionId,include_terminal:!0,include_phase_closed:!1});if(!state.ok)throw Error(state.detail);let criticals=state.memberships.filter((membership)=>membership.critical),selected=ids.map((requested)=>{let exact=criticals.filter((membership)=>`${membership.trace_id}/${membership.entry_id}`===requested);if(exact.length===1)return exact[0];let byEntry=criticals.filter((membership)=>membership.entry_id===requested);if(byEntry.length!==1)throw Error(byEntry.length===0?`unknown directive override target: ${requested}`:`ambiguous directive override target; use trace_id/entry_id: ${requested}`);return byEntry[0]});for(let membership of selected){let outcome=membership.terminal?.outcome??"n_a",committed=await validateAndCommitTerminalBatch(directory,{trace_id:membership.trace_id,session_id:sessionId,phase:phaseLabel,task_id:membership.task_id,items:[{entry_id:membership.entry_id,outcome,source:"phase_override",reason:justification}],authorization:{actor:"phase-override",reason:justification,expected_event_id:membership.terminal?.event_id??""}});if(!committed.ok||committed.rejected.length>0)throw Error("failed to persist authoritative directive override");try{await recordKnowledgeEvent(directory,{type:"override",trace_id:membership.trace_id,knowledge_id:membership.entry_id,session_id:sessionId,agent:"architect",source:"phase_override",reason:`override: ${justification}`.slice(0,280)})}catch{}}}function formatDirectiveBlockMessage(unresolved){return["PHASE_COMPLETE_BLOCKED: unresolved critical knowledge directive(s):",...unresolved.map((u)=>{let why=u.reason==="no_verdict"?"no terminal verdict (applied/verified/ignored+reason/n_a+reason)":"violated with no subsequent applied/verified remediation";return` - ${u.trace_id?`${u.trace_id}/${u.id}`:u.id}: ${why}`}),"Resolve each by applying/verifying the directive, recording an explicit","ignored/n_a with a reason, or (architect only) accept_violations with a","written justification."].join(`
6570
6577
  `)}init_review_receipt();init_skill_usage_log();init_utils2();init_file_locks();init_plan_schema();init_ledger();init_utils3();init_warning_buffer();init_logger();init_project_boundary();init_manager();import*as fs160 from"node:fs";import*as path273 from"node:path";var _fsInternals={mkdirSync:(...args2)=>fs160.mkdirSync(...args2),writeFileSync:(path274,data,encoding)=>fs160.writeFileSync(path274,data,encoding??"utf8"),readFileSync:(path274,encoding)=>fs160.readFileSync(path274,encoding??"utf8"),existsSync:(path274)=>fs160.existsSync(path274)};async function writeCheckpoint(directory){try{assertProjectRoot(directory);let plan=await loadPlan(directory);if(!plan)return;let exportDir=path273.join(directory,".swarm","plan-export");_fsInternals.mkdirSync(exportDir,{recursive:!0});let jsonPath=path273.join(exportDir,"SWARM_PLAN.json"),mdPath=path273.join(exportDir,"SWARM_PLAN.md");_fsInternals.writeFileSync(jsonPath,JSON.stringify(plan,null,2));let md=derivePlanMarkdown(plan),header=`<!--
6571
6578
  AUTO-GENERATED EXPORT/CHECKPOINT SNAPSHOT — DO NOT EDIT
6572
6579
  This file is NOT the live plan. It is a derived export artifact.
@@ -6578,7 +6585,7 @@ Regenerated on: save_plan and phase_complete.
6578
6585
  `),existing=relatedExisting.slice(0,20).map((m)=>`[${m.id}] kind=${m.kind} | ${m.text}`).join(`
6579
6586
  `);return["You are consolidating raw episodic memory into durable semantic facts.","","Episodic events (verbatim):",episodic,"","Existing durable memories (for dedup/contradiction):",existing||"(none)","",'Emit STRICT JSON only: {"facts":[{"text":..,"kind":..,"confidence":0-1,"contradictsMemoryId"?:"mem_..."}]}',"Rules: only emit facts directly supported by the cited episodic evidence.","If uncertain, omit the fact (emit fewer facts or an empty array).",`Use durable kinds (${Array.from(DURABLE_MEMORY_KINDS).join(", ")}); keep each fact under ${CURATOR_PROMOTED_MEMORY_MAX_TEXT_LENGTH} characters.`,"Set contradictsMemoryId only when a fact directly conflicts with an existing memory above.",'Never include the literal text "## Retrieved Swarm Memory".'].join(`
6580
6587
  `)}function aggregateEvidence(cluster,phaseNumber){let refs=new Set;for(let p of cluster)for(let ref of p.evidenceRefs)refs.add(ref);let list=Array.from(refs).slice(0,19);return list.push(`consolidation:phase-${phaseNumber}`),list}async function runConsolidationPass(input,deps){let{phaseNumber,runId,config:config3}=input,consolidation=config3.consolidation,base={skipped:!0,phaseNumber,clusterCount:0,clustersDeferred:0,decisionsEmitted:0,added:0,superseded:0,contradictionsDetected:0,deduped:0,proposed:0,memoriesDecayed:0,errored:0};if(!config3.enabled||!consolidation.enabled||!deps.gateway.isEnabled())return{...base,skipReason:"disabled"};let priorLog=await deps.readLog();if(priorLog.some((r)=>r.phaseNumber===phaseNumber))return{...base,skipReason:"already_consolidated"};let processedBefore=new Set(priorLog.flatMap((r)=>r.processedProposalIds)),startedAt=deps.now().toISOString(),logKey=runId??"unknown";await deps.logEvent({event:"consolidation_started",runId:logKey,phaseNumber,timestamp:startedAt});let pendingProposals=(await deps.gateway.listProposals({status:"pending"})).filter((p)=>p.proposedBy?.agentRole!==CONSOLIDATION_AGENT_ROLE&&!processedBefore.has(p.id)).sort((a,b)=>a.id.localeCompare(b.id)),existingMemories=await deps.gateway.listMemories({}),clusters=clusterByJaccard(pendingProposals,(p)=>p.proposedRecord?.text??p.rationale,consolidation.jaccardThreshold),processable=clusters.slice(0,consolidation.maxClustersPerPass),clustersDeferred=Math.max(0,clusters.length-processable.length);await deps.logEvent({event:"cluster_count",runId:logKey,phaseNumber,clusterCount:clusters.length});let result={...base,skipped:!1,clusterCount:clusters.length,clustersDeferred},processedProposalIds=new Set;if(!deps.llmDelegate){if(result.memoriesDecayed=await applyDecay(existingMemories,input,deps),deps.signal?.aborted)return{...result,skipped:!0,skipReason:"aborted"};return await finalize2(input,deps,result,startedAt,processedProposalIds),{...result,skipReason:"no_llm_delegate_decay_only"}}let seenFactTexts=new Set;for(let cluster of processable){if(deps.signal?.aborted)return{...result,skipped:!0,skipReason:"aborted"};for(let p of cluster)processedProposalIds.add(p.id);let raw;try{let prompt=buildDistillationPrompt(cluster,existingMemories);raw=await deps.llmDelegate("",prompt,deps.signal)}catch{result.errored++;continue}let facts=parseDistillationOutput(raw),evidenceRefs=aggregateEvidence(cluster,phaseNumber);for(let fact of facts){let normalized=fact.text.replace(/\s+/g," ").trim().toLowerCase();if(seenFactTexts.has(normalized))continue;seenFactTexts.add(normalized);let plan=deriveDecision(fact,existingMemories,{autoApplyMinConfidence:consolidation.autoApplyMinConfidence,jaccardThreshold:consolidation.jaccardThreshold});try{await executePlan(plan,evidenceRefs,input,deps,result)}catch{result.errored++}}}if(deps.signal?.aborted)return{...result,skipped:!0,skipReason:"aborted"};if(result.memoriesDecayed=await applyDecay(existingMemories,input,deps),deps.signal?.aborted)return{...result,skipped:!0,skipReason:"aborted"};return await finalize2(input,deps,result,startedAt,processedProposalIds),result}async function executePlan(plan,evidenceRefs,input,deps,result){let{phaseNumber}=input;if(plan.type==="skip")return;if(plan.type==="dedup"){result.deduped++;return}let newRecord={kind:plan.fact.kind,text:plan.fact.text,confidence:plan.fact.confidence,stability:"durable",source:sourceForDistilled(evidenceRefs,phaseNumber),metadata:{consolidatedFromPhase:phaseNumber}},rationale=`consolidation phase ${phaseNumber}`;if(((plan.type==="add"||plan.type==="supersede")&&EVIDENCE_REQUIRED_KINDS.has(plan.fact.kind)&&!hasRealEvidence(evidenceRefs)?"proposal":plan.type)==="proposal"){await deps.gateway.propose({operation:plan.type==="supersede"?"supersede":"add",kind:plan.fact.kind,text:plan.fact.text,rationale:plan.type==="proposal"?`${rationale}: ${plan.reason}`:`${rationale}: evidence-required kind lacks real evidence source`,evidenceRefs,...plan.type==="supersede"?{targetMemoryId:plan.oldMemoryId}:{}}),result.proposed++;return}if(plan.type==="supersede"){let proposal2=await deps.gateway.propose({operation:"supersede",kind:plan.fact.kind,text:plan.fact.text,targetMemoryId:plan.oldMemoryId,rationale,evidenceRefs});if(proposal2.status!=="pending"){result.proposed++;return}await deps.gateway.applyCuratorDecision({action:"supersede",proposalId:proposal2.id,oldMemoryId:plan.oldMemoryId,replacement:newRecord,reason:`contradiction superseded during phase ${phaseNumber} consolidation`}),result.superseded++,result.contradictionsDetected++,result.decisionsEmitted++;return}let proposal=await deps.gateway.propose({operation:"add",kind:plan.fact.kind,text:plan.fact.text,rationale,evidenceRefs});if(proposal.status!=="pending"){result.proposed++;return}await deps.gateway.applyCuratorDecision({action:"add",proposalId:proposal.id,memory:newRecord}),result.added++,result.decisionsEmitted++}async function applyDecay(memories,input,deps){let decayed=0,halfLives=input.config.consolidation.decayHalfLifeDays,now2=deps.now();for(let memory of memories){if(deps.signal?.aborted)break;if(memory.metadata.deleted===!0||memory.supersededBy)continue;if(isPastDecayHorizon(memory,halfLives,now2))continue;let nextExpiry=computeDecayExpiry(memory,halfLives,now2);if(!nextExpiry)continue;try{await deps.gateway.upsertCurated({...memory,expiresAt:nextExpiry}),decayed++}catch{}}return decayed}async function finalize2(input,deps,result,startedAt,processedProposalIds){let{phaseNumber,runId}=input,logKey=runId??"unknown",completedAt=deps.now().toISOString();await deps.logEvent({event:"decisions_emitted",runId:logKey,phaseNumber,decisionsEmitted:result.decisionsEmitted}),await deps.logEvent({event:"contradictions_detected",runId:logKey,phaseNumber,contradictionsDetected:result.contradictionsDetected}),await deps.logEvent({event:"memories_decayed",runId:logKey,phaseNumber,memoriesDecayed:result.memoriesDecayed}),await deps.logEvent({event:"consolidation_completed",runId:logKey,phaseNumber,clusterCount:result.clusterCount,decisionsEmitted:result.decisionsEmitted,contradictionsDetected:result.contradictionsDetected,memoriesDecayed:result.memoriesDecayed,timestamp:completedAt}),await deps.appendLog({phaseNumber,runId,startedAt,completedAt,clusterCount:result.clusterCount,clustersDeferred:result.clustersDeferred,decisionsEmitted:result.decisionsEmitted,added:result.added,superseded:result.superseded,contradictionsDetected:result.contradictionsDetected,deduped:result.deduped,proposed:result.proposed,memoriesDecayed:result.memoriesDecayed,errored:result.errored,processedProposalIds:Array.from(processedProposalIds)})}init_consolidation_log();init_gateway();init_run_log();init_storage_root();var CONSOLIDATION_TIMEOUT_MS=300000,runningByDirectory2=new Map;async function runMemoryConsolidation(req){let existing=runningByDirectory2.get(req.directory);if(existing)return existing;let run=(async()=>{if(!req.config.enabled||!req.config.consolidation.enabled)return{started:!1,reason:"disabled"};let gateway=createMemoryGateway({directory:req.directory,sessionID:req.sessionId,runId:req.sessionId,agentRole:"curator_consolidation"},{config:req.config}),controller=new AbortController,timer=setTimeout(()=>controller.abort(),CONSOLIDATION_TIMEOUT_MS);timer.unref?.();try{if(!gateway.isEnabled())return{started:!1,reason:"disabled"};let llmDelegate=createCuratorLLMDelegate(req.directory,"consolidation",req.sessionId),result=await runConsolidationPass({directory:req.directory,phaseNumber:req.phase,runId:req.sessionId,config:req.config},{gateway,llmDelegate,now:()=>new Date,logEvent:(event)=>appendMemoryRunLog(req.directory,req.sessionId,event),readLog:()=>readConsolidationLog(resolveVettedMemoryRoot(req.directory,req.config)),appendLog:(record3)=>appendConsolidationLog(resolveVettedMemoryRoot(req.directory,req.config),record3),signal:controller.signal});return{started:!result.skipped,reason:result.skipReason,result}}finally{clearTimeout(timer),await gateway.dispose()}})();runningByDirectory2.set(req.directory,run);try{return await run}finally{runningByDirectory2.delete(req.directory)}}function runMemoryConsolidationFireAndForget(req,onComplete,onError){queueMicrotask(()=>{runMemoryConsolidation(req).then(onComplete).catch(onError)})}init_skill_consolidation();init_snapshot_writer();init_state2();init_telemetry();init_state();init_file_locks();import*as fs161 from"node:fs";import*as path274 from"node:path";init_state4();var DEFAULT_CONFIG3={phase_reviewer:!0,phase_critic:!0,integrated_diff_required:!1};function defaultReadPlanJson(dir){try{let planPath=path274.join(dir,".swarm","plan.json");if(!fs161.existsSync(planPath))return null;let raw=fs161.readFileSync(planPath,"utf-8"),plan=JSON.parse(raw);if(typeof plan!=="object"||plan===null||!Array.isArray(plan.phases))return null;return plan}catch{return null}}function readReviewerEvidenceFromFile(directory,phase){try{let evidencePath=path274.join(directory,".swarm","evidence",String(phase),"lean-turbo-reviewer.json");if(!fs161.existsSync(evidencePath))return null;let raw=fs161.readFileSync(evidencePath,"utf-8"),parsed=JSON.parse(raw);if(typeof parsed!=="object"||parsed===null||typeof parsed.verdict!=="string")return null;let verdict=parsed.verdict;if(verdict!=="APPROVED"&&verdict!=="NEEDS_REVISION"&&verdict!=="REJECTED")return null;return parsed}catch{return null}}function readCriticEvidenceFromFile(directory,phase){try{let evidencePath=path274.join(directory,".swarm","evidence",String(phase),"lean-turbo-critic.json");if(!fs161.existsSync(evidencePath))return null;let raw=fs161.readFileSync(evidencePath,"utf-8"),parsed=JSON.parse(raw);if(typeof parsed!=="object"||parsed===null||typeof parsed.verdict!=="string")return null;let verdict=parsed.verdict;if(verdict!=="APPROVED"&&verdict!=="NEEDS_REVISION"&&verdict!=="REJECTED"&&verdict!=="ESCALATE_TO_HUMAN")return null;return parsed}catch{return null}}function listLaneEvidenceSync(directory,phase){let evidenceDir=path274.join(directory,".swarm","evidence",String(phase),"lean-turbo"),entries;try{entries=fs161.readdirSync(evidenceDir)}catch{return[]}entries.sort();let laneIds=[];for(let entry of entries){if(!entry.endsWith(".json")||entry==="lean-turbo-phase.json")continue;laneIds.push(entry.slice(0,-5))}return laneIds}var _internals212={listActiveLocks,readPersisted:readPersisted3,readPlanJson:defaultReadPlanJson,readReviewerEvidence:readReviewerEvidenceFromFile,readCriticEvidence:readCriticEvidenceFromFile,listLaneEvidence,listLaneEvidenceSync,verifyLeanTurboPhaseReady};function validatePersistedShape(persisted){if(typeof persisted!=="object"||persisted===null)return!1;if(Array.isArray(persisted))return!1;if(typeof persisted.sessions!=="object")return!1;if(persisted.sessions===null)return!1;if(Array.isArray(persisted.sessions))return!1;return!0}function validateLanesArray(lanes){if(!Array.isArray(lanes))return!1;for(let lane of lanes){if(typeof lane!=="object"||lane===null)return!1;if(typeof lane.laneId!=="string")return!1;if(typeof lane.status!=="string")return!1}return!0}function validateDegradedTasksArray(degradedTasks){if(!Array.isArray(degradedTasks))return!1;for(let dt of degradedTasks){if(typeof dt!=="object"||dt===null)return!1;if(typeof dt.taskId!=="string")return!1}return!0}function verifyLeanTurboPhaseReady(directory,phase,sessionIDOrConfig,config3){let sessionID=typeof sessionIDOrConfig==="string"?sessionIDOrConfig:void 0,mergedConfig={...DEFAULT_CONFIG3,...typeof sessionIDOrConfig==="object"&&sessionIDOrConfig!==null?sessionIDOrConfig:config3??DEFAULT_CONFIG3},statePath=path274.join(directory,".swarm","turbo-state.json");if(!fs161.existsSync(statePath))return{ok:!1,reason:"Lean Turbo state unreadable or missing"};let persisted=_internals212.readPersisted(directory);if(!persisted)return{ok:!1,reason:"Lean Turbo state unreadable or missing"};if(!validatePersistedShape(persisted))return{ok:!1,reason:"Lean Turbo state unreadable or missing"};let runState=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){runState=sessionState;break}if(!runState&&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"){runState=sessionState;break}}if(!runState)return{ok:!1,reason:sessionID?`No active Lean Turbo session for phase ${phase} and session ${sessionID}`:`No active Lean Turbo session for phase ${phase}`};if(!validateLanesArray(runState.lanes))return{ok:!1,reason:`No active Lean Turbo session for phase ${phase}`};if(!validateDegradedTasksArray(runState.degradedTasks))return{ok:!1,reason:`No active Lean Turbo session for phase ${phase}`};if(runState.lanes.length===0&&(!Array.isArray(runState.serializedTasks)||runState.serializedTasks.length===0)&&(!Array.isArray(runState.degradedTasks)||runState.degradedTasks.length===0))return{ok:!1,reason:`No lane plan or fallback tasks found for phase ${phase}`};let laneIds=runState.lanes.map((l)=>l.laneId);if(runState.lanes.length>0){for(let lane of runState.lanes)if(lane.status!=="completed"&&lane.status!=="failed")return{ok:!1,reason:`Lane ${lane.laneId} is not completed (status: ${lane.status})`}}if(runState.lanes.length>0){let evidenceLaneIds=new Set(_internals212.listLaneEvidenceSync(directory,phase));for(let lane of runState.lanes)if((lane.status==="completed"||lane.status==="failed")&&!evidenceLaneIds.has(lane.laneId))return{ok:!1,reason:`Lane ${lane.laneId} is ${lane.status} but lane evidence file is missing`}}let activeLocks=_internals212.listActiveLocks(directory),phaseLaneIds=new Set(laneIds);for(let lock of activeLocks)if(lock.laneId&&phaseLaneIds.has(lock.laneId))return{ok:!1,reason:`Active locks remain for lane ${lock.laneId}`};let laneTaskIds=new Set;for(let lane of runState.lanes)if(Array.isArray(lane.taskIds))for(let taskId of lane.taskIds)laneTaskIds.add(taskId);let serialDegradedTasks=runState.degradedTasks.filter((dt)=>!laneTaskIds.has(dt.taskId));if(serialDegradedTasks.length>0){let plan=_internals212.readPlanJson(directory);if(!plan)return{ok:!1,reason:"Cannot verify degraded task status: plan.json unreadable or malformed"};for(let dt of serialDegradedTasks){if(!Array.isArray(plan.phases))return{ok:!1,reason:`Cannot verify degraded task ${dt.taskId}: plan.json malformed (phases is not an array)`};let planPhase=plan.phases.find((p)=>p&&typeof p==="object"&&p!==null&&p.id===phase);if(!planPhase)return{ok:!1,reason:`Cannot verify degraded task ${dt.taskId}: phase ${phase} not found in plan.json`};if(!Array.isArray(planPhase.tasks))return{ok:!1,reason:`Cannot verify degraded task ${dt.taskId}: plan.json malformed (phase ${phase} tasks is not an array)`};let task2=planPhase.tasks.find((t)=>t&&typeof t==="object"&&t!==null&&t.id===dt.taskId);if(!task2)return{ok:!1,reason:`Degraded task ${dt.taskId} not found in plan`};if(task2.status!=="completed")return{ok:!1,reason:`Degraded task ${dt.taskId} not yet completed via standard flow`}}}let serializedTasks=runState.serializedTasks;if(Array.isArray(serializedTasks)&&serializedTasks.length>0){let plan=_internals212.readPlanJson(directory);if(!plan)return{ok:!1,reason:"Cannot verify serialized task status: plan.json unreadable or malformed"};if(!Array.isArray(plan.phases))return{ok:!1,reason:"Cannot verify serialized tasks: plan.json malformed (phases is not an array)"};let planPhase=plan.phases.find((p)=>p&&typeof p==="object"&&p!==null&&p.id===phase);if(!planPhase)return{ok:!1,reason:`Cannot verify serialized tasks: phase ${phase} not found in plan.json`};if(!Array.isArray(planPhase.tasks))return{ok:!1,reason:`Cannot verify serialized tasks: plan.json malformed (phase ${phase} tasks is not an array)`};for(let serTaskId of serializedTasks){let task2=planPhase.tasks.find((t)=>t&&typeof t==="object"&&t!==null&&t.id===serTaskId);if(!task2)return{ok:!1,reason:`Serialized task ${serTaskId} not found in plan`};if(task2.status!=="completed")return{ok:!1,reason:`Serialized task ${serTaskId} not yet completed (status: ${task2.status})`}}}if(mergedConfig.integrated_diff_required){let evidencePath=path274.join(directory,".swarm","evidence",String(phase),"lean-turbo-phase.json"),hasDiff=!1;try{let content=fs161.readFileSync(evidencePath,"utf-8");hasDiff=!!JSON.parse(content).integratedDiffSummary}catch{}if(!hasDiff)return{ok:!1,reason:`Integrated diff summary is required but missing for phase ${phase}`}}let reviewerVerdict=runState.lastReviewerVerdict;if(!reviewerVerdict)reviewerVerdict=_internals212.readReviewerEvidence(directory,phase)?.verdict??void 0;if(mergedConfig.phase_reviewer){if(reviewerVerdict!=="APPROVED")return{ok:!1,reason:"Integrated reviewer approval missing or rejected"}}let criticVerdict=runState.lastCriticVerdict;if(!criticVerdict)criticVerdict=_internals212.readCriticEvidence(directory,phase)?.verdict??void 0;if(mergedConfig.phase_critic){if(criticVerdict!=="APPROVED")return{ok:!1,reason:"Integrated critic approval missing or rejected"}}return{ok:!0,reason:`Phase ${phase} is ready to advance`,evidence:{lanes:laneIds,degradedTasks:runState.degradedTasks.map((dt)=>dt.taskId),reviewerVerdict:reviewerVerdict??runState.lastReviewerVerdict,criticVerdict:criticVerdict??runState.lastCriticVerdict}}}init_logger();init_create_tool();init_store4();async function runArchitectureSupervisorGate(ctx){let{phase,dir,pluginConfig,agentsDispatched,safeWarn}=ctx,asConfig=pluginConfig.architectural_supervision,summarizeFindings=(findings)=>{if(!Array.isArray(findings)||findings.length===0)return"";let details=findings.map((f)=>f&&typeof f==="object"&&typeof f.description==="string"?f.description:void 0).filter((d)=>Boolean(d));return details.length>0?`
6581
- Findings: ${details.join("; ")}`:""},asBlocked=(reason,message)=>({blocked:!0,reason,message,agentsDispatched,agentsMissing:[],warnings:[]}),asEntry=null;try{asEntry=readSupervisorReportRaw(dir,phase)}catch(asError){return asBlocked("ARCH_SUPERVISOR_ERROR",`Phase ${phase} cannot be completed: architecture supervisor gate encountered an error. Error: ${String(asError)}`)}if(!asEntry)return asBlocked("ARCH_SUPERVISOR_REQUIRED",`Phase ${phase} cannot be completed: architectural_supervision gate mode is enabled and no architecture supervisor evidence was found at .swarm/evidence/${phase}/architecture-supervisor.json. Dispatch critic_architecture_supervisor with the phase + agent summaries, then call write_architecture_supervisor_evidence.`);let now2=new Date,asTime=asEntry.timestamp?new Date(asEntry.timestamp):null;if(!asTime||Number.isNaN(asTime.getTime()))return asBlocked("ARCH_SUPERVISOR_INVALID_TIMESTAMP",`Phase ${phase} cannot be completed: architecture supervisor evidence has a missing or invalid timestamp.`);if(asTime.getTime()>now2.getTime())return asBlocked("ARCH_SUPERVISOR_FUTURE_TIMESTAMP",`Phase ${phase} cannot be completed: architecture supervisor evidence timestamp is in the future.`);if(now2.getTime()-asTime.getTime()>86400000)return asBlocked("ARCH_SUPERVISOR_STALE_EVIDENCE",`Phase ${phase} cannot be completed: architecture supervisor evidence is older than 24 hours. Re-run the supervisor for fresh review.`);if(typeof asEntry.phase_number!=="number"||asEntry.phase_number!==phase)return asBlocked("ARCH_SUPERVISOR_PHASE_MISMATCH",`Phase ${phase} cannot be completed: architecture supervisor evidence is for phase ${String(asEntry.phase_number)}, not phase ${phase}.`);let gateWarnings=[];if(asConfig?.provenance_verify===!0){let provenance=asEntry.provenance;if(!provenance||!provenance.agent_name&&!provenance.session_id)return asBlocked("ARCH_SUPERVISOR_MISSING_PROVENANCE",`Phase ${phase} cannot be completed: architecture supervisor evidence lacks provenance (agent_name or session_id). Evidence provenance verification is enabled.`)}else if(!asEntry.provenance||!asEntry.provenance.agent_name&&!asEntry.provenance.session_id){let msg=`Architecture supervisor evidence lacks provenance for phase ${phase}. Enable 'provenance_verify' in architectural_supervision config to enforce provenance verification.`;gateWarnings.push(msg),safeWarn(`[phase_complete] ${msg}`,void 0)}let asVerdict=asEntry.verdict;if(asVerdict==="REJECT")return asBlocked("ARCH_SUPERVISOR_REJECTED",`Phase ${phase} cannot be completed: architecture supervisor returned verdict 'REJECT'. Address the system-level findings before completing the phase.${summarizeFindings(asEntry.findings)}`);if(asVerdict==="CONCERNS"){if(asConfig?.allow_concerns_to_complete===!1)return asBlocked("ARCH_SUPERVISOR_CONCERNS",`Phase ${phase} cannot be completed: architecture supervisor returned verdict 'CONCERNS' and allow_concerns_to_complete is disabled.${summarizeFindings(asEntry.findings)}`);safeWarn(`[phase_complete] Architecture supervisor returned CONCERNS for phase ${phase} — proceeding (allow_concerns_to_complete is enabled)`,void 0)}else if(asVerdict!=="APPROVE")return asBlocked("ARCH_SUPERVISOR_INVALID",`Phase ${phase} cannot be completed: architecture supervisor evidence contains unrecognized verdict '${String(asVerdict)}'. Expected one of: APPROVE, CONCERNS, REJECT.`);return{blocked:!1,agentsDispatched,agentsMissing:[],warnings:gateWarnings}}async function runCompletionVerifyGate(ctx){let{phase,dir,agentsDispatched,safeWarn}=ctx;try{let completionResultRaw=await executeCompletionVerify({phase},dir),completionResult=JSON.parse(completionResultRaw);if(completionResult.status==="blocked")return{blocked:!0,reason:"COMPLETION_INCOMPLETE",message:`Phase ${phase} cannot be completed: ${completionResult.reason}`,agentsDispatched,agentsMissing:[],warnings:completionResult.blockedTasks?[`Blocked tasks: ${completionResult.blockedTasks.map((t)=>t.task_id).join(", ")}`]:[]};return{blocked:!1,agentsDispatched,agentsMissing:[],warnings:[]}}catch(completionError){return safeWarn("[phase_complete] Completion verify error (non-blocking):",completionError),{blocked:!1,agentsDispatched,agentsMissing:[],warnings:[]}}}init_effective_spec();import*as fs162 from"node:fs";import*as path275 from"node:path";init_qa_gate_profile();init_ledger();init_manager();init_utils3();init_state2();async function resolveGatePreamble(dir,sessionID){let plan=await loadPlan(dir);if(!plan)return{resolved:!1};let planId=derivePlanId(plan),planHash=computePlanHash(plan),lookup=getProfileLookupForIdentity(dir,plan),overrides=(sessionID?swarmState.agentSessions.get(sessionID):void 0)?.qaGateSessionOverrides??{};if(lookup.kind==="missing"){let hasOverrides=Object.keys(overrides).length>0;return{resolved:hasOverrides,plan,planId,planHash,effectiveGates:hasOverrides?{...DEFAULT_QA_GATES,...overrides}:void 0,identityBound:!0}}let profile=lookup.profile,effective=getEffectiveGates(profile,overrides);return{resolved:!0,plan,planId,planHash,effectiveGates:effective,identityBound:lookup.kind==="bound"}}async function runDriftGate(ctx){let{phase,dir,sessionID,agentsDispatched,safeWarn}=ctx,gateWarnings=[],driftCheckEnabled=!0,driftHasEffectiveSpec=!1;try{driftHasEffectiveSpec=readEffectiveSpecSync(dir)!==null;let preamble=await resolveGatePreamble(dir,sessionID);if(preamble.resolved){if(preamble.identityBound===!1&&preamble.effectiveGates?.drift_check===!0)return{blocked:!0,reason:"DRIFT_VERIFICATION_IDENTITY_UNBOUND",message:`Phase ${phase} cannot be completed: drift_check is enabled but the QA gate profile is not exact-bound to the current raw swarm_id/plan_title. ${formatLegacyQaBindingRecovery({swarm:preamble.plan.swarm,title:preamble.plan.title},"retry completing the phase")}`,agentsDispatched,agentsMissing:[],warnings:[]};driftCheckEnabled=preamble.effectiveGates?.drift_check===!0}}catch(gateLoadError){safeWarn("[phase_complete] QA gate profile load error, drift_check defaults to enabled:",gateLoadError)}if(!driftCheckEnabled)return{blocked:!1,agentsDispatched,agentsMissing:[],warnings:[`drift_check gate is disabled. Drift verification was skipped for phase ${phase}.`]};let phaseType;try{let planPath=path275.join(dir,".swarm","plan.json");if(fs162.existsSync(planPath)){let planRaw=fs162.readFileSync(planPath,"utf-8");phaseType=JSON.parse(planRaw).phases?.find((p)=>p.id===phase)?.type}}catch{}if(phaseType==="non-code")return{blocked:!1,agentsDispatched,agentsMissing:[],warnings:[`Phase ${phase} is annotated as 'non-code'. Drift verification was skipped per phase type annotation.`]};try{let driftEvidencePath=path275.join(dir,".swarm","evidence",String(phase),"drift-verifier.json"),driftVerdictFound=!1,driftVerdictApproved=!1;try{let driftEvidenceContent=fs162.readFileSync(driftEvidencePath,"utf-8"),entries=JSON.parse(driftEvidenceContent).entries??[];for(let entry of entries)if(typeof entry.type==="string"&&entry.type.includes("drift")&&typeof entry.verdict==="string"){if(driftVerdictFound=!0,!entry.provenance||!entry.provenance.agent_name&&!entry.provenance.session_id){let msg=`Drift verification evidence lacks provenance for phase ${phase}. Evidence should include agent_name or session_id for verification.`;gateWarnings.push(msg),safeWarn(`[phase_complete] ${msg}`,void 0)}if(entry.verdict==="approved")driftVerdictApproved=!0;if(entry.verdict==="rejected"||typeof entry.summary==="string"&&entry.summary.includes("NEEDS_REVISION"))return{blocked:!0,reason:"DRIFT_VERIFICATION_REJECTED",message:`Phase ${phase} cannot be completed: drift verifier returned verdict '${entry.verdict}'. Address the drift issues before completing the phase.`,agentsDispatched,agentsMissing:[],warnings:[]}}}catch(readError){if(readError.code!=="ENOENT")safeWarn("[phase_complete] Drift verifier evidence unreadable:",readError);driftVerdictFound=!1}if(!driftVerdictFound)if(!driftHasEffectiveSpec){let incompleteTaskCount=0,planParseable=!1;try{let planPath=path275.join(dir,".swarm","plan.json");if(fs162.existsSync(planPath)){let planRaw=fs162.readFileSync(planPath,"utf-8"),plan=JSON.parse(planRaw);planParseable=!0;let planPhase=plan.phases?.find((p)=>p.id===phase);if(planPhase?.tasks)incompleteTaskCount=planPhase.tasks.filter((t)=>t.status!=="completed"&&t.status!=="closed").length}}catch{}if(!planParseable)return{blocked:!1,agentsDispatched,agentsMissing:[],warnings:["No effective spec found and drift verification evidence missing — consider running critic_drift_verifier before phase completion."]};else if(incompleteTaskCount>0)return{blocked:!1,agentsDispatched,agentsMissing:[],warnings:[`No effective spec found and drift verification evidence missing. Phase ${phase} has ${incompleteTaskCount} incomplete task(s) in plan.json — consider running critic_drift_verifier before phase completion.`]};else return{blocked:!1,agentsDispatched,agentsMissing:[],warnings:[`No effective spec found. Phase ${phase} tasks are all completed in plan.json. Drift verification was skipped.`]}}else return{blocked:!0,reason:"DRIFT_VERIFICATION_MISSING",message:`Phase ${phase} cannot be completed: drift_check is enabled and drift verifier evidence not found at .swarm/evidence/${phase}/drift-verifier.json. Run drift verification before completing the phase.`,agentsDispatched,agentsMissing:[],warnings:[]};if(!driftVerdictApproved&&driftVerdictFound)return{blocked:!0,reason:"DRIFT_VERIFICATION_REJECTED",message:`Phase ${phase} cannot be completed: drift verifier verdict is not approved.`,agentsDispatched,agentsMissing:[],warnings:[]};return{blocked:!1,agentsDispatched,agentsMissing:[],warnings:gateWarnings}}catch(driftError){return{blocked:!0,reason:"DRIFT_VERIFICATION_ERROR",message:`Phase ${phase} cannot be completed: drift verification encountered an error: ${driftError instanceof Error?driftError.message:String(driftError)}. This is a hard block — resolve the error before completing the phase.`,agentsDispatched,agentsMissing:[],warnings:[]}}}init_qa_gate_profile();init_utils3();init_state2();import*as fs163 from"node:fs";import*as path276 from"node:path";function parseTimestampMs(value){if(typeof value!=="string")return null;let parsed=new Date(value).getTime();return Number.isNaN(parsed)?null:parsed}function latestRetroTimestampMsFromBundle(bundle,phase){if(!bundle)return null;let timestamps=[parseTimestampMs(bundle.created_at),parseTimestampMs(bundle.updated_at),...(bundle.entries??[]).filter((entry)=>entry.type==="retrospective"&&entry.phase_number===phase).map((entry)=>parseTimestampMs(entry.timestamp))].filter((timestamp)=>timestamp!==null);return timestamps.length>0?Math.max(...timestamps):null}function readLatestRetroTimestampMs(dir,phase){let baseDir=path276.normalize(path276.resolve(dir,".swarm")),retroPath=path276.normalize(path276.join(baseDir,"evidence",`retro-${phase}`,"evidence.json"));if(!(process.platform==="win32"?retroPath.toLowerCase().startsWith(baseDir.toLowerCase()+path276.sep)||retroPath.toLowerCase()===baseDir.toLowerCase():retroPath.startsWith(baseDir+path276.sep)||retroPath===baseDir))return null;try{let content=fs163.readFileSync(retroPath,"utf-8");return latestRetroTimestampMsFromBundle(JSON.parse(content),phase)}catch{return null}}function sessionHasEnabledFinalCouncil(sessionID){if(!sessionID)return!1;return swarmState.agentSessions.get(sessionID)?.qaGateSessionOverrides?.final_council===!0}async function runFinalCouncilGate(ctx){let{phase,dir,sessionID,agentsDispatched,safeWarn}=ctx,finalCouncilEnabled=!1,gateWarnings=[];try{let preamble=await resolveGatePreamble(dir,sessionID);if(!preamble.resolved||!preamble.plan){if(hasAnyProfileWithEnabledGate(dir,"final_council")||sessionHasEnabledFinalCouncil(sessionID))return{blocked:!0,reason:"FINAL_COUNCIL_PLAN_REQUIRED",message:`Phase ${phase} cannot be completed: final_council is enabled but plan.json is missing or invalid, so the final council gate cannot verify the current plan identity. Restore a valid .swarm/plan.json and re-run the final council.`,agentsDispatched,agentsMissing:[],warnings:[]};let warning="Final council gate: plan.json is missing and no enabled final_council profile was found. If final_council is required, the gate cannot be verified.";return gateWarnings.push(warning),safeWarn(`[phase_complete] ${warning}`,void 0),{blocked:!1,agentsDispatched,agentsMissing:[],warnings:[warning]}}if(preamble.resolved&&preamble.plan){let lastPhaseId=preamble.plan.phases[preamble.plan.phases.length-1]?.id;if(lastPhaseId!==void 0&&phase===lastPhaseId){if(preamble.effectiveGates?.final_council===!0){if(preamble.identityBound===!1)return{blocked:!0,reason:"FINAL_COUNCIL_IDENTITY_UNBOUND",message:`Phase ${phase} (last phase) cannot be completed: final_council is enabled but the QA gate profile is not exact-bound to the current raw swarm_id/plan_title. ${formatLegacyQaBindingRecovery({swarm:preamble.plan.swarm,title:preamble.plan.title},"retry completing the project")}`,agentsDispatched,agentsMissing:[],warnings:[]};finalCouncilEnabled=!0;let fcPath=path276.join(dir,".swarm","evidence","final-council.json"),fcVerdictFound=!1,_fcVerdict;try{let fcContent=fs163.readFileSync(fcPath,"utf-8"),fcBundle=JSON.parse(fcContent);for(let entry of fcBundle.entries??[])if(typeof entry.type==="string"&&entry.type==="final-council"&&typeof entry.verdict==="string"){fcVerdictFound=!0,_fcVerdict=entry.verdict;let now2=new Date,fcTimeMs=parseTimestampMs(entry.timestamp);if(fcTimeMs===null)return{blocked:!0,reason:"FINAL_COUNCIL_TIMESTAMP_REQUIRED",message:`Phase ${phase} cannot be completed: final council evidence is missing a valid timestamp. Re-run the final council to generate fresh evidence.`,agentsDispatched,agentsMissing:[],warnings:[]};if(fcTimeMs>now2.getTime())return{blocked:!0,reason:"FINAL_COUNCIL_FUTURE_TIMESTAMP",message:`Phase ${phase} cannot be completed: final council evidence timestamp is in the future.`,agentsDispatched,agentsMissing:[],warnings:[]};if(now2.getTime()-fcTimeMs>86400000)return{blocked:!0,reason:"FINAL_COUNCIL_STALE_EVIDENCE",message:`Phase ${phase} cannot be completed: final council evidence is older than 24 hours. Re-run the final council for fresh review.`,agentsDispatched,agentsMissing:[],warnings:[]};let latestRetroTimestampMs=latestRetroTimestampMsFromBundle(ctx.loadedRetroBundle,phase)??readLatestRetroTimestampMs(dir,phase);if(latestRetroTimestampMs!==null&&fcTimeMs<latestRetroTimestampMs)return{blocked:!0,reason:"FINAL_COUNCIL_STALE_EVIDENCE",message:`Phase ${phase} cannot be completed: final council evidence predates the current phase retrospective. Re-run the final council after the latest project evidence is available.`,agentsDispatched,agentsMissing:[],warnings:[]};if(preamble.plan){let currentPlanId=preamble.planId;if(entry.plan_id&&entry.plan_id!==currentPlanId)return{blocked:!0,reason:"final_council_plan_mismatch",message:`Final council evidence belongs to a different plan (evidence: ${entry.plan_id}, current: ${currentPlanId}). Re-run the final council.`,agentsDispatched,agentsMissing:[],warnings:[]};if(!entry.plan_id)return{blocked:!0,reason:"FINAL_COUNCIL_PLAN_ID_REQUIRED",message:`Phase ${phase} (last phase) cannot be completed: final council evidence is missing plan_id binding. Re-run the final council to generate evidence with plan identity.`,agentsDispatched,agentsMissing:[],warnings:[]};if(entry.plan_hash!==preamble.planHash)return{blocked:!0,reason:entry.plan_hash?"FINAL_COUNCIL_STALE_PLAN":"FINAL_COUNCIL_PLAN_HASH_REQUIRED",message:entry.plan_hash?`Phase ${phase} cannot be completed: final council evidence was produced for an older plan hash. Re-run the final council for the current plan.`:`Phase ${phase} cannot be completed: final council evidence is missing plan_hash binding. Re-run the final council to generate evidence tied to the current plan content.`,agentsDispatched,agentsMissing:[],warnings:[]};let currentIdentityHash=derivePlanIdentityHash(preamble.plan);if(entry.plan_identity_hash!==currentIdentityHash)return{blocked:!0,reason:entry.plan_identity_hash?"FINAL_COUNCIL_PLAN_IDENTITY_MISMATCH":"FINAL_COUNCIL_PLAN_IDENTITY_REQUIRED",message:entry.plan_identity_hash?`Phase ${phase} cannot be completed: final council evidence belongs to a different raw plan identity. Re-run the final council.`:`Phase ${phase} cannot be completed: final council evidence is missing plan_identity_hash binding. Re-run the final council to generate collision-resistant plan identity evidence.`,agentsDispatched,agentsMissing:[],warnings:[]}}if(typeof entry.quorumSize!=="number"||!Number.isFinite(entry.quorumSize)||entry.quorumSize<5)return{blocked:!0,reason:"FINAL_COUNCIL_MISSING_QUORUM",message:`Phase ${phase} (last phase) cannot be completed: final council evidence is missing valid quorum metadata. Re-run the project-scoped five-member final council and call write_final_council_evidence to generate quorumed evidence.`,agentsDispatched,agentsMissing:[],warnings:[]};let requiredFinalCouncilMembers=["critic","reviewer","sme","test_engineer","explorer"],membersVoted=Array.isArray(entry.membersVoted)?entry.membersVoted.filter((member)=>typeof member==="string"):[],membersAbsent=Array.isArray(entry.membersAbsent)?entry.membersAbsent.filter((member)=>typeof member==="string"):[],distinctMembersVoted=new Set(membersVoted);if(!(requiredFinalCouncilMembers.every((member)=>distinctMembersVoted.has(member))&&distinctMembersVoted.size===requiredFinalCouncilMembers.length&&membersAbsent.length===0))return{blocked:!0,reason:"FINAL_COUNCIL_MISSING_QUORUM",message:`Phase ${phase} (last phase) cannot be completed: final council evidence does not prove all five required members voted. Re-run the project-scoped five-member final council and call write_final_council_evidence to generate complete evidence.`,agentsDispatched,agentsMissing:[],warnings:[]};if(entry.verdict==="rejected"||entry.verdict==="REJECTED")return{blocked:!0,reason:"FINAL_COUNCIL_REJECTED",message:`Phase ${phase} (last phase) cannot be completed: final council returned verdict 'REJECTED'. Address the required fixes before completing the project.`,agentsDispatched,agentsMissing:[],warnings:[]};if(entry.verdict==="concerns"||entry.verdict==="CONCERNS"){let advisoryNotes=Array.isArray(entry.advisoryNotes)?entry.advisoryNotes.filter((note)=>typeof note==="string"):[],warning=advisoryNotes.length>0?`Final council returned CONCERNS (non-blocking): ${advisoryNotes.join("; ")}`:"Final council returned CONCERNS (non-blocking).";gateWarnings.push(warning),safeWarn(`[phase_complete] ${warning}`,void 0)}if(entry.verdict!=="approved"&&entry.verdict!=="APPROVED"&&entry.verdict!=="concerns"&&entry.verdict!=="CONCERNS")return{blocked:!0,reason:"FINAL_COUNCIL_INVALID_VERDICT",message:`Phase ${phase} (last phase) cannot be completed: final council evidence contains unrecognized verdict '${entry.verdict}'. Expected one of: approved, concerns, rejected.`,agentsDispatched,agentsMissing:[],warnings:[]}}}catch(readErr){if(readErr.code!=="ENOENT")safeWarn("[phase_complete] Final council evidence unreadable:",readErr);fcVerdictFound=!1}if(!fcVerdictFound)return{blocked:!0,reason:"FINAL_COUNCIL_REQUIRED",final_council_required:!0,message:`Phase ${phase} (last phase) cannot be completed: final_council is enabled and final council evidence not found at .swarm/evidence/final-council.json. Dispatch critic, reviewer, sme, test_engineer, and explorer with project-scoped context, collect their CouncilMemberVerdict JSON, and call write_final_council_evidence before completing the project. Do not use convene_general_council for this gate.`,agentsDispatched,agentsMissing:[],warnings:["Final council required - dispatch the five project-scoped council members, then call write_final_council_evidence to persist quorumed evidence."]}}}}}catch(fcError){if(finalCouncilEnabled)return{blocked:!0,reason:"FINAL_COUNCIL_ERROR",message:`Phase ${phase} (last phase) cannot be completed: final council gate encountered an error. Error: ${String(fcError)}`,agentsDispatched,agentsMissing:[],warnings:[`FINAL_COUNCIL_ERROR: ${String(fcError)}`]};else safeWarn("[phase_complete] Final council gate error (non-blocking):",fcError)}return{blocked:!1,agentsDispatched,agentsMissing:[],warnings:gateWarnings}}init_schema();init_diff_source();init_evidence2();function pass(ctx,warnings=[]){return{blocked:!1,agentsDispatched:ctx.agentsDispatched,agentsMissing:[],warnings}}function block(ctx,reason,message){return{blocked:!0,reason,message,agentsDispatched:ctx.agentsDispatched,agentsMissing:[],warnings:[]}}function evidenceStatusMatchesScope(evidenceStatus,scopeStatus){return scopeStatus==="clean"?evidenceStatus==="clean":evidenceStatus==="completed"}async function runFinalReviewGate(ctx){let config3;try{config3=resolveAutoReviewConfig(ctx.pluginConfig.auto_review??{})}catch(error93){return block(ctx,"FINAL_REVIEW_CONFIG_INVALID",`Phase ${ctx.phase} cannot be completed: ${error93 instanceof Error?error93.message:String(error93)}`)}if(!config3.enabled||config3.final_review.mode!=="gate"||config3.trigger==="task_completion"||ctx.autoReviewTrigger===void 0)return pass(ctx);if(ctx.autoReviewBlocked)return block(ctx,"FINAL_REVIEW_CURRENT_RUN_BLOCKED",`Phase ${ctx.phase} cannot be completed: the current final review run blocked (${ctx.autoReviewBlockReason??"unknown reason"}).`);if(!ctx.autoReviewScopeHash)return block(ctx,"FINAL_REVIEW_REQUIRED",`Phase ${ctx.phase} cannot be completed: final auto-review gate is enabled but no current scope evidence was produced.`);let evidence2=readAutoReviewEvidenceForPhase(ctx.dir,ctx.phase);if(!evidence2)return block(ctx,"FINAL_REVIEW_EVIDENCE_MISSING",`Phase ${ctx.phase} cannot be completed: .swarm/evidence/${ctx.phase}/auto-review.json is missing or malformed.`);if(evidence2.scope.hash!==ctx.autoReviewScopeHash||evidence2.phase!==ctx.phase||evidence2.trigger!==ctx.autoReviewTrigger||ctx.autoReviewScopeComplete!==void 0&&evidence2.scope.completeness.complete!==ctx.autoReviewScopeComplete)return block(ctx,"FINAL_REVIEW_EVIDENCE_STALE",`Phase ${ctx.phase} cannot be completed: final review evidence does not match the current review scope.`);let currentScope=await _internals213.collectReviewDiff({directory:ctx.dir,maxBytes:config3.final_review.max_diff_bytes});if(currentScope.status==="error")return block(ctx,"FINAL_REVIEW_SCOPE_COLLECTION_FAILED",`Phase ${ctx.phase} cannot be completed: terminal final-review scope collection failed (${currentScope.reason}).`);if(currentScope.scopeHash!==ctx.autoReviewScopeHash||currentScope.scopeHash!==evidence2.scope.hash||currentScope.headSha!==evidence2.scope.head_sha||JSON.stringify(currentScope.selector)!==JSON.stringify(evidence2.scope.selector)||JSON.stringify(currentScope.completeness)!==JSON.stringify(evidence2.scope.completeness)||ctx.autoReviewScopeComplete!==void 0&&currentScope.completeness.complete!==ctx.autoReviewScopeComplete||!evidenceStatusMatchesScope(evidence2.review.status,currentScope.status))return block(ctx,"FINAL_REVIEW_EVIDENCE_STALE",`Phase ${ctx.phase} cannot be completed: repository scope changed after final review evidence was produced.`);if(evidence2.policy.mode!==config3.final_review.mode||evidence2.policy.min_confidence!==config3.min_confidence||evidence2.policy.structured_findings!==config3.structured_findings||evidence2.policy.validate_findings!==config3.validate_findings)return block(ctx,"FINAL_REVIEW_POLICY_STALE",`Phase ${ctx.phase} cannot be completed: final review evidence was produced under a different policy.`);let integrity=validateAutoReviewEvidenceIntegrity(ctx.dir,evidence2,{scopeHash:ctx.autoReviewScopeHash,phase:ctx.phase,trigger:ctx.autoReviewTrigger,policy:evidence2.policy,scopeContent:currentScope.canonicalText});if(!integrity.ok)return block(ctx,integrity.code==="receipt_missing"?"FINAL_REVIEW_RECEIPT_MISSING":"FINAL_REVIEW_EVIDENCE_INVALID",`Phase ${ctx.phase} cannot be completed: final review evidence integrity check failed (${integrity.reason}).`);if(evidence2.review.status==="error")return block(ctx,"FINAL_REVIEW_FAILED",`Phase ${ctx.phase} cannot be completed: final review dispatch or parsing failed.`);if(!evidence2.scope.completeness.complete)return block(ctx,"FINAL_REVIEW_SCOPE_INCOMPLETE",`Phase ${ctx.phase} cannot be completed: final review scope was truncated or incomplete.`);if(evidence2.review.status==="completed"&&evidence2.review.output_mode!=="structured")return block(ctx,"FINAL_REVIEW_STRUCTURED_EVIDENCE_REQUIRED",`Phase ${ctx.phase} cannot be completed: gate mode requires structured review evidence.`);if(!evidence2.validation_complete)return block(ctx,"FINAL_REVIEW_VALIDATION_INCOMPLETE",`Phase ${ctx.phase} cannot be completed: independent finding validation evidence is incomplete.`);let gateCandidates=evidence2.findings.filter((finding)=>finding.anchored&&(finding.effective_severity==="high"||finding.effective_severity==="critical"));if(gateCandidates.some((finding)=>!finding.validation||finding.validation.finding_id!==finding.finding_id))return block(ctx,"FINAL_REVIEW_VALIDATION_INCOMPLETE",`Phase ${ctx.phase} cannot be completed: gate-eligible findings lack exact-ID validation evidence.`);let confirmedIds=gateCandidates.filter((finding)=>finding.validation?.disposition==="CONFIRMED").map((finding)=>finding.finding_id).sort(),recordedBlockingIds=[...evidence2.blocking_finding_ids].sort();if(confirmedIds.length!==recordedBlockingIds.length||confirmedIds.some((id,index)=>id!==recordedBlockingIds[index]))return block(ctx,"FINAL_REVIEW_EVIDENCE_INVALID",`Phase ${ctx.phase} cannot be completed: blocking finding IDs do not match independently confirmed findings.`);if(evidence2.blocking_finding_ids.length>0)return block(ctx,"FINAL_REVIEW_CONFIRMED_FINDINGS",`Phase ${ctx.phase} cannot be completed: ${evidence2.blocking_finding_ids.length} anchored HIGH/CRITICAL finding(s) were independently CONFIRMED.`);return pass(ctx)}var _internals213={collectReviewDiff};import*as fs164 from"node:fs";import*as path277 from"node:path";async function runHallucinationGate(ctx){let{phase,dir,sessionID,agentsDispatched,safeWarn}=ctx;try{let preamble=await resolveGatePreamble(dir,sessionID);if(preamble.resolved&&preamble.effectiveGates?.hallucination_guard===!0){if(preamble.identityBound===!1)return{blocked:!0,reason:"HALLUCINATION_VERIFICATION_IDENTITY_UNBOUND",message:`Phase ${phase} cannot be completed: hallucination_guard is enabled but the QA gate profile is not exact-bound to the current raw swarm_id/plan_title. ${formatLegacyQaBindingRecovery({swarm:preamble.plan.swarm,title:preamble.plan.title},"retry completing the phase")}`,agentsDispatched,agentsMissing:[],warnings:[]};let hgPath=path277.join(dir,".swarm","evidence",String(phase),"hallucination-guard.json"),hgVerdictFound=!1,hgVerdictApproved=!1;try{let hgContent=fs164.readFileSync(hgPath,"utf-8"),hgBundle=JSON.parse(hgContent);for(let entry of hgBundle.entries??[])if(typeof entry.type==="string"&&entry.type.includes("hallucination")&&typeof entry.verdict==="string"){if(hgVerdictFound=!0,entry.verdict==="approved")hgVerdictApproved=!0;if(entry.verdict==="rejected"||typeof entry.summary==="string"&&entry.summary.includes("NEEDS_REVISION"))return{blocked:!0,reason:"HALLUCINATION_VERIFICATION_REJECTED",message:`Phase ${phase} cannot be completed: hallucination verifier returned verdict '${entry.verdict}'. Remove fabricated APIs/signatures and fix broken citations before completing the phase.`,agentsDispatched,agentsMissing:[],warnings:[]}}}catch(readErr){if(readErr.code!=="ENOENT")safeWarn("[phase_complete] Hallucination guard evidence unreadable:",readErr);hgVerdictFound=!1}if(!hgVerdictFound)return{blocked:!0,reason:"HALLUCINATION_VERIFICATION_MISSING",message:`Phase ${phase} cannot be completed: hallucination_guard is enabled and evidence not found at .swarm/evidence/${phase}/hallucination-guard.json. Delegate to critic_hallucination_verifier and call write_hallucination_evidence before completing the phase.`,agentsDispatched,agentsMissing:[],warnings:[]};if(!hgVerdictApproved)return{blocked:!0,reason:"HALLUCINATION_VERIFICATION_REJECTED",message:`Phase ${phase} cannot be completed: hallucination verifier verdict is not approved.`,agentsDispatched,agentsMissing:[],warnings:[]}}}catch(hgError){safeWarn("[phase_complete] Hallucination guard error (non-blocking):",hgError)}return{blocked:!1,agentsDispatched,agentsMissing:[],warnings:[]}}import*as fs165 from"node:fs";import*as path278 from"node:path";async function runMutationGate(ctx){let{phase,dir,sessionID,agentsDispatched,safeWarn}=ctx;try{let preamble=await resolveGatePreamble(dir,sessionID);if(preamble.resolved&&preamble.effectiveGates?.mutation_test===!0){if(preamble.identityBound===!1)return{blocked:!0,reason:"MUTATION_GATE_IDENTITY_UNBOUND",message:`Phase ${phase} cannot be completed: mutation_test is enabled but the QA gate profile is not exact-bound to the current raw swarm_id/plan_title. ${formatLegacyQaBindingRecovery({swarm:preamble.plan.swarm,title:preamble.plan.title},"retry completing the phase")}`,agentsDispatched,agentsMissing:[],warnings:[]};let mgPath=path278.join(dir,".swarm","evidence",String(phase),"mutation-gate.json"),mgVerdictFound=!1,mgVerdict;try{let mgContent=fs165.readFileSync(mgPath,"utf-8"),mgBundle=JSON.parse(mgContent);for(let entry of mgBundle.entries??[])if(typeof entry.type==="string"&&entry.type==="mutation-gate"&&typeof entry.verdict==="string"){if(mgVerdictFound=!0,mgVerdict=entry.verdict,entry.verdict==="fail")return{blocked:!0,reason:"MUTATION_GATE_FAIL",message:`Phase ${phase} cannot be completed: mutation gate returned verdict 'fail'. Resolve surviving mutants or lower the kill-rate threshold before completing the phase.`,agentsDispatched,agentsMissing:[],warnings:[]};else if(!["pass","warn","skip"].includes(entry.verdict))return{blocked:!0,reason:"MUTATION_GATE_FAIL",message:`Phase ${phase} cannot be completed: mutation gate evidence contains unrecognized verdict '${entry.verdict}'. Expected one of: pass, warn, fail, skip.`,agentsDispatched,agentsMissing:[],warnings:[]}}}catch(readErr){if(readErr.code!=="ENOENT")safeWarn("[phase_complete] Mutation gate evidence unreadable:",readErr);mgVerdictFound=!1}if(!mgVerdictFound)return{blocked:!0,reason:"MUTATION_GATE_MISSING",message:`Phase ${phase} cannot be completed: mutation_test is enabled and evidence not found at .swarm/evidence/${phase}/mutation-gate.json. Run mutation_test, then call write_mutation_evidence before completing the phase.`,agentsDispatched,agentsMissing:[],warnings:[]};if(mgVerdict==="warn")safeWarn(`[phase_complete] Mutation gate verdict is 'warn' for phase ${phase} — proceeding with warning`,void 0)}}catch(mgError){safeWarn("[phase_complete] Mutation gate error (non-blocking):",mgError)}return{blocked:!1,agentsDispatched,agentsMissing:[],warnings:[]}}import*as fs166 from"node:fs";import*as path279 from"node:path";async function runPhaseCouncilGate(ctx){let{phase,dir,sessionID,pluginConfig,agentsDispatched,safeWarn}=ctx,gateWarnings=[],councilModeEnabled=!1;try{let preamble=await resolveGatePreamble(dir,sessionID);if(preamble.resolved&&preamble.effectiveGates?.phase_council===!0&&pluginConfig.council?.enabled===!0){if(preamble.identityBound===!1)return{blocked:!0,reason:"PHASE_COUNCIL_IDENTITY_UNBOUND",message:`Phase ${phase} cannot be completed: phase_council is enabled but the QA gate profile is not exact-bound to the current raw swarm_id/plan_title. ${formatLegacyQaBindingRecovery({swarm:preamble.plan.swarm,title:preamble.plan.title},"retry completing the phase")}`,agentsDispatched,agentsMissing:[],warnings:[]};councilModeEnabled=!0;let pcPath=path279.join(dir,".swarm","evidence",String(phase),"phase-council.json"),pcVerdictFound=!1,_pcVerdict,pcQuorumSize,pcTimestamp,pcPhaseNumber;try{let pcContent=fs166.readFileSync(pcPath,"utf-8"),pcBundle=JSON.parse(pcContent);for(let entry of pcBundle.entries??[])if(typeof entry.type==="string"&&entry.type==="phase-council"&&typeof entry.verdict==="string"){pcVerdictFound=!0,_pcVerdict=entry.verdict,pcQuorumSize=typeof entry.quorumSize==="number"?entry.quorumSize:void 0,pcTimestamp=typeof entry.timestamp==="string"?entry.timestamp:void 0,pcPhaseNumber=typeof entry.phase_number==="number"?entry.phase_number:typeof entry.phase==="number"?entry.phase:void 0;let now2=new Date,pcTime=pcTimestamp?new Date(pcTimestamp):null;if(!pcTime||Number.isNaN(pcTime.getTime()))return{blocked:!0,reason:"PHASE_COUNCIL_INVALID_TIMESTAMP",message:`Phase ${phase} cannot be completed: phase council evidence has missing or invalid timestamp.`,agentsDispatched,agentsMissing:[],warnings:[]};let maxAge=86400000;if(pcTime.getTime()>now2.getTime())return{blocked:!0,reason:"PHASE_COUNCIL_FUTURE_TIMESTAMP",message:`Phase ${phase} cannot be completed: phase council evidence timestamp is in the future.`,agentsDispatched,agentsMissing:[],warnings:[]};if(now2.getTime()-pcTime.getTime()>maxAge)return{blocked:!0,reason:"PHASE_COUNCIL_STALE_EVIDENCE",message:`Phase ${phase} cannot be completed: phase council evidence is older than 24 hours. Re-convene council for fresh review.`,agentsDispatched,agentsMissing:[],warnings:[]};if(!entry.provenance||!entry.provenance.agent_name&&!entry.provenance.session_id){let msg=`Phase council evidence lacks provenance for phase ${phase}. Evidence should include agent_name or session_id for verification.`;gateWarnings.push(msg),safeWarn(`[phase_complete] ${msg}`,void 0)}if(entry.verdict==="REJECT"||entry.verdict==="reject"){let requiredFixes=entry.requiredFixes??entry.required_fixes??[],fixesDetail=Array.isArray(requiredFixes)&&requiredFixes.length>0?`
6588
+ Findings: ${details.join("; ")}`:""},asBlocked=(reason,message)=>({blocked:!0,reason,message,agentsDispatched,agentsMissing:[],warnings:[]}),asEntry=null;try{asEntry=readSupervisorReportRaw(dir,phase)}catch(asError){return asBlocked("ARCH_SUPERVISOR_ERROR",`Phase ${phase} cannot be completed: architecture supervisor gate encountered an error. Error: ${String(asError)}`)}if(!asEntry)return asBlocked("ARCH_SUPERVISOR_REQUIRED",`Phase ${phase} cannot be completed: architectural_supervision gate mode is enabled and no architecture supervisor evidence was found at .swarm/evidence/${phase}/architecture-supervisor.json. Dispatch critic_architecture_supervisor with the phase + agent summaries, then call write_architecture_supervisor_evidence.`);let now2=new Date,asTime=asEntry.timestamp?new Date(asEntry.timestamp):null;if(!asTime||Number.isNaN(asTime.getTime()))return asBlocked("ARCH_SUPERVISOR_INVALID_TIMESTAMP",`Phase ${phase} cannot be completed: architecture supervisor evidence has a missing or invalid timestamp.`);if(asTime.getTime()>now2.getTime())return asBlocked("ARCH_SUPERVISOR_FUTURE_TIMESTAMP",`Phase ${phase} cannot be completed: architecture supervisor evidence timestamp is in the future.`);if(now2.getTime()-asTime.getTime()>86400000)return asBlocked("ARCH_SUPERVISOR_STALE_EVIDENCE",`Phase ${phase} cannot be completed: architecture supervisor evidence is older than 24 hours. Re-run the supervisor for fresh review.`);if(typeof asEntry.phase_number!=="number"||asEntry.phase_number!==phase)return asBlocked("ARCH_SUPERVISOR_PHASE_MISMATCH",`Phase ${phase} cannot be completed: architecture supervisor evidence is for phase ${String(asEntry.phase_number)}, not phase ${phase}.`);let gateWarnings=[];if(asConfig?.provenance_verify===!0){let provenance=asEntry.provenance;if(!provenance||!provenance.agent_name&&!provenance.session_id)return asBlocked("ARCH_SUPERVISOR_MISSING_PROVENANCE",`Phase ${phase} cannot be completed: architecture supervisor evidence lacks provenance (agent_name or session_id). Evidence provenance verification is enabled.`)}else if(!asEntry.provenance||!asEntry.provenance.agent_name&&!asEntry.provenance.session_id){let msg=`Architecture supervisor evidence lacks provenance for phase ${phase}. Enable 'provenance_verify' in architectural_supervision config to enforce provenance verification.`;gateWarnings.push(msg),safeWarn(`[phase_complete] ${msg}`,void 0)}let asVerdict=asEntry.verdict;if(asVerdict==="REJECT")return asBlocked("ARCH_SUPERVISOR_REJECTED",`Phase ${phase} cannot be completed: architecture supervisor returned verdict 'REJECT'. Address the system-level findings before completing the phase.${summarizeFindings(asEntry.findings)}`);if(asVerdict==="CONCERNS"){if(asConfig?.allow_concerns_to_complete===!1)return asBlocked("ARCH_SUPERVISOR_CONCERNS",`Phase ${phase} cannot be completed: architecture supervisor returned verdict 'CONCERNS' and allow_concerns_to_complete is disabled.${summarizeFindings(asEntry.findings)}`);safeWarn(`[phase_complete] Architecture supervisor returned CONCERNS for phase ${phase} — proceeding (allow_concerns_to_complete is enabled)`,void 0)}else if(asVerdict!=="APPROVE")return asBlocked("ARCH_SUPERVISOR_INVALID",`Phase ${phase} cannot be completed: architecture supervisor evidence contains unrecognized verdict '${String(asVerdict)}'. Expected one of: APPROVE, CONCERNS, REJECT.`);return{blocked:!1,agentsDispatched,agentsMissing:[],warnings:gateWarnings}}async function runCompletionVerifyGate(ctx){let{phase,dir,agentsDispatched}=ctx;try{let completionResultRaw=await executeCompletionVerify({phase},dir),completionResult=JSON.parse(completionResultRaw);if(completionResult.status==="blocked")return{blocked:!0,reason:"COMPLETION_INCOMPLETE",message:`Phase ${phase} cannot be completed: ${completionResult.reason}`,agentsDispatched,agentsMissing:[],warnings:completionResult.blockedTasks?[`Blocked tasks: ${completionResult.blockedTasks.map((t)=>t.task_id).join(", ")}`]:[]};return{blocked:!1,agentsDispatched,agentsMissing:[],warnings:[]}}catch(completionError){return{blocked:!0,reason:"COMPLETION_VERIFY_ERROR",message:`Phase ${phase} cannot be completed: completion verify gate encountered an error. Error: ${String(completionError)}`,agentsDispatched,agentsMissing:[],warnings:[`COMPLETION_VERIFY_ERROR: ${String(completionError)}`]}}}init_effective_spec();import*as fs162 from"node:fs";import*as path275 from"node:path";init_qa_gate_profile();init_ledger();init_manager();init_utils3();init_state2();async function resolveGatePreamble(dir,sessionID){let plan=await loadPlan(dir);if(!plan)return{resolved:!1};let planId=derivePlanId(plan),planHash=computePlanHash(plan),lookup=getProfileLookupForIdentity(dir,plan),overrides=(sessionID?swarmState.agentSessions.get(sessionID):void 0)?.qaGateSessionOverrides??{};if(lookup.kind==="missing"){let hasOverrides=Object.keys(overrides).length>0;return{resolved:hasOverrides,plan,planId,planHash,effectiveGates:hasOverrides?{...DEFAULT_QA_GATES,...overrides}:void 0,identityBound:!0}}let profile=lookup.profile,effective=getEffectiveGates(profile,overrides);return{resolved:!0,plan,planId,planHash,effectiveGates:effective,identityBound:lookup.kind==="bound"}}async function runDriftGate(ctx){let{phase,dir,sessionID,agentsDispatched,safeWarn}=ctx,gateWarnings=[],driftCheckEnabled=!0,driftHasEffectiveSpec=!1;try{driftHasEffectiveSpec=readEffectiveSpecSync(dir)!==null;let preamble=await resolveGatePreamble(dir,sessionID);if(preamble.resolved){if(preamble.identityBound===!1&&preamble.effectiveGates?.drift_check===!0)return{blocked:!0,reason:"DRIFT_VERIFICATION_IDENTITY_UNBOUND",message:`Phase ${phase} cannot be completed: drift_check is enabled but the QA gate profile is not exact-bound to the current raw swarm_id/plan_title. ${formatLegacyQaBindingRecovery({swarm:preamble.plan.swarm,title:preamble.plan.title},"retry completing the phase")}`,agentsDispatched,agentsMissing:[],warnings:[]};driftCheckEnabled=preamble.effectiveGates?.drift_check===!0}}catch(gateLoadError){safeWarn("[phase_complete] QA gate profile load error, drift_check defaults to enabled:",gateLoadError)}if(!driftCheckEnabled)return{blocked:!1,agentsDispatched,agentsMissing:[],warnings:[`drift_check gate is disabled. Drift verification was skipped for phase ${phase}.`]};let phaseType;try{let planPath=path275.join(dir,".swarm","plan.json");if(fs162.existsSync(planPath)){let planRaw=fs162.readFileSync(planPath,"utf-8");phaseType=JSON.parse(planRaw).phases?.find((p)=>p.id===phase)?.type}}catch{}if(phaseType==="non-code")return{blocked:!1,agentsDispatched,agentsMissing:[],warnings:[`Phase ${phase} is annotated as 'non-code'. Drift verification was skipped per phase type annotation.`]};try{let driftEvidencePath=path275.join(dir,".swarm","evidence",String(phase),"drift-verifier.json"),driftVerdictFound=!1,driftVerdictApproved=!1;try{let driftEvidenceContent=fs162.readFileSync(driftEvidencePath,"utf-8"),entries=JSON.parse(driftEvidenceContent).entries??[];for(let entry of entries)if(typeof entry.type==="string"&&entry.type.includes("drift")&&typeof entry.verdict==="string"){if(driftVerdictFound=!0,!entry.provenance||!entry.provenance.agent_name&&!entry.provenance.session_id){let msg=`Drift verification evidence lacks provenance for phase ${phase}. Evidence should include agent_name or session_id for verification.`;gateWarnings.push(msg),safeWarn(`[phase_complete] ${msg}`,void 0)}if(entry.verdict==="approved")driftVerdictApproved=!0;if(entry.verdict==="rejected"||typeof entry.summary==="string"&&entry.summary.includes("NEEDS_REVISION"))return{blocked:!0,reason:"DRIFT_VERIFICATION_REJECTED",message:`Phase ${phase} cannot be completed: drift verifier returned verdict '${entry.verdict}'. Address the drift issues before completing the phase.`,agentsDispatched,agentsMissing:[],warnings:[]}}}catch(readError){if(readError.code!=="ENOENT")safeWarn("[phase_complete] Drift verifier evidence unreadable:",readError);driftVerdictFound=!1}if(!driftVerdictFound)if(!driftHasEffectiveSpec){let incompleteTaskCount=0,planParseable=!1;try{let planPath=path275.join(dir,".swarm","plan.json");if(fs162.existsSync(planPath)){let planRaw=fs162.readFileSync(planPath,"utf-8"),plan=JSON.parse(planRaw);planParseable=!0;let planPhase=plan.phases?.find((p)=>p.id===phase);if(planPhase?.tasks)incompleteTaskCount=planPhase.tasks.filter((t)=>t.status!=="completed"&&t.status!=="closed").length}}catch{}if(!planParseable)return{blocked:!1,agentsDispatched,agentsMissing:[],warnings:["No effective spec found and drift verification evidence missing — consider running critic_drift_verifier before phase completion."]};else if(incompleteTaskCount>0)return{blocked:!1,agentsDispatched,agentsMissing:[],warnings:[`No effective spec found and drift verification evidence missing. Phase ${phase} has ${incompleteTaskCount} incomplete task(s) in plan.json — consider running critic_drift_verifier before phase completion.`]};else return{blocked:!1,agentsDispatched,agentsMissing:[],warnings:[`No effective spec found. Phase ${phase} tasks are all completed in plan.json. Drift verification was skipped.`]}}else return{blocked:!0,reason:"DRIFT_VERIFICATION_MISSING",message:`Phase ${phase} cannot be completed: drift_check is enabled and drift verifier evidence not found at .swarm/evidence/${phase}/drift-verifier.json. Run drift verification before completing the phase.`,agentsDispatched,agentsMissing:[],warnings:[]};if(!driftVerdictApproved&&driftVerdictFound)return{blocked:!0,reason:"DRIFT_VERIFICATION_REJECTED",message:`Phase ${phase} cannot be completed: drift verifier verdict is not approved.`,agentsDispatched,agentsMissing:[],warnings:[]};return{blocked:!1,agentsDispatched,agentsMissing:[],warnings:gateWarnings}}catch(driftError){return{blocked:!0,reason:"DRIFT_VERIFICATION_ERROR",message:`Phase ${phase} cannot be completed: drift verification encountered an error: ${driftError instanceof Error?driftError.message:String(driftError)}. This is a hard block — resolve the error before completing the phase.`,agentsDispatched,agentsMissing:[],warnings:[]}}}init_qa_gate_profile();init_utils3();init_state2();import*as fs163 from"node:fs";import*as path276 from"node:path";function parseTimestampMs(value){if(typeof value!=="string")return null;let parsed=new Date(value).getTime();return Number.isNaN(parsed)?null:parsed}function latestRetroTimestampMsFromBundle(bundle,phase){if(!bundle)return null;let timestamps=[parseTimestampMs(bundle.created_at),parseTimestampMs(bundle.updated_at),...(bundle.entries??[]).filter((entry)=>entry.type==="retrospective"&&entry.phase_number===phase).map((entry)=>parseTimestampMs(entry.timestamp))].filter((timestamp)=>timestamp!==null);return timestamps.length>0?Math.max(...timestamps):null}function readLatestRetroTimestampMs(dir,phase){let baseDir=path276.normalize(path276.resolve(dir,".swarm")),retroPath=path276.normalize(path276.join(baseDir,"evidence",`retro-${phase}`,"evidence.json"));if(!(process.platform==="win32"?retroPath.toLowerCase().startsWith(baseDir.toLowerCase()+path276.sep)||retroPath.toLowerCase()===baseDir.toLowerCase():retroPath.startsWith(baseDir+path276.sep)||retroPath===baseDir))return null;try{let content=fs163.readFileSync(retroPath,"utf-8");return latestRetroTimestampMsFromBundle(JSON.parse(content),phase)}catch{return null}}function sessionHasEnabledFinalCouncil(sessionID){if(!sessionID)return!1;return swarmState.agentSessions.get(sessionID)?.qaGateSessionOverrides?.final_council===!0}async function runFinalCouncilGate(ctx){let{phase,dir,sessionID,agentsDispatched,safeWarn}=ctx,finalCouncilEnabled=!1,gateWarnings=[];try{let preamble=await resolveGatePreamble(dir,sessionID);if(!preamble.resolved||!preamble.plan){if(hasAnyProfileWithEnabledGate(dir,"final_council")||sessionHasEnabledFinalCouncil(sessionID))return{blocked:!0,reason:"FINAL_COUNCIL_PLAN_REQUIRED",message:`Phase ${phase} cannot be completed: final_council is enabled but plan.json is missing or invalid, so the final council gate cannot verify the current plan identity. Restore a valid .swarm/plan.json and re-run the final council.`,agentsDispatched,agentsMissing:[],warnings:[]};let warning="Final council gate: plan.json is missing and no enabled final_council profile was found. If final_council is required, the gate cannot be verified.";return gateWarnings.push(warning),safeWarn(`[phase_complete] ${warning}`,void 0),{blocked:!1,agentsDispatched,agentsMissing:[],warnings:[warning]}}if(preamble.resolved&&preamble.plan){let lastPhaseId=preamble.plan.phases[preamble.plan.phases.length-1]?.id;if(lastPhaseId!==void 0&&phase===lastPhaseId){if(preamble.effectiveGates?.final_council===!0){if(preamble.identityBound===!1)return{blocked:!0,reason:"FINAL_COUNCIL_IDENTITY_UNBOUND",message:`Phase ${phase} (last phase) cannot be completed: final_council is enabled but the QA gate profile is not exact-bound to the current raw swarm_id/plan_title. ${formatLegacyQaBindingRecovery({swarm:preamble.plan.swarm,title:preamble.plan.title},"retry completing the project")}`,agentsDispatched,agentsMissing:[],warnings:[]};finalCouncilEnabled=!0;let fcPath=path276.join(dir,".swarm","evidence","final-council.json"),fcVerdictFound=!1,_fcVerdict;try{let fcContent=fs163.readFileSync(fcPath,"utf-8"),fcBundle=JSON.parse(fcContent);for(let entry of fcBundle.entries??[])if(typeof entry.type==="string"&&entry.type==="final-council"&&typeof entry.verdict==="string"){fcVerdictFound=!0,_fcVerdict=entry.verdict;let now2=new Date,fcTimeMs=parseTimestampMs(entry.timestamp);if(fcTimeMs===null)return{blocked:!0,reason:"FINAL_COUNCIL_TIMESTAMP_REQUIRED",message:`Phase ${phase} cannot be completed: final council evidence is missing a valid timestamp. Re-run the final council to generate fresh evidence.`,agentsDispatched,agentsMissing:[],warnings:[]};if(fcTimeMs>now2.getTime())return{blocked:!0,reason:"FINAL_COUNCIL_FUTURE_TIMESTAMP",message:`Phase ${phase} cannot be completed: final council evidence timestamp is in the future.`,agentsDispatched,agentsMissing:[],warnings:[]};if(now2.getTime()-fcTimeMs>86400000)return{blocked:!0,reason:"FINAL_COUNCIL_STALE_EVIDENCE",message:`Phase ${phase} cannot be completed: final council evidence is older than 24 hours. Re-run the final council for fresh review.`,agentsDispatched,agentsMissing:[],warnings:[]};let latestRetroTimestampMs=latestRetroTimestampMsFromBundle(ctx.loadedRetroBundle,phase)??readLatestRetroTimestampMs(dir,phase);if(latestRetroTimestampMs!==null&&fcTimeMs<latestRetroTimestampMs)return{blocked:!0,reason:"FINAL_COUNCIL_STALE_EVIDENCE",message:`Phase ${phase} cannot be completed: final council evidence predates the current phase retrospective. Re-run the final council after the latest project evidence is available.`,agentsDispatched,agentsMissing:[],warnings:[]};if(preamble.plan){let currentPlanId=preamble.planId;if(entry.plan_id&&entry.plan_id!==currentPlanId)return{blocked:!0,reason:"final_council_plan_mismatch",message:`Final council evidence belongs to a different plan (evidence: ${entry.plan_id}, current: ${currentPlanId}). Re-run the final council.`,agentsDispatched,agentsMissing:[],warnings:[]};if(!entry.plan_id)return{blocked:!0,reason:"FINAL_COUNCIL_PLAN_ID_REQUIRED",message:`Phase ${phase} (last phase) cannot be completed: final council evidence is missing plan_id binding. Re-run the final council to generate evidence with plan identity.`,agentsDispatched,agentsMissing:[],warnings:[]};if(entry.plan_hash!==preamble.planHash)return{blocked:!0,reason:entry.plan_hash?"FINAL_COUNCIL_STALE_PLAN":"FINAL_COUNCIL_PLAN_HASH_REQUIRED",message:entry.plan_hash?`Phase ${phase} cannot be completed: final council evidence was produced for an older plan hash. Re-run the final council for the current plan.`:`Phase ${phase} cannot be completed: final council evidence is missing plan_hash binding. Re-run the final council to generate evidence tied to the current plan content.`,agentsDispatched,agentsMissing:[],warnings:[]};let currentIdentityHash=derivePlanIdentityHash(preamble.plan);if(entry.plan_identity_hash!==currentIdentityHash)return{blocked:!0,reason:entry.plan_identity_hash?"FINAL_COUNCIL_PLAN_IDENTITY_MISMATCH":"FINAL_COUNCIL_PLAN_IDENTITY_REQUIRED",message:entry.plan_identity_hash?`Phase ${phase} cannot be completed: final council evidence belongs to a different raw plan identity. Re-run the final council.`:`Phase ${phase} cannot be completed: final council evidence is missing plan_identity_hash binding. Re-run the final council to generate collision-resistant plan identity evidence.`,agentsDispatched,agentsMissing:[],warnings:[]}}if(typeof entry.quorumSize!=="number"||!Number.isFinite(entry.quorumSize)||entry.quorumSize<5)return{blocked:!0,reason:"FINAL_COUNCIL_MISSING_QUORUM",message:`Phase ${phase} (last phase) cannot be completed: final council evidence is missing valid quorum metadata. Re-run the project-scoped five-member final council and call write_final_council_evidence to generate quorumed evidence.`,agentsDispatched,agentsMissing:[],warnings:[]};let requiredFinalCouncilMembers=["critic","reviewer","sme","test_engineer","explorer"],membersVoted=Array.isArray(entry.membersVoted)?entry.membersVoted.filter((member)=>typeof member==="string"):[],membersAbsent=Array.isArray(entry.membersAbsent)?entry.membersAbsent.filter((member)=>typeof member==="string"):[],distinctMembersVoted=new Set(membersVoted);if(!(requiredFinalCouncilMembers.every((member)=>distinctMembersVoted.has(member))&&distinctMembersVoted.size===requiredFinalCouncilMembers.length&&membersAbsent.length===0))return{blocked:!0,reason:"FINAL_COUNCIL_MISSING_QUORUM",message:`Phase ${phase} (last phase) cannot be completed: final council evidence does not prove all five required members voted. Re-run the project-scoped five-member final council and call write_final_council_evidence to generate complete evidence.`,agentsDispatched,agentsMissing:[],warnings:[]};if(entry.verdict==="rejected"||entry.verdict==="REJECTED")return{blocked:!0,reason:"FINAL_COUNCIL_REJECTED",message:`Phase ${phase} (last phase) cannot be completed: final council returned verdict 'REJECTED'. Address the required fixes before completing the project.`,agentsDispatched,agentsMissing:[],warnings:[]};if(entry.verdict==="concerns"||entry.verdict==="CONCERNS"){let advisoryNotes=Array.isArray(entry.advisoryNotes)?entry.advisoryNotes.filter((note)=>typeof note==="string"):[],warning=advisoryNotes.length>0?`Final council returned CONCERNS (non-blocking): ${advisoryNotes.join("; ")}`:"Final council returned CONCERNS (non-blocking).";gateWarnings.push(warning),safeWarn(`[phase_complete] ${warning}`,void 0)}if(entry.verdict!=="approved"&&entry.verdict!=="APPROVED"&&entry.verdict!=="concerns"&&entry.verdict!=="CONCERNS")return{blocked:!0,reason:"FINAL_COUNCIL_INVALID_VERDICT",message:`Phase ${phase} (last phase) cannot be completed: final council evidence contains unrecognized verdict '${entry.verdict}'. Expected one of: approved, concerns, rejected.`,agentsDispatched,agentsMissing:[],warnings:[]}}}catch(readErr){if(readErr.code!=="ENOENT")safeWarn("[phase_complete] Final council evidence unreadable:",readErr);fcVerdictFound=!1}if(!fcVerdictFound)return{blocked:!0,reason:"FINAL_COUNCIL_REQUIRED",final_council_required:!0,message:`Phase ${phase} (last phase) cannot be completed: final_council is enabled and final council evidence not found at .swarm/evidence/final-council.json. Dispatch critic, reviewer, sme, test_engineer, and explorer with project-scoped context, collect their CouncilMemberVerdict JSON, and call write_final_council_evidence before completing the project. Do not use convene_general_council for this gate.`,agentsDispatched,agentsMissing:[],warnings:["Final council required - dispatch the five project-scoped council members, then call write_final_council_evidence to persist quorumed evidence."]}}}}}catch(fcError){if(finalCouncilEnabled)return{blocked:!0,reason:"FINAL_COUNCIL_ERROR",message:`Phase ${phase} (last phase) cannot be completed: final council gate encountered an error. Error: ${String(fcError)}`,agentsDispatched,agentsMissing:[],warnings:[`FINAL_COUNCIL_ERROR: ${String(fcError)}`]};else safeWarn("[phase_complete] Final council gate error (non-blocking):",fcError)}return{blocked:!1,agentsDispatched,agentsMissing:[],warnings:gateWarnings}}init_schema();init_diff_source();init_evidence2();function pass(ctx,warnings=[]){return{blocked:!1,agentsDispatched:ctx.agentsDispatched,agentsMissing:[],warnings}}function block(ctx,reason,message){return{blocked:!0,reason,message,agentsDispatched:ctx.agentsDispatched,agentsMissing:[],warnings:[]}}function evidenceStatusMatchesScope(evidenceStatus,scopeStatus){return scopeStatus==="clean"?evidenceStatus==="clean":evidenceStatus==="completed"}async function runFinalReviewGate(ctx){let config3;try{config3=resolveAutoReviewConfig(ctx.pluginConfig.auto_review??{})}catch(error93){return block(ctx,"FINAL_REVIEW_CONFIG_INVALID",`Phase ${ctx.phase} cannot be completed: ${error93 instanceof Error?error93.message:String(error93)}`)}if(!config3.enabled||config3.final_review.mode!=="gate"||config3.trigger==="task_completion"||ctx.autoReviewTrigger===void 0)return pass(ctx);if(ctx.autoReviewBlocked)return block(ctx,"FINAL_REVIEW_CURRENT_RUN_BLOCKED",`Phase ${ctx.phase} cannot be completed: the current final review run blocked (${ctx.autoReviewBlockReason??"unknown reason"}).`);if(!ctx.autoReviewScopeHash)return block(ctx,"FINAL_REVIEW_REQUIRED",`Phase ${ctx.phase} cannot be completed: final auto-review gate is enabled but no current scope evidence was produced.`);let evidence2=readAutoReviewEvidenceForPhase(ctx.dir,ctx.phase);if(!evidence2)return block(ctx,"FINAL_REVIEW_EVIDENCE_MISSING",`Phase ${ctx.phase} cannot be completed: .swarm/evidence/${ctx.phase}/auto-review.json is missing or malformed.`);if(evidence2.scope.hash!==ctx.autoReviewScopeHash||evidence2.phase!==ctx.phase||evidence2.trigger!==ctx.autoReviewTrigger||ctx.autoReviewScopeComplete!==void 0&&evidence2.scope.completeness.complete!==ctx.autoReviewScopeComplete)return block(ctx,"FINAL_REVIEW_EVIDENCE_STALE",`Phase ${ctx.phase} cannot be completed: final review evidence does not match the current review scope.`);let currentScope=await _internals213.collectReviewDiff({directory:ctx.dir,maxBytes:config3.final_review.max_diff_bytes});if(currentScope.status==="error")return block(ctx,"FINAL_REVIEW_SCOPE_COLLECTION_FAILED",`Phase ${ctx.phase} cannot be completed: terminal final-review scope collection failed (${currentScope.reason}).`);if(currentScope.scopeHash!==ctx.autoReviewScopeHash||currentScope.scopeHash!==evidence2.scope.hash||currentScope.headSha!==evidence2.scope.head_sha||JSON.stringify(currentScope.selector)!==JSON.stringify(evidence2.scope.selector)||JSON.stringify(currentScope.completeness)!==JSON.stringify(evidence2.scope.completeness)||ctx.autoReviewScopeComplete!==void 0&&currentScope.completeness.complete!==ctx.autoReviewScopeComplete||!evidenceStatusMatchesScope(evidence2.review.status,currentScope.status))return block(ctx,"FINAL_REVIEW_EVIDENCE_STALE",`Phase ${ctx.phase} cannot be completed: repository scope changed after final review evidence was produced.`);if(evidence2.policy.mode!==config3.final_review.mode||evidence2.policy.min_confidence!==config3.min_confidence||evidence2.policy.structured_findings!==config3.structured_findings||evidence2.policy.validate_findings!==config3.validate_findings)return block(ctx,"FINAL_REVIEW_POLICY_STALE",`Phase ${ctx.phase} cannot be completed: final review evidence was produced under a different policy.`);let integrity=validateAutoReviewEvidenceIntegrity(ctx.dir,evidence2,{scopeHash:ctx.autoReviewScopeHash,phase:ctx.phase,trigger:ctx.autoReviewTrigger,policy:evidence2.policy,scopeContent:currentScope.canonicalText});if(!integrity.ok)return block(ctx,integrity.code==="receipt_missing"?"FINAL_REVIEW_RECEIPT_MISSING":"FINAL_REVIEW_EVIDENCE_INVALID",`Phase ${ctx.phase} cannot be completed: final review evidence integrity check failed (${integrity.reason}).`);if(evidence2.review.status==="error")return block(ctx,"FINAL_REVIEW_FAILED",`Phase ${ctx.phase} cannot be completed: final review dispatch or parsing failed.`);if(!evidence2.scope.completeness.complete)return block(ctx,"FINAL_REVIEW_SCOPE_INCOMPLETE",`Phase ${ctx.phase} cannot be completed: final review scope was truncated or incomplete.`);if(evidence2.review.status==="completed"&&evidence2.review.output_mode!=="structured")return block(ctx,"FINAL_REVIEW_STRUCTURED_EVIDENCE_REQUIRED",`Phase ${ctx.phase} cannot be completed: gate mode requires structured review evidence.`);if(!evidence2.validation_complete)return block(ctx,"FINAL_REVIEW_VALIDATION_INCOMPLETE",`Phase ${ctx.phase} cannot be completed: independent finding validation evidence is incomplete.`);let gateCandidates=evidence2.findings.filter((finding)=>finding.anchored&&(finding.effective_severity==="high"||finding.effective_severity==="critical"));if(gateCandidates.some((finding)=>!finding.validation||finding.validation.finding_id!==finding.finding_id))return block(ctx,"FINAL_REVIEW_VALIDATION_INCOMPLETE",`Phase ${ctx.phase} cannot be completed: gate-eligible findings lack exact-ID validation evidence.`);let confirmedIds=gateCandidates.filter((finding)=>finding.validation?.disposition==="CONFIRMED").map((finding)=>finding.finding_id).sort(),recordedBlockingIds=[...evidence2.blocking_finding_ids].sort();if(confirmedIds.length!==recordedBlockingIds.length||confirmedIds.some((id,index)=>id!==recordedBlockingIds[index]))return block(ctx,"FINAL_REVIEW_EVIDENCE_INVALID",`Phase ${ctx.phase} cannot be completed: blocking finding IDs do not match independently confirmed findings.`);if(evidence2.blocking_finding_ids.length>0)return block(ctx,"FINAL_REVIEW_CONFIRMED_FINDINGS",`Phase ${ctx.phase} cannot be completed: ${evidence2.blocking_finding_ids.length} anchored HIGH/CRITICAL finding(s) were independently CONFIRMED.`);return pass(ctx)}var _internals213={collectReviewDiff};import*as fs164 from"node:fs";import*as path277 from"node:path";async function runHallucinationGate(ctx){let{phase,dir,sessionID,agentsDispatched,safeWarn}=ctx,hallucinationGateEnabled=!1;try{let preamble=await resolveGatePreamble(dir,sessionID);if(preamble.resolved&&preamble.effectiveGates?.hallucination_guard===!0){if(hallucinationGateEnabled=!0,preamble.identityBound===!1)return{blocked:!0,reason:"HALLUCINATION_VERIFICATION_IDENTITY_UNBOUND",message:`Phase ${phase} cannot be completed: hallucination_guard is enabled but the QA gate profile is not exact-bound to the current raw swarm_id/plan_title. ${formatLegacyQaBindingRecovery({swarm:preamble.plan.swarm,title:preamble.plan.title},"retry completing the phase")}`,agentsDispatched,agentsMissing:[],warnings:[]};let hgPath=path277.join(dir,".swarm","evidence",String(phase),"hallucination-guard.json"),hgVerdictFound=!1,hgVerdictApproved=!1;try{let hgContent=fs164.readFileSync(hgPath,"utf-8"),hgBundle=JSON.parse(hgContent);for(let entry of hgBundle.entries??[])if(typeof entry.type==="string"&&entry.type.includes("hallucination")&&typeof entry.verdict==="string"){if(hgVerdictFound=!0,entry.verdict==="approved")hgVerdictApproved=!0;if(entry.verdict==="rejected"||typeof entry.summary==="string"&&entry.summary.includes("NEEDS_REVISION"))return{blocked:!0,reason:"HALLUCINATION_VERIFICATION_REJECTED",message:`Phase ${phase} cannot be completed: hallucination verifier returned verdict '${entry.verdict}'. Remove fabricated APIs/signatures and fix broken citations before completing the phase.`,agentsDispatched,agentsMissing:[],warnings:[]}}}catch(readErr){if(readErr.code!=="ENOENT")safeWarn("[phase_complete] Hallucination guard evidence unreadable:",readErr);hgVerdictFound=!1}if(!hgVerdictFound)return{blocked:!0,reason:"HALLUCINATION_VERIFICATION_MISSING",message:`Phase ${phase} cannot be completed: hallucination_guard is enabled and evidence not found at .swarm/evidence/${phase}/hallucination-guard.json. Delegate to critic_hallucination_verifier and call write_hallucination_evidence before completing the phase.`,agentsDispatched,agentsMissing:[],warnings:[]};if(!hgVerdictApproved)return{blocked:!0,reason:"HALLUCINATION_VERIFICATION_REJECTED",message:`Phase ${phase} cannot be completed: hallucination verifier verdict is not approved.`,agentsDispatched,agentsMissing:[],warnings:[]}}}catch(hgError){if(hallucinationGateEnabled)return{blocked:!0,reason:"HALLUCINATION_GATE_ERROR",message:`Phase ${phase} cannot be completed: hallucination guard gate encountered an error when hallucination_guard was enabled. Error: ${String(hgError)}`,agentsDispatched,agentsMissing:[],warnings:[`HALLUCINATION_GATE_ERROR: ${String(hgError)}`]};else safeWarn("[phase_complete] Hallucination guard error (non-blocking):",hgError)}return{blocked:!1,agentsDispatched,agentsMissing:[],warnings:[]}}import*as fs165 from"node:fs";import*as path278 from"node:path";async function runMutationGate(ctx){let{phase,dir,sessionID,agentsDispatched,safeWarn}=ctx,mutationGateEnabled=!1;try{let preamble=await resolveGatePreamble(dir,sessionID);if(preamble.resolved&&preamble.effectiveGates?.mutation_test===!0){if(mutationGateEnabled=!0,preamble.identityBound===!1)return{blocked:!0,reason:"MUTATION_GATE_IDENTITY_UNBOUND",message:`Phase ${phase} cannot be completed: mutation_test is enabled but the QA gate profile is not exact-bound to the current raw swarm_id/plan_title. ${formatLegacyQaBindingRecovery({swarm:preamble.plan.swarm,title:preamble.plan.title},"retry completing the phase")}`,agentsDispatched,agentsMissing:[],warnings:[]};let mgPath=path278.join(dir,".swarm","evidence",String(phase),"mutation-gate.json"),mgVerdictFound=!1,mgVerdict;try{let mgContent=fs165.readFileSync(mgPath,"utf-8"),mgBundle=JSON.parse(mgContent);for(let entry of mgBundle.entries??[])if(typeof entry.type==="string"&&entry.type==="mutation-gate"&&typeof entry.verdict==="string"){if(mgVerdictFound=!0,mgVerdict=entry.verdict,entry.verdict==="fail")return{blocked:!0,reason:"MUTATION_GATE_FAIL",message:`Phase ${phase} cannot be completed: mutation gate returned verdict 'fail'. Resolve surviving mutants or lower the kill-rate threshold before completing the phase.`,agentsDispatched,agentsMissing:[],warnings:[]};else if(!["pass","warn","skip"].includes(entry.verdict))return{blocked:!0,reason:"MUTATION_GATE_FAIL",message:`Phase ${phase} cannot be completed: mutation gate evidence contains unrecognized verdict '${entry.verdict}'. Expected one of: pass, warn, fail, skip.`,agentsDispatched,agentsMissing:[],warnings:[]}}}catch(readErr){if(readErr.code!=="ENOENT")safeWarn("[phase_complete] Mutation gate evidence unreadable:",readErr);mgVerdictFound=!1}if(!mgVerdictFound)return{blocked:!0,reason:"MUTATION_GATE_MISSING",message:`Phase ${phase} cannot be completed: mutation_test is enabled and evidence not found at .swarm/evidence/${phase}/mutation-gate.json. Run mutation_test, then call write_mutation_evidence before completing the phase.`,agentsDispatched,agentsMissing:[],warnings:[]};if(mgVerdict==="warn")safeWarn(`[phase_complete] Mutation gate verdict is 'warn' for phase ${phase} — proceeding with warning`,void 0)}}catch(mgError){if(mutationGateEnabled)return{blocked:!0,reason:"MUTATION_GATE_ERROR",message:`Phase ${phase} cannot be completed: mutation gate encountered an error when mutation_test was enabled. Error: ${String(mgError)}`,agentsDispatched,agentsMissing:[],warnings:[`MUTATION_GATE_ERROR: ${String(mgError)}`]};else safeWarn("[phase_complete] Mutation gate error (non-blocking):",mgError)}return{blocked:!1,agentsDispatched,agentsMissing:[],warnings:[]}}import*as fs166 from"node:fs";import*as path279 from"node:path";async function runPhaseCouncilGate(ctx){let{phase,dir,sessionID,pluginConfig,agentsDispatched,safeWarn}=ctx,gateWarnings=[],councilModeEnabled=!1;try{let preamble=await resolveGatePreamble(dir,sessionID);if(preamble.resolved&&preamble.effectiveGates?.phase_council===!0&&pluginConfig.council?.enabled===!0){if(preamble.identityBound===!1)return{blocked:!0,reason:"PHASE_COUNCIL_IDENTITY_UNBOUND",message:`Phase ${phase} cannot be completed: phase_council is enabled but the QA gate profile is not exact-bound to the current raw swarm_id/plan_title. ${formatLegacyQaBindingRecovery({swarm:preamble.plan.swarm,title:preamble.plan.title},"retry completing the phase")}`,agentsDispatched,agentsMissing:[],warnings:[]};councilModeEnabled=!0;let pcPath=path279.join(dir,".swarm","evidence",String(phase),"phase-council.json"),pcVerdictFound=!1,_pcVerdict,pcQuorumSize,pcTimestamp,pcPhaseNumber;try{let pcContent=fs166.readFileSync(pcPath,"utf-8"),pcBundle=JSON.parse(pcContent);for(let entry of pcBundle.entries??[])if(typeof entry.type==="string"&&entry.type==="phase-council"&&typeof entry.verdict==="string"){pcVerdictFound=!0,_pcVerdict=entry.verdict,pcQuorumSize=typeof entry.quorumSize==="number"?entry.quorumSize:void 0,pcTimestamp=typeof entry.timestamp==="string"?entry.timestamp:void 0,pcPhaseNumber=typeof entry.phase_number==="number"?entry.phase_number:typeof entry.phase==="number"?entry.phase:void 0;let now2=new Date,pcTime=pcTimestamp?new Date(pcTimestamp):null;if(!pcTime||Number.isNaN(pcTime.getTime()))return{blocked:!0,reason:"PHASE_COUNCIL_INVALID_TIMESTAMP",message:`Phase ${phase} cannot be completed: phase council evidence has missing or invalid timestamp.`,agentsDispatched,agentsMissing:[],warnings:[]};let maxAge=86400000;if(pcTime.getTime()>now2.getTime())return{blocked:!0,reason:"PHASE_COUNCIL_FUTURE_TIMESTAMP",message:`Phase ${phase} cannot be completed: phase council evidence timestamp is in the future.`,agentsDispatched,agentsMissing:[],warnings:[]};if(now2.getTime()-pcTime.getTime()>maxAge)return{blocked:!0,reason:"PHASE_COUNCIL_STALE_EVIDENCE",message:`Phase ${phase} cannot be completed: phase council evidence is older than 24 hours. Re-convene council for fresh review.`,agentsDispatched,agentsMissing:[],warnings:[]};if(!entry.provenance||!entry.provenance.agent_name&&!entry.provenance.session_id){let msg=`Phase council evidence lacks provenance for phase ${phase}. Evidence should include agent_name or session_id for verification.`;gateWarnings.push(msg),safeWarn(`[phase_complete] ${msg}`,void 0)}if(entry.verdict==="REJECT"||entry.verdict==="reject"){let requiredFixes=entry.requiredFixes??entry.required_fixes??[],fixesDetail=Array.isArray(requiredFixes)&&requiredFixes.length>0?`
6582
6589
  Required fixes: ${requiredFixes.map((f)=>f.detail??JSON.stringify(f)).join("; ")}`:"";return{blocked:!0,reason:"PHASE_COUNCIL_REJECTED",message:`Phase ${phase} cannot be completed: phase council returned verdict 'REJECT'. Address the required fixes before completing the phase.${fixesDetail}`,agentsDispatched,agentsMissing:[],warnings:[]}}if(entry.verdict==="CONCERNS"||entry.verdict==="concerns"){if(!(pluginConfig.council?.phaseConcernsAllowComplete??!0)){let advisoryNotes=entry.advisoryNotes??entry.advisory_notes??[],notesDetail=Array.isArray(advisoryNotes)&&advisoryNotes.length>0?`
6583
6590
  Advisory notes: ${advisoryNotes.join("; ")}`:"";return{blocked:!0,reason:"PHASE_COUNCIL_CONCERNS",message:`Phase ${phase} cannot be completed: phase council returned verdict 'CONCERNS'.${notesDetail}`,agentsDispatched,agentsMissing:[],warnings:[]}}safeWarn(`[phase_complete] Phase council returned CONCERNS for phase ${phase} — proceeding (phaseConcernsAllowComplete is enabled)`,void 0)}if(entry.verdict!=="APPROVE"&&entry.verdict!=="approve"&&entry.verdict!=="CONCERNS"&&entry.verdict!=="concerns")return{blocked:!0,reason:"PHASE_COUNCIL_INVALID",message:`Phase ${phase} cannot be completed: phase council evidence contains unrecognized verdict '${entry.verdict}'. Expected one of: APPROVE, CONCERNS, REJECT.`,agentsDispatched,agentsMissing:[],warnings:[]}}}catch(readErr){if(readErr.code!=="ENOENT")safeWarn("[phase_complete] Phase council evidence unreadable:",readErr);pcVerdictFound=!1}if(!pcVerdictFound)return{blocked:!0,reason:"PHASE_COUNCIL_REQUIRED",phase_council_required:!0,message:`Phase ${phase} cannot be completed: phase_council is enabled and phase council evidence not found at .swarm/evidence/${phase}/phase-council.json. Convene a phase-level council (dispatch 5 members, collect verdicts, call submit_phase_council_verdicts) before completing the phase.`,agentsDispatched,agentsMissing:[],warnings:["Phase council required — convene 5 council members (critic, reviewer, sme, test_engineer, explorer) for holistic phase review. Call submit_phase_council_verdicts to synthesize verdicts and write phase-council.json evidence."]};if(pcQuorumSize===void 0||typeof pcQuorumSize!=="number")return{blocked:!0,reason:"PHASE_COUNCIL_MISSING_QUORUM",message:`Phase ${phase} cannot be completed: phase council evidence is missing quorumSize field.`,agentsDispatched,agentsMissing:[],warnings:[]};if(pcQuorumSize<3)return{blocked:!0,reason:"PHASE_COUNCIL_INSUFFICIENT_QUORUM",message:`Phase ${phase} cannot be completed: phase council quorum (${pcQuorumSize}) is below minimum (3). Re-convene council with sufficient members.`,agentsDispatched,agentsMissing:[],warnings:[]};if(pcPhaseNumber===void 0||typeof pcPhaseNumber!=="number")return{blocked:!0,reason:"PHASE_COUNCIL_MISSING_PHASE",message:`Phase ${phase} cannot be completed: phase council evidence is missing phase_number field.`,agentsDispatched,agentsMissing:[],warnings:[]};if(pcPhaseNumber!==phase)return{blocked:!0,reason:"PHASE_COUNCIL_PHASE_MISMATCH",message:`Phase ${phase} cannot be completed: phase council evidence is for phase ${pcPhaseNumber}, not phase ${phase}. Run council for the correct phase.`,agentsDispatched,agentsMissing:[],warnings:[]}}}catch(pcError){if(councilModeEnabled)return{blocked:!0,reason:"PHASE_COUNCIL_ERROR",message:`Phase ${phase} cannot be completed: phase council gate encountered an error when phase_council was enabled. Error: ${String(pcError)}`,agentsDispatched,agentsMissing:[],warnings:[`PHASE_COUNCIL_ERROR: ${String(pcError)}`]};else safeWarn("[phase_complete] Phase council gate error (non-blocking):",pcError)}return{blocked:!1,agentsDispatched,agentsMissing:[],warnings:gateWarnings}}init_resolve_working_directory();var phaseCompleteReceiptInternals={recordPhaseCloseIntent,commitPhaseClosed};function resolvePhaseReviewAgentNames(runtime){return runtime.generatedAgentNames??swarmState.generatedAgentNames}function buildMissingAgentRecoveryGuidance(input){if(input.missing.length===0)return;let steps=[`Dispatch the missing required role${input.missing.length===1?"":"s"} (${input.missing.join(", ")}) and retry phase_complete after each Task returns a successful, non-empty result.`];if(input.docsAddedByConfig&&input.missing.includes("docs"))steps.push("If this phase genuinely has no documentation obligation, set phase_complete.require_docs to false in opencode-swarm configuration; that setting is independent of the QA gate profile.");if(!input.docsPlanReadable&&input.missing.includes("docs"))steps.push("A readable plan is required to bind durable docs participation. Restore or rebuild .swarm/plan.json/.swarm/plan.md (or recover from .swarm/plan-export/) before re-dispatching docs, then retry phase_complete.");if(input.docsEvidenceStatus==="corrupt")steps.push("The readable docs-participation projection is corrupt; a genuine docs re-dispatch will quarantine the original bytes and rebuild it safely.");else if(input.docsEvidenceStatus==="unreadable"||input.docsEvidenceStatus==="oversized")steps.push("The docs-participation projection needs operator repair or archival before a re-dispatch can persist new proof.");if(input.missing.includes("docs")&&input.docsEvidenceStatus==="missing")steps.push("No prior durable docs-participation receipt was found (this can happen after a plugin upgrade or a cleared evidence store). A fresh docs Task dispatch writes a new durable completion receipt and is the canonical recovery path.");if(input.policy==="warn")steps.push("The configured warn policy allows closure with a warning, but it does not create participation proof.");else steps.push('Last resort: if the missing role obligation genuinely cannot be satisfied in this environment, set phase_complete.policy to "warn" in opencode-swarm configuration. This weakens enforcement for every missing role and does NOT create durable participation proof, so only use it when the obligation cannot be met.');return steps.join(" ")}function safeWarn(message,error93){try{warn(message,error93 instanceof Error?error93.message:String(error93))}catch{}}var MAX_OUTPUT_BYTES7=512000,TASK_GATE_INFERABLE_AGENTS=new Set(["coder","reviewer","test_engineer"]);function canInferMissingAgentsFromTaskGates(agentsMissing){return agentsMissing.every((agent)=>TASK_GATE_INFERABLE_AGENTS.has(agent))}async function allCompletedTasksHavePassedGateEvidence(directory,tasks){for(let task2 of tasks){if(task2.status!=="completed")return!1;if(!await hasPassedAllGates(directory,task2.id))return!1}return tasks.length>0}function collectCrossSessionDispatchedAgents(phaseReferenceTimestamp,callerSessionId){let agents=new Set,contributorSessionIds=[],callerSession=swarmState.agentSessions.get(callerSessionId);if(callerSession){if(contributorSessionIds.push(callerSessionId),callerSession.phaseAgentsDispatched)for(let agent of callerSession.phaseAgentsDispatched)agents.add(agent);for(let delegation of _getDelegationsSince(callerSessionId,phaseReferenceTimestamp))agents.add(stripKnownSwarmPrefix(delegation.from)),agents.add(stripKnownSwarmPrefix(delegation.to))}for(let[sessionId,session]of swarmState.agentSessions){if(sessionId===callerSessionId)continue;let hasRecentToolCalls=session.lastToolCallTime>=phaseReferenceTimestamp,hasRecentDelegations=swarmState.delegationChains.get(sessionId)?.some((d)=>d.timestamp>=phaseReferenceTimestamp)??!1,hasRestoredAgents=(session.phaseAgentsDispatched?.size??0)>0&&session.lastPhaseCompleteTimestamp===phaseReferenceTimestamp;if(hasRecentToolCalls||hasRecentDelegations||hasRestoredAgents){if(contributorSessionIds.push(sessionId),session.phaseAgentsDispatched)for(let agent of session.phaseAgentsDispatched)agents.add(agent);for(let delegation of _getDelegationsSince(sessionId,phaseReferenceTimestamp))agents.add(stripKnownSwarmPrefix(delegation.from)),agents.add(stripKnownSwarmPrefix(delegation.to))}}return{agents,contributorSessionIds}}async function fallbackWritePlanWithTrace(dir,planPath,candidate2,phase,warnings){let validation2=PlanSchema.safeParse(candidate2);if(!validation2.success){let detail=validation2.error.issues.slice(0,5).map((issue3)=>`${issue3.path.join(".")||"<root>"}: ${issue3.message}`).join("; ");return warn("[phase_complete] Last-resort plan.json write aborted — mutated plan failed PlanSchema validation:",detail),warnings.push(`Warning: last-resort plan.json write skipped — mutated plan failed schema validation (${detail})`),!1}await atomicWriteFile(planPath,JSON.stringify(validation2.data,null,2));try{let traceEvent={event:"phase_complete_fallback_write",phase,timestamp:new Date().toISOString()},eventsPath=validateSwarmPath(dir,"events.jsonl");fs168.appendFileSync(eventsPath,`${JSON.stringify(traceEvent)}
6584
6591
  `,"utf-8")}catch(eventError){warnings.push(`Warning: failed to record phase_complete_fallback_write trace event: ${eventError instanceof Error?eventError.message:String(eventError)}`)}return!0}function _getDelegationsSince(sessionID,sinceTimestamp){let chain=swarmState.delegationChains.get(sessionID);if(!chain)return[];if(sinceTimestamp===0)return chain;return chain.filter((entry)=>entry.timestamp>sinceTimestamp)}function isValidRetroEntry(entry,phase){return entry.type==="retrospective"&&"phase_number"in entry&&entry.phase_number===phase&&"verdict"in entry&&entry.verdict==="pass"}function blockedResult(phase,gateResult){let{reason,message,agentsDispatched,agentsMissing,warnings,blocked:_blocked,...extra}=gateResult;return JSON.stringify({success:!1,phase,status:"blocked",reason,message,agentsDispatched,agentsMissing,warnings,...extra},null,2)}async function executePhaseComplete(args2,workingDirectory,directory,runtime={}){let phase=Number(args2.phase),summary=args2.summary,sessionID=args2.sessionID;if(Number.isNaN(phase)||phase<1||!Number.isFinite(phase)||!Number.isInteger(phase))return JSON.stringify({success:!1,phase,status:"blocked",message:"Invalid phase number",agentsDispatched:[],warnings:["Phase must be a positive number"]},null,2);if(!sessionID)return JSON.stringify({success:!1,phase,message:"Session ID is required",agentsDispatched:[],warnings:["sessionID parameter is required for phase completion tracking"]},null,2);let phaseReferenceTimestamp=ensureAgentSession(sessionID).lastPhaseCompleteTimestamp??0,warnings=[],crossSessionResult=collectCrossSessionDispatchedAgents(phaseReferenceTimestamp,sessionID),agentsDispatched=Array.from(crossSessionResult.agents).sort(),dir=workingDirectory||directory,{config:config3}=loadPluginConfigWithMeta(dir),phaseCompleteConfig;try{phaseCompleteConfig=PhaseCompleteConfigSchema.parse(config3.phase_complete??{})}catch(parseError){return JSON.stringify({success:!1,phase,status:"incomplete",message:`Invalid phase_complete configuration: ${parseError instanceof Error?parseError.message:"Unknown error"}`,agentsDispatched,agentsMissing:[],warnings:["Configuration validation failed"]},null,2)}if(phaseCompleteConfig.enabled===!1)return JSON.stringify({success:!0,phase,status:"disabled",message:`Phase ${phase} complete (enforcement disabled)`,agentsDispatched,agentsMissing:[],warnings:[]},null,2);let receiptPlan=await loadPlan(dir).catch(()=>null),receiptPhaseLabel=receiptPlan?extractCurrentPhaseFromPlan(receiptPlan)??`Phase ${receiptPlan.current_phase??phase}`:`Phase ${phase}`,knowledgeEnabled=config3.knowledge?.enabled!==!1;if(knowledgeEnabled){let requestedAccept=Array.isArray(args2.acceptViolations)?args2.acceptViolations.filter((s)=>typeof s==="string"&&s.length>0):[],justification=typeof args2.acceptViolationsJustification==="string"?args2.acceptViolationsJustification.trim():"",callerAgent=args2.callerAgent??swarmState.activeAgent.get(sessionID)??"architect",isArchitect=stripKnownSwarmPrefix(callerAgent).toLowerCase()==="architect";if(requestedAccept.length>0&&!isArchitect)return blockedResult(phase,{reason:"override_denied_non_architect",message:"accept_violations is architect-only — this caller may not override critical directive violations.",agentsDispatched,agentsMissing:[],warnings});if(requestedAccept.length>0&&justification.length<10)return blockedResult(phase,{reason:"override_requires_justification",message:"accept_violations requires accept_violations_justification (minimum 10 characters of substantive reasoning).",agentsDispatched,agentsMissing:[],warnings});let effectiveAccept=requestedAccept.length>0&&isArchitect&&justification.length>=10?requestedAccept:[];if(effectiveAccept.length>0)try{await recordDirectiveOverrides(dir,effectiveAccept,justification,sessionID,receiptPhaseLabel)}catch{return blockedResult(phase,{reason:"directive_gate_failed_closed",message:"Critical-directive override could not be committed to authoritative receipt state; failing closed.",agentsDispatched,agentsMissing:[],warnings})}let directiveGate=await evaluatePhaseCriticalDirectives({directory:dir,sessionId:sessionID,phaseLabel:receiptPhaseLabel});if(directiveGate.blocked)return blockedResult(phase,{reason:directiveGate.failedClosed?"directive_gate_failed_closed":"unresolved_critical_directives",message:directiveGate.failedClosed?"Critical-directive gate could not read authoritative receipt state; failing closed.":formatDirectiveBlockMessage(directiveGate.unresolved),agentsDispatched,agentsMissing:[],warnings,unresolved_directives:directiveGate.unresolved})}let retroResult=await loadEvidence(dir,`retro-${phase}`),retroFound=!1,retroEntry=null,invalidSchemaErrors=[],loadedRetroTaskId=null,loadedRetroBundle=null,primaryRetroTaskId=`retro-${phase}`;if(retroResult.status==="found"){let validEntry=retroResult.bundle.entries?.find((entry)=>isValidRetroEntry(entry,phase));if(validEntry)retroFound=!0,retroEntry=validEntry,loadedRetroTaskId=primaryRetroTaskId,loadedRetroBundle=retroResult.bundle}else if(retroResult.status==="invalid_schema")invalidSchemaErrors=retroResult.errors;if(!retroFound){let retroTaskIds=(await listEvidenceTaskIds(dir)).filter((id)=>id.startsWith("retro-")&&/^retro-\d+$/.test(id));for(let taskId of retroTaskIds){let bundleResult=await loadEvidence(dir,taskId);if(bundleResult.status!=="found"){if(bundleResult.status==="invalid_schema")invalidSchemaErrors.push(...bundleResult.errors);continue}let validEntry=bundleResult.bundle.entries?.find((entry)=>isValidRetroEntry(entry,phase));if(validEntry){retroFound=!0,retroEntry=validEntry,loadedRetroTaskId=taskId,loadedRetroBundle=bundleResult.bundle;break}}}if(!retroFound){let schemaErrorDetail=invalidSchemaErrors.length>0?` Schema validation failed: ${invalidSchemaErrors.join("; ")}.`:"";return JSON.stringify({success:!1,phase,status:"blocked",reason:"RETROSPECTIVE_MISSING",message:`Phase ${phase} cannot be completed: no valid retrospective evidence found.${schemaErrorDetail} Write a retrospective bundle at .swarm/evidence/retro-${phase}/evidence.json before calling phase_complete.`,agentsDispatched,agentsMissing:[],warnings:[`Retrospective missing for phase ${phase}.${schemaErrorDetail} Use this template:`,JSON.stringify({schema_version:"1.0.0",task_id:`retro-${phase}`,created_at:new Date().toISOString(),updated_at:new Date().toISOString(),entries:[{task_id:`retro-${phase}`,type:"retrospective",timestamp:new Date().toISOString(),agent:"architect",verdict:"pass",summary:`Phase ${phase} completed.`,phase_number:phase,total_tool_calls:0,coder_revisions:0,reviewer_rejections:0,test_failures:0,security_findings:0,integration_issues:0,task_count:1,task_complexity:"simple",top_rejection_reasons:[],lessons_learned:[]}]},null,2)]},null,2)}let gateCtx={phase,dir,sessionID,pluginConfig:config3,agentsDispatched,safeWarn,loadedRetroBundle,loadedRetroTaskId};if(hasActiveTurboMode(sessionID))warnings.push(`Turbo mode active — skipped completion-verify, drift-verifier, hallucination-guard, mutation-gate, and phase-council gates for phase ${phase}.`);else{{let gateResult2=await runCompletionVerifyGate(gateCtx);if(gateResult2.blocked)return blockedResult(phase,gateResult2);warnings.push(...gateResult2.warnings)}{let gateResult2=await runDriftGate(gateCtx);if(gateResult2.blocked)return blockedResult(phase,gateResult2);warnings.push(...gateResult2.warnings)}{let gateResult2=await runHallucinationGate(gateCtx);if(gateResult2.blocked)return blockedResult(phase,gateResult2);warnings.push(...gateResult2.warnings)}{let gateResult2=await runMutationGate(gateCtx);if(gateResult2.blocked)return blockedResult(phase,gateResult2);warnings.push(...gateResult2.warnings)}{let gateResult2=await runPhaseCouncilGate(gateCtx);if(gateResult2.blocked)return blockedResult(phase,gateResult2);warnings.push(...gateResult2.warnings)}}if(config3.architectural_supervision?.enabled&&config3.architectural_supervision.mode==="gate"){let gateResult2=await runArchitectureSupervisorGate(gateCtx);if(gateResult2.blocked)return blockedResult(phase,gateResult2);warnings.push(...gateResult2.warnings)}try{let autoReviewConfig=resolveAutoReviewConfig(config3.auto_review??{});if(mayRunPhaseAutoReview(autoReviewConfig)){let phaseIds=(await loadPlan(dir).catch(()=>null))?.phases?.map((item)=>Number(item.id)).filter((id)=>Number.isInteger(id)&&id>0)??[],phaseReview=await runPhaseAutoReview({directory:dir,sessionID,phase,isFinalPlanPhase:phaseIds.length>0&&phase===Math.max(...phaseIds),activeLeanTurbo:hasActiveLeanTurbo(sessionID),config:autoReviewConfig,dispatcher:runtime.reviewModelDispatcher,generatedAgentNames:resolvePhaseReviewAgentNames(runtime),activeAgentName:args2.callerAgent??runtime.getActiveAgentName?.(sessionID),agentModelRegistry:runtime.reviewAgentModelRegistry,injectAdvisory:(_targetSessionID,advisory)=>{let sessionState=swarmState.agentSessions.get(sessionID);if(!sessionState)return;pushAdvisory(sessionState,advisory)}});gateCtx.autoReviewTrigger=phaseReview.trigger,gateCtx.autoReviewScopeHash=phaseReview.scopeHash,gateCtx.autoReviewScopeComplete=phaseReview.scopeComplete,gateCtx.autoReviewBlocked=phaseReview.blocked,gateCtx.autoReviewBlockReason=phaseReview.blockReason,warnings.push(...phaseReview.warnings)}}catch(error93){gateCtx.autoReviewTrigger="phase_completion",gateCtx.autoReviewBlocked=!0,gateCtx.autoReviewBlockReason="REVIEW_DISPATCH_FAILED",warnings.push(`Auto-review configuration or dispatch failed: ${error93 instanceof Error?error93.message:String(error93)}`)}{let reviewGateResult=await runFinalReviewGate(gateCtx);if(reviewGateResult.blocked)return blockedResult(phase,reviewGateResult);warnings.push(...reviewGateResult.warnings)}let gateResult=await runFinalCouncilGate(gateCtx);if(gateResult.blocked)return blockedResult(phase,gateResult);warnings.push(...gateResult.warnings);{let approval=verifyFullAutoPhaseApproval(dir,sessionID,phase,config3);if(!approval.ok)return JSON.stringify({success:!1,phase,status:"blocked",reason:"FULL_AUTO_APPROVAL_REQUIRED",message:`Phase ${phase} cannot be completed: ${approval.reason??"Full-Auto v2 approval missing"}`,agentsDispatched,agentsMissing:[],warnings:[`Full-Auto v2 active. Re-run critic_oversight with trigger_source=phase_boundary so an APPROVED record is written to .swarm/evidence/${phase}/full-auto-*.json before calling phase_complete again.`]},null,2)}let epicActiveForProject=isEpicModeActiveForProject(dir);if(hasActiveLeanTurbo(sessionID)&&!epicActiveForProject){let leanConfig=config3?.turbo?.lean,leanPhaseReadyConfig=leanConfig?{phase_reviewer:leanConfig.phase_reviewer,phase_critic:leanConfig.phase_critic,integrated_diff_required:leanConfig.integrated_diff_required}:void 0,leanCheck=_internals212.verifyLeanTurboPhaseReady(dir,phase,sessionID,leanPhaseReadyConfig);if(!leanCheck.ok)return JSON.stringify({success:!1,phase,status:"blocked",reason:"LEAN_TURBO_PHASE_NOT_READY",message:`Phase ${phase} cannot be completed: ${leanCheck.reason}`,agentsDispatched,agentsMissing:[],warnings:[`Lean Turbo phase readiness: ${leanCheck.reason}`]},null,2)}let knowledgeConfig;try{knowledgeConfig=KnowledgeConfigSchema.parse(config3.knowledge??{})}catch(parseErr){warnings.push(`Knowledge config validation failed: ${String(parseErr)}`),knowledgeConfig=KnowledgeConfigSchema.parse({})}if(retroFound&&retroEntry?.lessons_learned&&retroEntry.lessons_learned.length>0)try{let projectName=path281.basename(dir),curationResult=await curateAndStoreSwarm(retroEntry.lessons_learned,projectName,{phase_number:phase},dir,knowledgeConfig,{llmDelegate:createCuratorLLMDelegate(dir,"phase",sessionID),enrichmentQuota:{maxCalls:knowledgeConfig.enrichment.max_calls_per_day,window:knowledgeConfig.enrichment.quota_window}});if(curationResult&&curationResult.stored+curationResult.reinforced+curationResult.quarantined+curationResult.rejected>0){let sessionState=swarmState.agentSessions.get(sessionID);if(sessionState)pushAdvisory(sessionState,`[CURATOR] Knowledge curation: ${curationResult.stored} stored, ${curationResult.reinforced} reinforced, ${curationResult.skipped} skipped, ${curationResult.rejected} rejected, ${curationResult.quarantined} quarantined (unactionable).`)}}catch(error93){safeWarn("[phase_complete] Failed to curate lessons from retrospective:",error93)}let complianceWarnings=[];try{let curatorConfig=CuratorConfigSchema.parse(config3.curator??{});if(curatorConfig.enabled&&curatorConfig.phase_enabled){let llmDelegate=createCuratorLLMDelegate(dir,"phase",sessionID??void 0),curatorResult=await runCuratorPhase(dir,phase,agentsDispatched,curatorConfig,{},llmDelegate);{let scopeContent=curatorResult.digest?.summary??`Phase ${phase} curator analysis`,complianceWarnings2=curatorResult.compliance.filter((c)=>c.severity==="warning"),receipt=complianceWarnings2.length>0?buildRejectedReceipt({agent:"curator",scopeContent,scopeDescription:"phase-digest",blockingFindings:complianceWarnings2.map((c)=>({location:`phase-${c.phase}`,summary:c.description,severity:c.type==="missing_reviewer"?"high":"medium"})),evidenceReferences:[],passConditions:["resolve all compliance warnings before phase completion"]}):buildApprovedReceipt({agent:"curator",scopeContent,scopeDescription:"phase-digest",checkedAspects:["phase_compliance","knowledge_recommendations","phase_digest"],validatedClaims:[`phase: ${phase}`,`agents_dispatched: ${agentsDispatched.length}`,`knowledge_recommendations: ${curatorResult.knowledge_recommendations.length}`]});persistReviewReceipt(dir,receipt).catch(()=>{})}let knowledgeResult=await applyCuratorKnowledgeUpdates(dir,curatorResult.knowledge_recommendations,knowledgeConfig),driftAdvisoryPushedThisRun=!1;try{let{runDeterministicDriftCheck:runDeterministicDriftCheck2}=await Promise.resolve().then(() => (init_curator_drift(),exports_curator_drift));await runDeterministicDriftCheck2(dir,phase,curatorResult,curatorConfig,(message2)=>{let sessionState=swarmState.agentSessions.get(sessionID);if(sessionState)pushAdvisory(sessionState,message2),driftAdvisoryPushedThisRun=!0})}catch{}let callerSessionState=swarmState.agentSessions.get(sessionID);if(callerSessionState){let digestSummary=curatorResult.digest?.summary?curatorResult.digest.summary.slice(0,200):"Phase analysis complete",complianceNote=curatorResult.compliance.length>0?` (${curatorResult.compliance.length} compliance observation(s))`:"",analyzeHint=curatorResult.knowledge_recommendations.length>0?" Call curator_analyze with recommendations to apply knowledge updates from this phase.":"";if(digestSummary!=="Phase analysis complete")pushAdvisory(callerSessionState,`[CURATOR] Phase ${phase} digest: ${digestSummary}${complianceNote}. Knowledge: ${knowledgeResult.applied} applied, ${knowledgeResult.skipped} skipped.${analyzeHint}`);try{let{readPriorDriftReports:readPriorDriftReports2}=await Promise.resolve().then(() => (init_curator_drift(),exports_curator_drift)),phaseReport=(await readPriorDriftReports2(dir)).filter((r)=>r.phase===phase).pop();if(phaseReport&&phaseReport.drift_score>0&&!driftAdvisoryPushedThisRun)pushAdvisory(callerSessionState,`[CURATOR DRIFT DETECTED (phase ${phase}, score ${phaseReport.drift_score})]: Prior drift report found on disk. Consider running critic_drift_verifier before phase completion to get a proper drift review. Review drift report for phase ${phase} and address spec alignment if applicable.`)}catch{}}if(curatorResult.compliance.length>0&&!curatorConfig.suppress_warnings)complianceWarnings=curatorResult.compliance.map((obs)=>`[${obs.severity.toUpperCase()}] ${obs.description}`).slice(0,5)}}catch(curatorError){safeWarn("[phase_complete] Curator pipeline error (non-blocking):",curatorError)}try{if(config3.design_docs?.enabled===!0){let outDir=config3.design_docs.out_dir??"docs",{runDesignDocDriftCheck:runDesignDocDriftCheck2}=await Promise.resolve().then(() => (init_design_doc_drift(),exports_design_doc_drift)),docReport=await runDesignDocDriftCheck2(dir,phase,outDir);if(docReport?.verdict==="DOC_STALE"){let callerSessionState=swarmState.agentSessions.get(sessionID);if(callerSessionState){let staleIds=docReport.stale_sections.map((s)=>s.section_id).slice(0,8).join(", ");pushAdvisory(callerSessionState,`[DESIGN-DOC DRIFT (phase ${phase})]: ${docReport.stale_sections.length} design-doc section(s) are stale (${staleIds}). Run /swarm design-docs --update to sync ${outDir}/ and append a design-changelog entry. Advisory only — does not block completion.`)}}}}catch(docDriftError){safeWarn("[phase_complete] Design-doc drift check error (non-blocking):",docDriftError)}let floorOptions={floorAction:knowledgeConfig.confidence_floor_action,floorMinOutcomes:knowledgeConfig.confidence_floor_min_outcomes,floorSignalThreshold:knowledgeConfig.confidence_floor_signal_threshold};try{let feedbackResult=await applySkillUsageFeedback(dir,{floorOptions});if(feedbackResult.processed>0){let sessionState=swarmState.agentSessions.get(sessionID);if(sessionState)pushAdvisory(sessionState,`[FEEDBACK] Skill usage feedback: ${feedbackResult.processed} skills processed, ${feedbackResult.bumps} confidence updates applied.`)}}catch(skillUsageError){safeWarn("[phase_complete] Skill usage feedback error (non-blocking):",skillUsageError)}try{pruneSkillUsageLog(dir,500)}catch(skillPruneError){safeWarn("[phase_complete] Skill usage log pruning error (non-blocking):",skillPruneError)}try{let verdictMarkerPath=validateSwarmPath(dir,"verdict-feedback-last-processed.json"),verdictSinceTimestamp,verdictSinceEventId;try{let markerData=JSON.parse(fs168.readFileSync(verdictMarkerPath,"utf-8"));verdictSinceTimestamp=markerData.lastProcessedTimestamp,verdictSinceEventId=markerData.lastProcessedEventId}catch{}let{applyKnowledgeVerdictFeedback:applyKnowledgeVerdictFeedback2}=await Promise.resolve().then(() => (init_knowledge_events(),exports_knowledge_events)),verdictResult=await applyKnowledgeVerdictFeedback2(dir,{sinceTimestamp:verdictSinceTimestamp,sinceEventId:verdictSinceEventId,floorOptions});if(verdictResult.lastProcessedTimestamp)try{fs168.writeFileSync(verdictMarkerPath,JSON.stringify({lastProcessedTimestamp:verdictResult.lastProcessedTimestamp,lastProcessedEventId:verdictResult.lastProcessedEventId}),"utf-8")}catch{}if(verdictResult.bumps>0){let sessionState=swarmState.agentSessions.get(sessionID);if(sessionState)pushAdvisory(sessionState,`[FEEDBACK] Knowledge verdict feedback: ${verdictResult.processed} entries processed, ${verdictResult.bumps} confidence updates applied.`)}}catch(verdictError){safeWarn("[phase_complete] Knowledge verdict feedback error (non-blocking):",verdictError)}let phaseRequiredAgents,participationPlan=null;try{let plan=await loadPlan(dir);if(!plan)throw Error("plan unavailable");participationPlan=plan,phaseRequiredAgents=plan.phases.find((p)=>p.id===phase)?.required_agents}catch{}let configuredRequired=[...phaseRequiredAgents??phaseCompleteConfig.required_agents],effectiveRequired=[...configuredRequired],docsAddedByConfig=phaseCompleteConfig.require_docs&&!configuredRequired.includes("docs");if(phaseCompleteConfig.require_docs&&!effectiveRequired.includes("docs"))effectiveRequired.push("docs");let docsEvidenceStatus=null;if(effectiveRequired.includes("docs")){crossSessionResult.agents.delete("docs");let staleDocsIndex=agentsDispatched.indexOf("docs");if(staleDocsIndex!==-1)agentsDispatched.splice(staleDocsIndex,1);if(participationPlan){let docsParticipation=readPhaseParticipation(dir,participationPlan,phase,"docs");if(docsEvidenceStatus=docsParticipation.status,docsParticipation.found)crossSessionResult.agents.add("docs"),agentsDispatched.push("docs"),agentsDispatched.sort(),warnings.push(`Recovered durable docs participation proof for phase ${phase}.`)}}let agentsMissing=effectiveRequired.filter((req)=>!crossSessionResult.agents.has(req));if(agentsMissing.length>0)try{let planPath=validateSwarmPath(dir,"plan.json"),planRaw=fs168.readFileSync(planPath,"utf-8"),targetPhase=JSON.parse(planRaw).phases.find((p)=>p.id===phase);if(targetPhase&&targetPhase.tasks.length>0&&canInferMissingAgentsFromTaskGates(agentsMissing)&&await allCompletedTasksHavePassedGateEvidence(dir,targetPhase.tasks))warnings.push(`Agent dispatch fallback: all ${targetPhase.tasks.length} tasks in phase ${phase} are completed in plan.json and durable gate evidence passed. Clearing missing agents: ${agentsMissing.join(", ")}.`),agentsMissing=[]}catch{}let recoveryGuidance=buildMissingAgentRecoveryGuidance({missing:agentsMissing,docsAddedByConfig,docsEvidenceStatus,docsPlanReadable:participationPlan!==null,policy:phaseCompleteConfig.policy}),VALID_TASK_COMPLEXITY=["trivial","simple","moderate","complex"],firstEntry=loadedRetroBundle?.entries?.[0];if(loadedRetroTaskId!==primaryRetroTaskId&&loadedRetroTaskId?.startsWith("retro-")&&loadedRetroBundle?.schema_version==="1.0.0"&&firstEntry?.task_complexity&&VALID_TASK_COMPLEXITY.includes(firstEntry.task_complexity))warnings.push(`Retrospective data for phase ${phase} may have been automatically migrated to current schema format.`);let success3=!0,status="success",safeSummary=summary?.trim().slice(0,500),message=safeSummary?`Phase ${phase} completed: ${safeSummary}`:`Phase ${phase} completed`;if(agentsMissing.length>0)if(phaseCompleteConfig.policy==="enforce")success3=!1,status="incomplete",message=`Phase ${phase} incomplete: missing required agents: ${agentsMissing.join(", ")}. ${recoveryGuidance}`;else status="warned",warnings.push(`Warning: phase ${phase} missing required agents: ${agentsMissing.join(", ")}`);let result={success:success3,phase,status,message,agentsDispatched,agentsMissing,warnings,...recoveryGuidance?{recovery_guidance:recoveryGuidance}:{}},hasPlan=!1;try{hasPlan=fs168.existsSync(validateSwarmPath(dir,"plan.json"))}catch{}if(!hasPlan&&!crossSessionResult.agents.has("reviewer")&&!crossSessionResult.agents.has("test_engineer"))warnings.push(`⚠️ Plan-free phase ${phase}: no independent reviewer or test_engineer dispatch detected. Code changes in plan-free sessions should have independent review. Consider dispatching reviewer + test_engineer before completing future plan-free phases.`);if(retroFound&&retroEntry?.lessons_learned&&retroEntry.lessons_learned.length>0)await updateRetrievalOutcome(dir,`Phase ${phase}`,success3).catch(()=>{});if(phaseCompleteConfig.regression_sweep?.enforce)try{let planPath=validateSwarmPath(dir,"plan.json"),planRaw=fs168.readFileSync(planPath,"utf-8"),targetPhase=JSON.parse(planRaw).phases.find((p)=>p.id===phase);if(targetPhase){let sweepFound=!1;for(let task2 of targetPhase.tasks){let taskEvidenceResult=await loadEvidence(dir,task2.id);if(taskEvidenceResult.status==="found"){let entries=taskEvidenceResult.bundle.entries??[];for(let entry of entries)if(entry.regression_sweep!==void 0){sweepFound=!0;break}}if(sweepFound)break}if(!sweepFound)warnings.push(`Warning: regression_sweep.enforce=true but no regression-sweep result found for any task in phase ${phase}. Run tests to populate regression-sweep results.`)}}catch{}let now2=Date.now(),durationMs=now2-phaseReferenceTimestamp,event={event:"phase_complete",phase,timestamp:new Date(now2).toISOString(),agents_dispatched:agentsDispatched,agents_missing:agentsMissing,status,summary:safeSummary??null},lockTaskId=`phase-complete-${Date.now()}`,eventsFilePath="events.jsonl",agentName="phase-complete";for(let[,agent]of swarmState?.activeAgent??[]){agentName=agent;break}let lockResult;try{lockResult=await tryAcquireLock(dir,eventsFilePath,agentName,lockTaskId)}catch(error93){warnings.push(`Warning: failed to acquire lock for phase complete event: ${error93 instanceof Error?error93.message:String(error93)}`)}if(!lockResult?.acquired)warnings.push("Warning: could not acquire lock for events.jsonl write — proceeding without lock");try{let eventsPath=validateSwarmPath(dir,"events.jsonl");fs168.appendFileSync(eventsPath,`${JSON.stringify(event)}
@@ -6631,13 +6638,14 @@ ${task2.acceptance??""}`,matchesFreeText=idPattern.test(taskText),matchesFrRefs=
6631
6638
  `);for(let line of lines){let trimmed=line.trim();if(!trimmed||trimmed.startsWith("#")||trimmed.startsWith("metadata:"))continue;let match=trimmed.match(depRegex);if(match){let groupId=match[1],artifactId=match[2],version5=match[3];if(version5&&version5!=="unspecified")components.push({name:artifactId,version:version5,type:"library",purl:generatePurl("maven",artifactId,version5,groupId)})}}return components}var javaDetectors=[{name:"Java pom.xml",patterns:["pom.xml"],detect:(_filePath,content)=>{return parsePomXml(content)}},{name:"Java gradle.lockfile",patterns:["gradle.lockfile"],detect:(_filePath,content)=>{return parseGradleLockfile(content)}}];function parsePackageJson(content){let components=[];try{let pkg=JSON.parse(content),deps={...pkg.dependencies,...pkg.devDependencies};for(let[name,version5]of Object.entries(deps)){let cleanVersion=String(version5).replace(/^[\^~>=<]+/,"");components.push({name,version:cleanVersion||"unknown",type:"library",purl:generatePurl("npm",name,cleanVersion||"unknown")})}}catch{}return components}function parsePackageLock(content){let components=[];try{let lock=JSON.parse(content),packages=lock.packages||lock.dependencies||{};for(let[pkgPath,pkgData]of Object.entries(packages)){if(pkgPath==="")continue;let pkg=pkgData,version5=pkg.version||"",name=pkg.name||pkgPath.replace(/^node_modules\//,"").replace(/@.*$/,"");if(name&&version5)components.push({name,version:version5,type:"library",purl:generatePurl("npm",name,version5),license:pkg.license})}}catch{}return components}function parseYarnLock(content){let components=[],blocks=content.split(/^(?=@?[\w-]+@)/m);for(let block2 of blocks){let pkgMatch=block2.match(/^(@?[\w-]+)@(\d+\.\d+\.\d+(?:-[\w.]+)?)/m);if(!pkgMatch)continue;let name=pkgMatch[1],version5=pkgMatch[2];if(name&&version5)components.push({name,version:version5,type:"library",purl:generatePurl("npm",name,version5)})}return components}function parsePnpmLockYaml(content){let components=[];try{let lines=content.split(`
6632
6639
  `);for(let line of lines){let packageMatch=line.match(/^\s*\/(@?[\w-]+)@([\d.]+):?/);if(packageMatch)components.push({name:packageMatch[1],version:packageMatch[2],type:"library",purl:generatePurl("npm",packageMatch[1],packageMatch[2])})}}catch{}return components}var nodejsDetectors=[{name:"Node.js package-lock.json",patterns:["package-lock.json"],detect:(_filePath,content)=>{return parsePackageLock(content)}},{name:"Node.js yarn.lock",patterns:["yarn.lock"],detect:(_filePath,content)=>{return parseYarnLock(content)}},{name:"Node.js pnpm-lock.yaml",patterns:["pnpm-lock.yaml"],detect:(_filePath,content)=>{return parsePnpmLockYaml(content)}},{name:"Node.js package.json",patterns:["package.json"],detect:(_filePath,content)=>{return parsePackageJson(content)}}];function parseRequirementsTxt(content){let components=[],lines=content.split(`
6633
6640
  `);for(let line of lines){let trimmed=line.trim();if(!trimmed||trimmed.startsWith("#"))continue;if(trimmed.startsWith("-"))continue;let match=trimmed.match(/^([a-zA-Z0-9_-]+)(?:[=<>~!]+)?([\d.]+)?/);if(match){let name=match[1],version5=match[2]||"unknown";if(name)components.push({name,version:version5,type:"library",purl:generatePurl("pypi",name,version5)})}}return components}function parsePoetryLock(content){let components=[],packageBlocks=content.split(/\[\[package\]\]/);for(let block2 of packageBlocks){if(block2.trim()==="")continue;let nameMatch=block2.match(/name\s*=\s*"([^"]+)"/),versionMatch=block2.match(/version\s*=\s*"([^"]+)"/);if(nameMatch&&versionMatch){let name=nameMatch[1],version5=versionMatch[1],licenseMatch=block2.match(/license\s*=\s*"([^"]+)"/);components.push({name,version:version5,type:"library",purl:generatePurl("pypi",name,version5),license:licenseMatch?.[1]})}}return components}function parsePipfileLock(content){let components=[];try{let lock=JSON.parse(content),sections=[lock.default,lock.dev].filter(Boolean);for(let section of sections){if(!section)continue;for(let[name,pkgData]of Object.entries(section)){let version5=pkgData.version||"unknown";if(version5=version5.replace(/^[=<>~!]+/,""),version5&&version5!=="*")components.push({name,version:version5,type:"library",purl:generatePurl("pypi",name,version5)})}}}catch{}return components}var pythonDetectors=[{name:"Python poetry.lock",patterns:["poetry.lock"],detect:(_filePath,content)=>{return parsePoetryLock(content)}},{name:"Python Pipfile.lock",patterns:["Pipfile.lock"],detect:(_filePath,content)=>{return parsePipfileLock(content)}},{name:"Python requirements.txt",patterns:["requirements.txt"],detect:(_filePath,content)=>{return parseRequirementsTxt(content)}}];function parseCargoToml(content){let components=[],lines=content.split(`
6634
- `),inDependencies=!1,inDevDependencies=!1;for(let line of lines){let trimmed=line.trim();if(trimmed==="[dependencies]"||trimmed.startsWith("[dependencies]")){inDependencies=!0,inDevDependencies=!1;continue}if(trimmed==="[dev-dependencies]"||trimmed.startsWith("[dev-dependencies]")){inDependencies=!1,inDevDependencies=!0;continue}if(trimmed.startsWith("[")&&trimmed.endsWith("]")){inDependencies=!1,inDevDependencies=!1;continue}if(!inDependencies&&!inDevDependencies)continue;if(!trimmed||trimmed.startsWith("#"))continue;let match=trimmed.match(/^([a-zA-Z0-9_-]+)\s*=/);if(match){let name=match[1],version5="unknown",simpleMatch=trimmed.match(/"([\d.]+)"/);if(simpleMatch)version5=simpleMatch[1];else{let versionFieldMatch=trimmed.match(/version\s*=\s*"([\d.]+)"/);if(versionFieldMatch)version5=versionFieldMatch[1]}if(name&&version5!=="unknown")components.push({name,version:version5,type:"library",purl:generatePurl("cargo",name,version5)})}}return components}function parseCargoLock(content){let components=[],packageBlocks=content.split(/\[\[package\]\]/);for(let block2 of packageBlocks){if(block2.trim()==="")continue;let nameMatch=block2.match(/name\s*=\s*"([^"]+)"/),versionMatch=block2.match(/version\s*=\s*"([^"]+)"/);if(nameMatch&&versionMatch){let name=nameMatch[1],version5=versionMatch[1];components.push({name,version:version5,type:"library",purl:generatePurl("cargo",name,version5)})}}return components}var rustDetectors=[{name:"Rust Cargo.lock",patterns:["Cargo.lock"],detect:(_filePath,content)=>{return parseCargoLock(content)}},{name:"Rust Cargo.toml",patterns:["Cargo.toml"],detect:(_filePath,content)=>{return parseCargoToml(content)}}];function parsePackageResolved(content){let components=[];try{let pins=JSON.parse(content).pins||[];for(let pin of pins){let identity=pin.identity||pin.package||"",state=pin.state||{},version5=state.version||state.revision||"",org="",orgMatch=(pin.location||"").match(/github\.com\/([^/]+)\//);if(orgMatch)org=orgMatch[1];if(identity&&version5)components.push({name:identity,version:version5,type:"library",purl:generatePurl("swift",identity,version5,org||void 0)})}}catch{}return components}var swiftDetectors=[{name:"Swift Package.resolved",patterns:["Package.resolved"],detect:(_filePath,content)=>{return parsePackageResolved(content)}}];function generatePurl(ecosystem,name,version5,namespace){let encodedName=encodeURIComponent(name),encodedVersion=encodeURIComponent(version5);switch(ecosystem){case"npm":return`pkg:npm/${encodedName}@${encodedVersion}`;case"pypi":return`pkg:pypi/${encodedName}@${encodedVersion}`;case"cargo":return`pkg:cargo/${encodedName}@${encodedVersion}`;case"golang":if(namespace)return`pkg:golang/${namespace}/${encodedName}@${encodedVersion}`;return`pkg:golang/${encodedName}@${encodedVersion}`;case"maven":return`pkg:maven/${encodeURIComponent(namespace||"unknown")}/${encodedName}@${encodedVersion}`;case"nuget":return`pkg:nuget/${encodedName}@${encodedVersion}`;case"swift":if(namespace)return`pkg:swift/${encodeURIComponent(namespace)}/${encodedName}@${encodedVersion}`;return`pkg:swift/${encodedName}@${encodedVersion}`;case"pub":return`pkg:pub/${encodedName}@${encodedVersion}`;default:return`pkg:unknown/${encodedName}@${encodedVersion}`}}var allDetectors=[...nodejsDetectors,...pythonDetectors,...rustDetectors,...goDetectors,...javaDetectors,...dotnetDetectors,...swiftDetectors,...dartDetectors];function findDetectorsForFile(filePath){let fileName=filePath.split(/[/\\]/).pop()||"";return allDetectors.filter((detector)=>detector.patterns.some((pattern)=>simpleGlobToRegex(pattern).test(fileName)))}function detectComponents(filePath,content){let detectors=findDetectorsForFile(filePath);for(let detector of detectors)try{let components=detector.detect(filePath,content);if(components.length>0)return components}catch(error93){log(`[sbom] Detector failed for ${filePath}:`,error93 instanceof Error?error93.message:String(error93))}return[]}var DEFAULT_TOOL_VENDOR="opencode-swarm",DEFAULT_TOOL_NAME="sbom_generate",DEFAULT_TOOL_VERSION="6.9.0";function toCycloneDXComponent(component){let cyclonedxComponent={type:component.type,name:component.name,version:component.version};if(component.purl)cyclonedxComponent.purl=component.purl;if(component.license){let isSpdxId=/^[A-Za-z][A-Za-z0-9.*+-]*$/.test(component.license);cyclonedxComponent.licenses=[{license:isSpdxId?{id:component.license}:{name:component.license}}]}return cyclonedxComponent}function generateCycloneDX(components,options){let toolName=options?.toolName??DEFAULT_TOOL_NAME,toolVersion=options?.toolVersion??DEFAULT_TOOL_VERSION,bomVersion=options?.bomVersion??1,timestamp=new Date().toISOString(),cyclonedxComponents=components.map(toCycloneDXComponent);return{bomFormat:"CycloneDX",specVersion:"1.5",version:bomVersion,metadata:{timestamp,tools:[{vendor:DEFAULT_TOOL_VENDOR,name:toolName,version:toolVersion}]},components:cyclonedxComponents}}function serializeCycloneDX(bom){return JSON.stringify(bom,null,2)}init_utils();init_logger();init_swarm_artifact_cache();init_create_tool();var DEFAULT_OUTPUT_DIR=".swarm/evidence/sbom";function findManifestFiles(rootDir){let manifestFiles=[],patterns=[...new Set(allDetectors.flatMap((d)=>d.patterns))];function searchDir(dir){try{let entries=fs178.readdirSync(dir,{withFileTypes:!0});for(let entry of entries){let fullPath=path294.join(dir,entry.name);if(entry.name.startsWith(".")||entry.name==="node_modules"||entry.name==="dist"||entry.name==="build"||entry.name==="target")continue;if(entry.isDirectory())searchDir(fullPath);else if(entry.isFile()){for(let pattern of patterns)if(simpleGlobToRegex(pattern).test(entry.name)){manifestFiles.push(path294.relative(rootDir,fullPath));break}}}}catch{}}return searchDir(rootDir),manifestFiles}function findManifestFilesInDirs(directories,workingDir){let found=[],patterns=[...new Set(allDetectors.flatMap((d)=>d.patterns))];for(let dir of directories)try{let entries=fs178.readdirSync(dir,{withFileTypes:!0});for(let entry of entries){let fullPath=path294.join(dir,entry.name);if(entry.isFile()){for(let pattern of patterns)if(simpleGlobToRegex(pattern).test(entry.name)){found.push(path294.relative(workingDir,fullPath));break}}}}catch{}return found}function getDirectoriesFromChangedFiles(changedFiles,workingDir){let dirs=new Set;for(let file3 of changedFiles){let currentDir=path294.dirname(file3);while(!0)if(currentDir&&currentDir!=="."&&currentDir!==path294.sep){dirs.add(path294.join(workingDir,currentDir));let parent=path294.dirname(currentDir);if(parent===currentDir)break;currentDir=parent}else{dirs.add(workingDir);break}}return[...dirs]}function ensureOutputDir(outputDir){try{fs178.mkdirSync(outputDir,{recursive:!0})}catch(error93){if(!error93||error93.code!=="EEXIST")throw error93}}function generateSbomFilename(){let now2=new Date,year=now2.getFullYear(),month=String(now2.getMonth()+1).padStart(2,"0"),day=String(now2.getDate()).padStart(2,"0"),hours=String(now2.getHours()).padStart(2,"0"),minutes=String(now2.getMinutes()).padStart(2,"0"),seconds=String(now2.getSeconds()).padStart(2,"0");return`sbom-${year}${month}${day}-${hours}${minutes}${seconds}.json`}function validateArgs4(args2){if(typeof args2!=="object"||args2===null)return!1;let obj=args2;if(typeof obj.scope!=="string"||!["changed","all"].includes(obj.scope))return!1;if(obj.scope==="changed"){if(!Array.isArray(obj.changed_files)||obj.changed_files.length===0)return!1}if(obj.output_dir!==void 0&&typeof obj.output_dir!=="string")return!1;if(obj.changed_files!==void 0){if(!Array.isArray(obj.changed_files))return!1;for(let f of obj.changed_files)if(typeof f!=="string")return!1}return!0}var sbom_generate=createSwarmTool({allowWorkingDirectoryOverride:!0,description:"Generate Software Bill of Materials (SBOM) by scanning project for dependency manifests. Uses CycloneDX format. Supports scanning entire project or only changed files.",args:{scope:exports_external.enum(["changed","all"]).describe('Scan scope: "changed" for modified files only, "all" for entire project'),changed_files:exports_external.array(exports_external.string()).optional().describe('List of changed files (required if scope="changed")'),output_dir:exports_external.string().optional().describe("Output directory for SBOM (default: .swarm/evidence/sbom/)")},async execute(args2,directory){if(!validateArgs4(args2))return JSON.stringify({...{verdict:"skip",files:[],components_count:0,output_path:""},error:'Invalid arguments: scope is required ("changed" or "all"), and changed_files is required when scope="changed"'},null,2);let obj=args2,scope=obj.scope,changedFiles=obj.changed_files,relativeOutputDir=obj.output_dir||DEFAULT_OUTPUT_DIR,workingDir=directory,outputDir=path294.isAbsolute(relativeOutputDir)?relativeOutputDir:path294.join(workingDir,relativeOutputDir),manifestFiles=[];if(scope==="all")manifestFiles=findManifestFiles(workingDir);else if(scope==="changed"&&changedFiles&&changedFiles.length>0){let changedDirs=getDirectoriesFromChangedFiles(changedFiles,workingDir);if(changedDirs.length>0)manifestFiles=findManifestFilesInDirs(changedDirs,workingDir)}if(manifestFiles.length===0)return JSON.stringify({verdict:"skip",files:[],components_count:0,output_path:""},null,2);let allComponents=[],processedFiles=[];for(let manifestFile of manifestFiles)try{let fullPath=path294.isAbsolute(manifestFile)?manifestFile:path294.join(workingDir,manifestFile);if(!fs178.existsSync(fullPath))continue;let content=fs178.readFileSync(fullPath,"utf-8"),components=detectComponents(manifestFile,content);if(processedFiles.push(manifestFile),components.length>0)allComponents.push(...components)}catch{}if(processedFiles.length===0&&manifestFiles.length>0);ensureOutputDir(outputDir);let bom=generateCycloneDX(allComponents),bomJson=serializeCycloneDX(bom),filename=generateSbomFilename(),outputPath=path294.join(outputDir,filename);fs178.writeFileSync(outputPath,bomJson,"utf-8"),invalidateCachedArtifact(outputPath);let verdict=processedFiles.length>0?"pass":"pass";try{let timestamp=new Date().toISOString();await saveEvidence(workingDir,"sbom_generate",{task_id:"sbom_generate",type:"sbom",timestamp,agent:"sbom_generate",verdict,summary:`Generated SBOM with ${allComponents.length} component(s) from ${processedFiles.length} manifest file(s)`,components:allComponents.map((c)=>({name:c.name,version:c.version,type:c.type,purl:c.purl,license:c.license})),metadata:{timestamp,tool:"sbom_generate",tool_version:"6.9.0"},files:processedFiles,components_count:allComponents.length,output_path:outputPath})}catch(error93){log(`Warning: Failed to save SBOM evidence: ${error93 instanceof Error?error93.message:String(error93)}`)}let result={verdict,files:processedFiles,components_count:allComponents.length,output_path:outputPath};return JSON.stringify(result,null,2)}});init_zod();init_create_tool();import*as fs179 from"node:fs";import*as path295 from"node:path";var SPEC_CANDIDATES=["openapi.json","openapi.yaml","openapi.yml","swagger.json","swagger.yaml","swagger.yml","api/openapi.json","api/openapi.yaml","docs/openapi.json","docs/openapi.yaml","spec/openapi.json","spec/openapi.yaml"],SKIP_DIRS=["node_modules","dist","build",".git",".swarm","coverage","__tests__"],SKIP_EXTENSIONS=[".test.",".spec."],MAX_SPEC_SIZE=10485760,ALLOWED_EXTENSIONS=[".json",".yaml",".yml"];function normalizeApiPath(p){return p.replace(/\/$/,"").replace(/\{[^}]+\}/g,":param").replace(/:[a-zA-Z_][a-zA-Z0-9_]*/g,":param")}function discoverSpecFile(cwd,specFileArg){if(specFileArg){let resolvedPath=path295.resolve(cwd,specFileArg),normalizedCwd=cwd.endsWith(path295.sep)?cwd:cwd+path295.sep;if(!resolvedPath.startsWith(normalizedCwd)&&resolvedPath!==cwd)throw Error("Invalid spec_file: path traversal detected");let ext=path295.extname(resolvedPath).toLowerCase();if(!ALLOWED_EXTENSIONS.includes(ext))throw Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);if(fs179.statSync(resolvedPath).size>MAX_SPEC_SIZE)throw Error(`Invalid spec_file: file exceeds ${MAX_SPEC_SIZE/1024/1024}MB limit`);if(!fs179.existsSync(resolvedPath))throw Error(`Spec file not found: ${resolvedPath}`);return resolvedPath}for(let candidate2 of SPEC_CANDIDATES){let candidatePath=path295.resolve(cwd,candidate2);if(fs179.existsSync(candidatePath)){if(fs179.statSync(candidatePath).size<=MAX_SPEC_SIZE)return candidatePath}}return null}function parseSpec(specFile){let content=fs179.readFileSync(specFile,"utf-8");if(path295.extname(specFile).toLowerCase()===".json")return parseJsonSpec(content);return parseYamlSpec(content)}function parseJsonSpec(content){let spec;try{spec=JSON.parse(content)}catch{return[]}let paths=[];if(!spec.paths)return paths;for(let[pathKey2,pathValue]of Object.entries(spec.paths)){let methods=[];if(typeof pathValue==="object"&&pathValue!==null){for(let method of["get","post","put","patch","delete","options","head"])if(method in pathValue)methods.push(method)}if(methods.length>0)paths.push({path:pathKey2,methods})}return paths}function parseYamlSpec(content){let paths=[];if(!content.match(/^paths:\s*$/m))return paths;let pathRegex=/^\s{2}(\/[^\s:]+):/gm;for(let match=pathRegex.exec(content);match!==null;match=pathRegex.exec(content)){let pathKey2=match[1],methodRegex=/^\s{4}(get|post|put|patch|delete|options|head):/gm,methods=[],pathStart=match.index,nextPathMatch=content.substring(pathStart+1).match(/^\s{2}\//m),pathEnd=nextPathMatch&&nextPathMatch.index!==void 0?pathStart+1+nextPathMatch.index:content.length,pathSection=content.substring(pathStart,pathEnd),methodMatch=methodRegex.exec(pathSection);while(methodMatch!==null)methods.push(methodMatch[1]),methodMatch=methodRegex.exec(pathSection);if(methods.length>0)paths.push({path:pathKey2,methods})}return paths}function extractRoutes2(cwd){let routes=[];function walkDir2(dir){let entries;try{entries=fs179.readdirSync(dir,{withFileTypes:!0})}catch{return}for(let entry of entries){let fullPath=path295.join(dir,entry.name);if(entry.isSymbolicLink())continue;if(entry.isDirectory()){if(SKIP_DIRS.includes(entry.name))continue;walkDir2(fullPath)}else if(entry.isFile()){let ext=path295.extname(entry.name).toLowerCase(),baseName=entry.name.toLowerCase();if(![".ts",".js",".mjs"].includes(ext))continue;if(SKIP_EXTENSIONS.some((skip)=>baseName.includes(skip)))continue;let fileRoutes=extractRoutesFromFile(fullPath);routes.push(...fileRoutes)}}}return walkDir2(cwd),routes}function extractRoutesFromFile(filePath){let routes=[],lines=fs179.readFileSync(filePath,"utf-8").split(/\r?\n/),expressRegex=/(?:app|router|server|express)\.(get|post|put|patch|delete|options|head)\s*\(\s*['"`]([^'"`]+)['"`]/g,flaskRegex=/@(?:app|blueprint|bp)\.route\s*\(\s*['"]([^'"]+)['"]/g;for(let lineNum=0;lineNum<lines.length;lineNum++){let line=lines[lineNum],match=expressRegex.exec(line);expressRegex.lastIndex=0,flaskRegex.lastIndex=0;while(match!==null){let method=match[1].toLowerCase(),routePath=match[2];routes.push({path:routePath,method,file:filePath,line:lineNum+1}),match=expressRegex.exec(line)}match=flaskRegex.exec(line);while(match!==null){let routePath=match[1];routes.push({path:routePath,method:"get",file:filePath,line:lineNum+1}),match=flaskRegex.exec(line)}}return routes}function findDrift(specPaths,codeRoutes){let specPathMap=new Map;for(let sp of specPaths){let normalized=normalizeApiPath(sp.path);if(!specPathMap.has(normalized))specPathMap.set(normalized,[]);specPathMap.get(normalized).push(...sp.methods)}let codeRouteMap=new Map;for(let cr of codeRoutes){let normalized=normalizeApiPath(cr.path);if(!codeRouteMap.has(normalized))codeRouteMap.set(normalized,[]);codeRouteMap.get(normalized).push(cr)}let undocumented=[];for(let[normalized,routes]of codeRouteMap)if(!specPathMap.has(normalized))for(let route of routes)undocumented.push({path:route.path,method:route.method,file:route.file,line:route.line});let phantom=[];for(let[normalized,methods]of specPathMap)if(!codeRouteMap.has(normalized))phantom.push({path:specPaths.find((sp)=>normalizeApiPath(sp.path)===normalized).path,methods});return{undocumented,phantom}}var schema_drift=createSwarmTool({description:"Compare OpenAPI spec against actual route implementations to find drift. Detects undocumented routes in code and phantom routes in spec.",args:{spec_file:exports_external.string().optional().describe("Path to OpenAPI spec file. Auto-detected if omitted. Checks: openapi.json/yaml/yml, swagger.json/yaml/yml, api/openapi.json/yaml, docs/openapi.json/yaml, spec/openapi.json/yaml")},async execute(args2,directory){let cwd=directory;if(args2!==null&&typeof args2!=="object")return JSON.stringify({...{specFile:"",specPathCount:0,codeRouteCount:0,undocumented:[],phantom:[],undocumentedCount:0,phantomCount:0,consistent:!1},error:"Invalid arguments"},null,2);let argsObj=args2;try{let specFile=discoverSpecFile(cwd,argsObj.spec_file);if(!specFile)return JSON.stringify({...{specFile:"",specPathCount:0,codeRouteCount:0,undocumented:[],phantom:[],undocumentedCount:0,phantomCount:0,consistent:!1},error:"No OpenAPI spec file found. Provide spec_file or place spec in one of: openapi.json/yaml/yml, swagger.json/yaml/yml, api/openapi.json/yaml, docs/openapi.json/yaml, spec/openapi.json/yaml"},null,2);let specPaths=parseSpec(specFile),codeRoutes=extractRoutes2(cwd),{undocumented,phantom}=findDrift(specPaths,codeRoutes),result={specFile,specPathCount:specPaths.length,codeRouteCount:codeRoutes.length,undocumented,phantom,undocumentedCount:undocumented.length,phantomCount:phantom.length,consistent:undocumented.length===0&&phantom.length===0};return JSON.stringify(result,null,2)}catch(error93){let errorMessage3=error93 instanceof Error?error93.message:"Unknown error";return JSON.stringify({...{specFile:"",specPathCount:0,codeRouteCount:0,undocumented:[],phantom:[],undocumentedCount:0,phantomCount:0,consistent:!1},error:errorMessage3},null,2)}}});init_zod();init_external_tool_runner();init_path_security();init_create_tool();import*as fs180 from"node:fs";import{createRequire as createRequire6}from"node:module";import*as path296 from"node:path";var require2=createRequire6(import.meta.url),DEFAULT_MAX_RESULTS4=100,DEFAULT_MAX_LINES=200,REGEX_TIMEOUT_MS=5000,MAX_FILE_SIZE_BYTES9=1048576,HARD_CAP_RESULTS4=1e4,HARD_CAP_LINES=1e4,MAX_QUERY_LENGTH=20000,MAX_RG_STDOUT_BYTES=8388608,MAX_RG_STDERR_BYTES=65536,FALLBACK_MAX_FILES=20000,FALLBACK_MAX_DIRS=5000,FALLBACK_MAX_DEPTH=40,FALLBACK_MAX_TOTAL_BYTES=67108864,DEFAULT_SKIP_DIRS=new Set([".git",".swarm","node_modules","dist","build","out","coverage",".next",".turbo",".cache"]);function globMatch(pattern,filePath){let normalizedPattern=pattern.replace(/\\/g,"/"),normalizedPath2=filePath.replace(/\\/g,"/"),regexPattern=normalizedPattern.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*\*/g,"{{DOUBLESTAR}}").replace(/\*/g,"[^/]*").replace(/\?/g,".").replace(/\{\{DOUBLESTAR\}\}/g,".*");try{return new RegExp(`^${regexPattern}$`).test(normalizedPath2)}catch{return!1}}function matchesGlobs(filePath,globs){if(globs.length===0)return!0;return globs.some((glob)=>globMatch(glob,filePath))}var WINDOWS_RESERVED_NAMES5=/^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;function containsWindowsAttacks4(str){if(/:[^\\/]/.test(str))return!0;let parts=str.split(/[/\\]/);for(let part of parts)if(WINDOWS_RESERVED_NAMES5.test(part))return!0;return!1}function isPathInWorkspace3(filePath,workspace){try{let resolvedPath=path296.resolve(workspace,filePath),realWorkspace=fs180.realpathSync(workspace),realResolvedPath=fs180.realpathSync(resolvedPath),relativePath2=path296.relative(realWorkspace,realResolvedPath);if(relativePath2.startsWith("..")||path296.isAbsolute(relativePath2))return!1;return!0}catch{return!1}}function validatePathForRead2(filePath,workspace){return isPathInWorkspace3(filePath,workspace)}function splitGlobPatterns2(value){return value?value.split(",").map((p)=>p.trim()).filter(Boolean):[]}function toWorkspaceRelativePath2(filePath,workspace){try{let resolved=path296.resolve(workspace,filePath),realWorkspace=fs180.realpathSync(workspace),realResolved=fs180.realpathSync(resolved),relative73=path296.relative(realWorkspace,realResolved);if(!relative73||relative73.startsWith("..")||path296.isAbsolute(relative73))return null;return relative73.split(path296.sep).join("/")}catch{return null}}function truncateLine(line,maxLines){let trimmed=line.trimEnd();if(trimmed.length>maxLines)return`${trimmed.substring(0,maxLines)}...`;return trimmed}function resolvePackagedRipgrep(){try{let mod=require2("@vscode/ripgrep");return typeof mod.rgPath==="string"&&mod.rgPath?mod.rgPath:null}catch{return null}}function resolveRipgrepBinary(){return _internals219.resolvePackagedRipgrep()??_internals219.resolveExecutableFromPath(["rg"])}async function ripgrepSearch(opts){let rgPath=_internals219.resolveRipgrepBinary();if(!rgPath)return{error:!0,type:"rg-not-found",message:"ripgrep (rg) not found; using fallback search was not possible"};let args2=["--json","--no-config","-n"];for(let pattern of splitGlobPatterns2(opts.include))args2.push("--glob",pattern);for(let pattern of splitGlobPatterns2(opts.exclude))args2.push("--glob",`!${pattern}`);if(opts.mode!=="regex")args2.push("--fixed-strings");args2.push("--",opts.query,".");let run=await _internals219.runExternalTool({executable:rgPath,args:args2,cwd:opts.workspace,timeoutMs:REGEX_TIMEOUT_MS,maxStdoutBytes:MAX_RG_STDOUT_BYTES,maxStderrBytes:MAX_RG_STDERR_BYTES});try{if(run.status==="timeout")return{error:!0,type:"regex-timeout",message:`Search timed out after ${REGEX_TIMEOUT_MS}ms`};if(run.status==="spawn-error")return{error:!0,type:"unknown",message:run.message??"ripgrep failed to start"};if(run.exitCode!==0&&run.stderr){if(run.stderr.includes("Invalid regex")||run.stderr.includes("regex parse error")||run.stderr.includes("SyntaxError"))return{error:!0,type:"invalid-query",message:`Invalid query: ${run.stderr.split(`
6641
+ `),inDependencies=!1,inDevDependencies=!1;for(let line of lines){let trimmed=line.trim();if(trimmed==="[dependencies]"||trimmed.startsWith("[dependencies]")){inDependencies=!0,inDevDependencies=!1;continue}if(trimmed==="[dev-dependencies]"||trimmed.startsWith("[dev-dependencies]")){inDependencies=!1,inDevDependencies=!0;continue}if(trimmed.startsWith("[")&&trimmed.endsWith("]")){inDependencies=!1,inDevDependencies=!1;continue}if(!inDependencies&&!inDevDependencies)continue;if(!trimmed||trimmed.startsWith("#"))continue;let match=trimmed.match(/^([a-zA-Z0-9_-]+)\s*=/);if(match){let name=match[1],version5="unknown",simpleMatch=trimmed.match(/"([\d.]+)"/);if(simpleMatch)version5=simpleMatch[1];else{let versionFieldMatch=trimmed.match(/version\s*=\s*"([\d.]+)"/);if(versionFieldMatch)version5=versionFieldMatch[1]}if(name&&version5!=="unknown")components.push({name,version:version5,type:"library",purl:generatePurl("cargo",name,version5)})}}return components}function parseCargoLock(content){let components=[],packageBlocks=content.split(/\[\[package\]\]/);for(let block2 of packageBlocks){if(block2.trim()==="")continue;let nameMatch=block2.match(/name\s*=\s*"([^"]+)"/),versionMatch=block2.match(/version\s*=\s*"([^"]+)"/);if(nameMatch&&versionMatch){let name=nameMatch[1],version5=versionMatch[1];components.push({name,version:version5,type:"library",purl:generatePurl("cargo",name,version5)})}}return components}var rustDetectors=[{name:"Rust Cargo.lock",patterns:["Cargo.lock"],detect:(_filePath,content)=>{return parseCargoLock(content)}},{name:"Rust Cargo.toml",patterns:["Cargo.toml"],detect:(_filePath,content)=>{return parseCargoToml(content)}}];function parsePackageResolved(content){let components=[];try{let pins=JSON.parse(content).pins||[];for(let pin of pins){let identity=pin.identity||pin.package||"",state=pin.state||{},version5=state.version||state.revision||"",org="",orgMatch=(pin.location||"").match(/github\.com\/([^/]+)\//);if(orgMatch)org=orgMatch[1];if(identity&&version5)components.push({name:identity,version:version5,type:"library",purl:generatePurl("swift",identity,version5,org||void 0)})}}catch{}return components}var swiftDetectors=[{name:"Swift Package.resolved",patterns:["Package.resolved"],detect:(_filePath,content)=>{return parsePackageResolved(content)}}];function generatePurl(ecosystem,name,version5,namespace){let encodedName=encodeURIComponent(name),encodedVersion=encodeURIComponent(version5);switch(ecosystem){case"npm":return`pkg:npm/${encodedName}@${encodedVersion}`;case"pypi":return`pkg:pypi/${encodedName}@${encodedVersion}`;case"cargo":return`pkg:cargo/${encodedName}@${encodedVersion}`;case"golang":if(namespace)return`pkg:golang/${namespace}/${encodedName}@${encodedVersion}`;return`pkg:golang/${encodedName}@${encodedVersion}`;case"maven":return`pkg:maven/${encodeURIComponent(namespace||"unknown")}/${encodedName}@${encodedVersion}`;case"nuget":return`pkg:nuget/${encodedName}@${encodedVersion}`;case"swift":if(namespace)return`pkg:swift/${encodeURIComponent(namespace)}/${encodedName}@${encodedVersion}`;return`pkg:swift/${encodedName}@${encodedVersion}`;case"pub":return`pkg:pub/${encodedName}@${encodedVersion}`;default:return`pkg:unknown/${encodedName}@${encodedVersion}`}}var allDetectors=[...nodejsDetectors,...pythonDetectors,...rustDetectors,...goDetectors,...javaDetectors,...dotnetDetectors,...swiftDetectors,...dartDetectors];function findDetectorsForFile(filePath){let fileName=filePath.split(/[/\\]/).pop()||"";return allDetectors.filter((detector)=>detector.patterns.some((pattern)=>simpleGlobToRegex(pattern).test(fileName)))}function detectComponents(filePath,content){let detectors=findDetectorsForFile(filePath);for(let detector of detectors)try{let components=detector.detect(filePath,content);if(components.length>0)return components}catch(error93){log(`[sbom] Detector failed for ${filePath}:`,error93 instanceof Error?error93.message:String(error93))}return[]}var DEFAULT_TOOL_VENDOR="opencode-swarm",DEFAULT_TOOL_NAME="sbom_generate",DEFAULT_TOOL_VERSION="6.9.0";function toCycloneDXComponent(component){let cyclonedxComponent={type:component.type,name:component.name,version:component.version};if(component.purl)cyclonedxComponent.purl=component.purl;if(component.license){let isSpdxId=/^[A-Za-z][A-Za-z0-9.*+-]*$/.test(component.license);cyclonedxComponent.licenses=[{license:isSpdxId?{id:component.license}:{name:component.license}}]}return cyclonedxComponent}function generateCycloneDX(components,options){let toolName=options?.toolName??DEFAULT_TOOL_NAME,toolVersion=options?.toolVersion??DEFAULT_TOOL_VERSION,bomVersion=options?.bomVersion??1,timestamp=new Date().toISOString(),cyclonedxComponents=components.map(toCycloneDXComponent);return{bomFormat:"CycloneDX",specVersion:"1.5",version:bomVersion,metadata:{timestamp,tools:[{vendor:DEFAULT_TOOL_VENDOR,name:toolName,version:toolVersion}]},components:cyclonedxComponents}}function serializeCycloneDX(bom){return JSON.stringify(bom,null,2)}init_utils();init_logger();init_swarm_artifact_cache();init_create_tool();var DEFAULT_OUTPUT_DIR=".swarm/evidence/sbom";function findManifestFiles(rootDir){let manifestFiles=[],patterns=[...new Set(allDetectors.flatMap((d)=>d.patterns))];function searchDir(dir){try{let entries=fs178.readdirSync(dir,{withFileTypes:!0});for(let entry of entries){let fullPath=path294.join(dir,entry.name);if(entry.name.startsWith(".")||entry.name==="node_modules"||entry.name==="dist"||entry.name==="build"||entry.name==="target")continue;if(entry.isDirectory())searchDir(fullPath);else if(entry.isFile()){for(let pattern of patterns)if(simpleGlobToRegex(pattern).test(entry.name)){manifestFiles.push(path294.relative(rootDir,fullPath));break}}}}catch{}}return searchDir(rootDir),manifestFiles}function findManifestFilesInDirs(directories,workingDir){let found=[],patterns=[...new Set(allDetectors.flatMap((d)=>d.patterns))];for(let dir of directories)try{let entries=fs178.readdirSync(dir,{withFileTypes:!0});for(let entry of entries){let fullPath=path294.join(dir,entry.name);if(entry.isFile()){for(let pattern of patterns)if(simpleGlobToRegex(pattern).test(entry.name)){found.push(path294.relative(workingDir,fullPath));break}}}}catch{}return found}function getDirectoriesFromChangedFiles(changedFiles,workingDir){let dirs=new Set;for(let file3 of changedFiles){let currentDir=path294.dirname(file3);while(!0)if(currentDir&&currentDir!=="."&&currentDir!==path294.sep){dirs.add(path294.join(workingDir,currentDir));let parent=path294.dirname(currentDir);if(parent===currentDir)break;currentDir=parent}else{dirs.add(workingDir);break}}return[...dirs]}function ensureOutputDir(outputDir){try{fs178.mkdirSync(outputDir,{recursive:!0})}catch(error93){if(!error93||error93.code!=="EEXIST")throw error93}}function generateSbomFilename(){let now2=new Date,year=now2.getFullYear(),month=String(now2.getMonth()+1).padStart(2,"0"),day=String(now2.getDate()).padStart(2,"0"),hours=String(now2.getHours()).padStart(2,"0"),minutes=String(now2.getMinutes()).padStart(2,"0"),seconds=String(now2.getSeconds()).padStart(2,"0");return`sbom-${year}${month}${day}-${hours}${minutes}${seconds}.json`}function validateArgs4(args2){if(typeof args2!=="object"||args2===null)return!1;let obj=args2;if(typeof obj.scope!=="string"||!["changed","all"].includes(obj.scope))return!1;if(obj.scope==="changed"){if(!Array.isArray(obj.changed_files)||obj.changed_files.length===0)return!1}if(obj.output_dir!==void 0&&typeof obj.output_dir!=="string")return!1;if(obj.changed_files!==void 0){if(!Array.isArray(obj.changed_files))return!1;for(let f of obj.changed_files)if(typeof f!=="string")return!1}return!0}var sbom_generate=createSwarmTool({allowWorkingDirectoryOverride:!0,description:"Generate Software Bill of Materials (SBOM) by scanning project for dependency manifests. Uses CycloneDX format. Supports scanning entire project or only changed files.",args:{scope:exports_external.enum(["changed","all"]).describe('Scan scope: "changed" for modified files only, "all" for entire project'),changed_files:exports_external.array(exports_external.string()).optional().describe('List of changed files (required if scope="changed")'),output_dir:exports_external.string().optional().describe("Output directory for SBOM (default: .swarm/evidence/sbom/)")},async execute(args2,directory){if(!validateArgs4(args2))return JSON.stringify({...{verdict:"skip",files:[],components_count:0,output_path:""},error:'Invalid arguments: scope is required ("changed" or "all"), and changed_files is required when scope="changed"'},null,2);let obj=args2,scope=obj.scope,changedFiles=obj.changed_files,relativeOutputDir=obj.output_dir||DEFAULT_OUTPUT_DIR,workingDir=directory,outputDir=path294.isAbsolute(relativeOutputDir)?relativeOutputDir:path294.join(workingDir,relativeOutputDir),manifestFiles=[];if(scope==="all")manifestFiles=findManifestFiles(workingDir);else if(scope==="changed"&&changedFiles&&changedFiles.length>0){let changedDirs=getDirectoriesFromChangedFiles(changedFiles,workingDir);if(changedDirs.length>0)manifestFiles=findManifestFilesInDirs(changedDirs,workingDir)}if(manifestFiles.length===0)return JSON.stringify({verdict:"skip",files:[],components_count:0,output_path:""},null,2);let allComponents=[],processedFiles=[];for(let manifestFile of manifestFiles)try{let fullPath=path294.isAbsolute(manifestFile)?manifestFile:path294.join(workingDir,manifestFile);if(!fs178.existsSync(fullPath))continue;let content=fs178.readFileSync(fullPath,"utf-8"),components=detectComponents(manifestFile,content);if(processedFiles.push(manifestFile),components.length>0)allComponents.push(...components)}catch{}if(processedFiles.length===0&&manifestFiles.length>0);ensureOutputDir(outputDir);let bom=generateCycloneDX(allComponents),bomJson=serializeCycloneDX(bom),filename=generateSbomFilename(),outputPath=path294.join(outputDir,filename);fs178.writeFileSync(outputPath,bomJson,"utf-8"),invalidateCachedArtifact(outputPath);let verdict=processedFiles.length>0?"pass":"pass";try{let timestamp=new Date().toISOString();await saveEvidence(workingDir,"sbom_generate",{task_id:"sbom_generate",type:"sbom",timestamp,agent:"sbom_generate",verdict,summary:`Generated SBOM with ${allComponents.length} component(s) from ${processedFiles.length} manifest file(s)`,components:allComponents.map((c)=>({name:c.name,version:c.version,type:c.type,purl:c.purl,license:c.license})),metadata:{timestamp,tool:"sbom_generate",tool_version:"6.9.0"},files:processedFiles,components_count:allComponents.length,output_path:outputPath})}catch(error93){log(`Warning: Failed to save SBOM evidence: ${error93 instanceof Error?error93.message:String(error93)}`)}let result={verdict,files:processedFiles,components_count:allComponents.length,output_path:outputPath};return JSON.stringify(result,null,2)}});init_zod();init_create_tool();import*as fs179 from"node:fs";import*as path295 from"node:path";var SPEC_CANDIDATES=["openapi.json","openapi.yaml","openapi.yml","swagger.json","swagger.yaml","swagger.yml","api/openapi.json","api/openapi.yaml","docs/openapi.json","docs/openapi.yaml","spec/openapi.json","spec/openapi.yaml"],SKIP_DIRS=["node_modules","dist","build",".git",".swarm","coverage","__tests__"],SKIP_EXTENSIONS=[".test.",".spec."],MAX_SPEC_SIZE=10485760,ALLOWED_EXTENSIONS=[".json",".yaml",".yml"];function normalizeApiPath(p){return p.replace(/\/$/,"").replace(/\{[^}]+\}/g,":param").replace(/:[a-zA-Z_][a-zA-Z0-9_]*/g,":param")}function discoverSpecFile(cwd,specFileArg){if(specFileArg){let resolvedPath=path295.resolve(cwd,specFileArg),normalizedCwd=cwd.endsWith(path295.sep)?cwd:cwd+path295.sep;if(!resolvedPath.startsWith(normalizedCwd)&&resolvedPath!==cwd)throw Error("Invalid spec_file: path traversal detected");let ext=path295.extname(resolvedPath).toLowerCase();if(!ALLOWED_EXTENSIONS.includes(ext))throw Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);if(fs179.statSync(resolvedPath).size>MAX_SPEC_SIZE)throw Error(`Invalid spec_file: file exceeds ${MAX_SPEC_SIZE/1024/1024}MB limit`);if(!fs179.existsSync(resolvedPath))throw Error(`Spec file not found: ${resolvedPath}`);return resolvedPath}for(let candidate2 of SPEC_CANDIDATES){let candidatePath=path295.resolve(cwd,candidate2);if(fs179.existsSync(candidatePath)){if(fs179.statSync(candidatePath).size<=MAX_SPEC_SIZE)return candidatePath}}return null}function parseSpec(specFile){let content=fs179.readFileSync(specFile,"utf-8");if(path295.extname(specFile).toLowerCase()===".json")return parseJsonSpec(content);return parseYamlSpec(content)}function parseJsonSpec(content){let spec;try{spec=JSON.parse(content)}catch{return[]}let paths=[];if(!spec.paths)return paths;for(let[pathKey2,pathValue]of Object.entries(spec.paths)){let methods=[];if(typeof pathValue==="object"&&pathValue!==null){for(let method of["get","post","put","patch","delete","options","head"])if(method in pathValue)methods.push(method)}if(methods.length>0)paths.push({path:pathKey2,methods})}return paths}function parseYamlSpec(content){let paths=[];if(!content.match(/^paths:\s*$/m))return paths;let pathRegex=/^\s{2}(\/[^\s:]+):/gm;for(let match=pathRegex.exec(content);match!==null;match=pathRegex.exec(content)){let pathKey2=match[1],methodRegex=/^\s{4}(get|post|put|patch|delete|options|head):/gm,methods=[],pathStart=match.index,nextPathMatch=content.substring(pathStart+1).match(/^\s{2}\//m),pathEnd=nextPathMatch&&nextPathMatch.index!==void 0?pathStart+1+nextPathMatch.index:content.length,pathSection=content.substring(pathStart,pathEnd),methodMatch=methodRegex.exec(pathSection);while(methodMatch!==null)methods.push(methodMatch[1]),methodMatch=methodRegex.exec(pathSection);if(methods.length>0)paths.push({path:pathKey2,methods})}return paths}function extractRoutes2(cwd){let routes=[];function walkDir2(dir){let entries;try{entries=fs179.readdirSync(dir,{withFileTypes:!0})}catch{return}for(let entry of entries){let fullPath=path295.join(dir,entry.name);if(entry.isSymbolicLink())continue;if(entry.isDirectory()){if(SKIP_DIRS.includes(entry.name))continue;walkDir2(fullPath)}else if(entry.isFile()){let ext=path295.extname(entry.name).toLowerCase(),baseName=entry.name.toLowerCase();if(![".ts",".js",".mjs"].includes(ext))continue;if(SKIP_EXTENSIONS.some((skip)=>baseName.includes(skip)))continue;let fileRoutes=extractRoutesFromFile(fullPath);routes.push(...fileRoutes)}}}return walkDir2(cwd),routes}function extractRoutesFromFile(filePath){let routes=[],lines=fs179.readFileSync(filePath,"utf-8").split(/\r?\n/),expressRegex=/(?:app|router|server|express)\.(get|post|put|patch|delete|options|head)\s*\(\s*['"`]([^'"`]+)['"`]/g,flaskRegex=/@(?:app|blueprint|bp)\.route\s*\(\s*['"]([^'"]+)['"]/g;for(let lineNum=0;lineNum<lines.length;lineNum++){let line=lines[lineNum],match=expressRegex.exec(line);expressRegex.lastIndex=0,flaskRegex.lastIndex=0;while(match!==null){let method=match[1].toLowerCase(),routePath=match[2];routes.push({path:routePath,method,file:filePath,line:lineNum+1}),match=expressRegex.exec(line)}match=flaskRegex.exec(line);while(match!==null){let routePath=match[1];routes.push({path:routePath,method:"get",file:filePath,line:lineNum+1}),match=flaskRegex.exec(line)}}return routes}function findDrift(specPaths,codeRoutes){let specPathMap=new Map;for(let sp of specPaths){let normalized=normalizeApiPath(sp.path);if(!specPathMap.has(normalized))specPathMap.set(normalized,[]);specPathMap.get(normalized).push(...sp.methods)}let codeRouteMap=new Map;for(let cr of codeRoutes){let normalized=normalizeApiPath(cr.path);if(!codeRouteMap.has(normalized))codeRouteMap.set(normalized,[]);codeRouteMap.get(normalized).push(cr)}let undocumented=[];for(let[normalized,routes]of codeRouteMap)if(!specPathMap.has(normalized))for(let route of routes)undocumented.push({path:route.path,method:route.method,file:route.file,line:route.line});let phantom=[];for(let[normalized,methods]of specPathMap)if(!codeRouteMap.has(normalized))phantom.push({path:specPaths.find((sp)=>normalizeApiPath(sp.path)===normalized).path,methods});return{undocumented,phantom}}var schema_drift=createSwarmTool({description:"Compare OpenAPI spec against actual route implementations to find drift. Detects undocumented routes in code and phantom routes in spec.",args:{spec_file:exports_external.string().optional().describe("Path to OpenAPI spec file. Auto-detected if omitted. Checks: openapi.json/yaml/yml, swagger.json/yaml/yml, api/openapi.json/yaml, docs/openapi.json/yaml, spec/openapi.json/yaml")},async execute(args2,directory){let cwd=directory;if(args2!==null&&typeof args2!=="object")return JSON.stringify({...{specFile:"",specPathCount:0,codeRouteCount:0,undocumented:[],phantom:[],undocumentedCount:0,phantomCount:0,consistent:!1},error:"Invalid arguments"},null,2);let argsObj=args2;try{let specFile=discoverSpecFile(cwd,argsObj.spec_file);if(!specFile)return JSON.stringify({...{specFile:"",specPathCount:0,codeRouteCount:0,undocumented:[],phantom:[],undocumentedCount:0,phantomCount:0,consistent:!1},error:"No OpenAPI spec file found. Provide spec_file or place spec in one of: openapi.json/yaml/yml, swagger.json/yaml/yml, api/openapi.json/yaml, docs/openapi.json/yaml, spec/openapi.json/yaml"},null,2);let specPaths=parseSpec(specFile),codeRoutes=extractRoutes2(cwd),{undocumented,phantom}=findDrift(specPaths,codeRoutes),result={specFile,specPathCount:specPaths.length,codeRouteCount:codeRoutes.length,undocumented,phantom,undocumentedCount:undocumented.length,phantomCount:phantom.length,consistent:undocumented.length===0&&phantom.length===0};return JSON.stringify(result,null,2)}catch(error93){let errorMessage3=error93 instanceof Error?error93.message:"Unknown error";return JSON.stringify({...{specFile:"",specPathCount:0,codeRouteCount:0,undocumented:[],phantom:[],undocumentedCount:0,phantomCount:0,consistent:!1},error:errorMessage3},null,2)}}});init_zod();init_external_tool_runner();init_path_security();init_create_tool();import*as fs180 from"node:fs";import{createRequire as createRequire6}from"node:module";import*as path296 from"node:path";var require2=createRequire6(import.meta.url),DEFAULT_MAX_RESULTS4=100,DEFAULT_MAX_LINES=200,REGEX_TIMEOUT_MS=5000,MAX_FILE_SIZE_BYTES9=1048576,HARD_CAP_RESULTS4=1e4,HARD_CAP_LINES=1e4,MAX_QUERY_LENGTH=20000,MAX_INCLUDE_PATTERNS=100,MAX_RG_STDOUT_BYTES=8388608,MAX_RG_STDERR_BYTES=65536,FALLBACK_MAX_FILES=20000,FALLBACK_MAX_DIRS=5000,FALLBACK_MAX_DEPTH=40,FALLBACK_MAX_TOTAL_BYTES=67108864,DEFAULT_SKIP_DIRS=new Set([".git",".swarm","node_modules","dist","build","out","coverage",".next",".turbo",".cache"]);function globMatch(pattern,filePath){let normalizedPattern=pattern.replace(/\\/g,"/"),normalizedPath2=filePath.replace(/\\/g,"/"),regexPattern=normalizedPattern.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*\*/g,"{{DOUBLESTAR}}").replace(/\*/g,"[^/]*").replace(/\?/g,".").replace(/\{\{DOUBLESTAR\}\}/g,".*");try{return new RegExp(`^${regexPattern}$`).test(normalizedPath2)}catch{return!1}}function matchesGlobs(filePath,globs){if(globs.length===0)return!0;return globs.some((glob)=>globMatch(glob,filePath))}var WINDOWS_RESERVED_NAMES5=/^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;function containsWindowsAttacks4(str){if(/:[^\\/]/.test(str))return!0;let parts=str.split(/[/\\]/);for(let part of parts)if(WINDOWS_RESERVED_NAMES5.test(part))return!0;return!1}function resolveWithinWorkspace(filePath,workspace){try{let resolvedPath=path296.resolve(workspace,filePath),realWorkspace=fs180.realpathSync(workspace),realResolvedPath=fs180.realpathSync(resolvedPath),relativePath2=path296.relative(realWorkspace,realResolvedPath);if(relativePath2.startsWith("..")||path296.isAbsolute(relativePath2))return null;return relativePath2}catch{return null}}function isPathInWorkspace3(filePath,workspace){return resolveWithinWorkspace(filePath,workspace)!==null}function validatePathForRead2(filePath,workspace){return isPathInWorkspace3(filePath,workspace)}function splitGlobPatterns2(value){return value?value.split(",").map((p)=>p.trim()).filter(Boolean):[]}var GLOB_METACHARACTERS=/[*?[\]{}]/;function isExactPath(pattern){return!GLOB_METACHARACTERS.test(pattern)}function targetsDotDirectory(pattern){let firstSegment=pattern.split(/[\\/]/)[0];return!!firstSegment&&firstSegment.startsWith(".")&&firstSegment!=="."&&firstSegment!==".."}function hasGitSegment(resolvedRelativePath){return resolvedRelativePath.split(/[\\/]/).some((segment)=>segment.toLowerCase()===".git")}function toWorkspaceRelativePath2(filePath,workspace){try{let resolved=path296.resolve(workspace,filePath),realWorkspace=fs180.realpathSync(workspace),realResolved=fs180.realpathSync(resolved),relative73=path296.relative(realWorkspace,realResolved);if(!relative73||relative73.startsWith("..")||path296.isAbsolute(relative73))return null;return relative73.split(path296.sep).join("/")}catch{return null}}function truncateLine(line,maxLines){let trimmed=line.trimEnd();if(trimmed.length>maxLines)return`${trimmed.substring(0,maxLines)}...`;return trimmed}function resolvePackagedRipgrep(){try{let mod=require2("@vscode/ripgrep");return typeof mod.rgPath==="string"&&mod.rgPath?mod.rgPath:null}catch{return null}}function resolveRipgrepBinary(){return _internals219.resolvePackagedRipgrep()??_internals219.resolveExecutableFromPath(["rg"])}async function ripgrepSearch(opts){let rgPath=_internals219.resolveRipgrepBinary();if(!rgPath)return{error:!0,type:"rg-not-found",message:"ripgrep (rg) not found; using fallback search was not possible"};let args2=["--json","--no-config","-n"],includes=splitGlobPatterns2(opts.include),promotablePaths=[],globIncludes=[];for(let pattern of includes){let resolvedRelative=resolveWithinWorkspace(pattern,opts.workspace);if(isExactPath(pattern)&&targetsDotDirectory(pattern)&&pattern.split(/[\\/]/)[0]?.toLowerCase()!==".git"&&resolvedRelative!==null&&!hasGitSegment(resolvedRelative))promotablePaths.push(pattern);else globIncludes.push(pattern)}let pathOperands;if(promotablePaths.length>0&&globIncludes.length===0)pathOperands=promotablePaths;else{for(let pattern of[...globIncludes,...promotablePaths])args2.push("--glob",pattern);if(includes.some((p)=>targetsDotDirectory(p)&&p.split(/[\\/]/)[0]?.toLowerCase()!==".git"))args2.push("--hidden","--no-ignore"),args2.push("--glob","!.git");pathOperands=["."]}for(let pattern of splitGlobPatterns2(opts.exclude))args2.push("--glob",`!${pattern}`);if(opts.mode!=="regex")args2.push("--fixed-strings");args2.push("--",opts.query,...pathOperands);let run=await _internals219.runExternalTool({executable:rgPath,args:args2,cwd:opts.workspace,timeoutMs:REGEX_TIMEOUT_MS,maxStdoutBytes:MAX_RG_STDOUT_BYTES,maxStderrBytes:MAX_RG_STDERR_BYTES});try{if(run.status==="timeout")return{error:!0,type:"regex-timeout",message:`Search timed out after ${REGEX_TIMEOUT_MS}ms`};if(run.status==="spawn-error")return{error:!0,type:"unknown",message:run.message??"ripgrep failed to start"};if(run.exitCode!==0&&run.stderr){if(run.stderr.includes("Invalid regex")||run.stderr.includes("regex parse error")||run.stderr.includes("SyntaxError"))return{error:!0,type:"invalid-query",message:`Invalid query: ${run.stderr.split(`
6642
+ `)[0]}`};if(run.exitCode===2)return{error:!0,type:"unknown",message:`ripgrep error: ${run.stderr.split(`
6635
6643
  `)[0]}`}}let matches=[],total=0;for(let line of run.stdout.split(`
6636
- `)){if(!line.trim())continue;try{let entry=JSON.parse(line);if(entry.type==="match"){let rawPath=entry.data?.path?.text??entry.data?.path,relativePath2=typeof rawPath==="string"?toWorkspaceRelativePath2(rawPath,opts.workspace):null;if(!relativePath2)continue;if(total++,matches.length<opts.maxResults){let match={file:relativePath2,lineNumber:entry.data.line_number,lineText:truncateLine(entry.data.lines.text,opts.maxLines)};matches.push(match)}}}catch{}}return{matches,truncated:total>opts.maxResults||run.stdoutTruncated||run.stderrTruncated,total,query:opts.query,mode:opts.mode,maxResults:opts.maxResults,engine:"ripgrep",outputTruncated:run.stdoutTruncated||run.stderrTruncated}}catch(err2){return{error:!0,type:"unknown",message:err2 instanceof Error?err2.message:String(err2)}}}function escapeRegex4(str){return str.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function collectFiles(dir,workspace,includeGlobs,excludeGlobs,state,depth=0){if(depth>FALLBACK_MAX_DEPTH||state.files.length>=FALLBACK_MAX_FILES||state.dirCount>=FALLBACK_MAX_DIRS)return state.truncated=!0,state.files;try{let realDir=fs180.realpathSync(dir);if(state.seenRealPaths.has(realDir))return state.files;state.seenRealPaths.add(realDir),state.dirCount++}catch{return state.files}if(!validatePathForRead2(dir,workspace))return state.files;try{let entries=fs180.readdirSync(dir,{withFileTypes:!0});for(let entry of entries){if(state.files.length>=FALLBACK_MAX_FILES||state.dirCount>=FALLBACK_MAX_DIRS){state.truncated=!0;break}let fullPath=path296.join(dir,entry.name),relativePath2=path296.relative(workspace,fullPath);if(!validatePathForRead2(fullPath,workspace))continue;if(entry.isDirectory()){if(DEFAULT_SKIP_DIRS.has(entry.name))continue;collectFiles(fullPath,workspace,includeGlobs,excludeGlobs,state,depth+1)}else if(entry.isFile()){if(includeGlobs.length>0&&!matchesGlobs(relativePath2,includeGlobs))continue;if(excludeGlobs.length>0&&matchesGlobs(relativePath2,excludeGlobs))continue;let normalized=toWorkspaceRelativePath2(fullPath,workspace);if(!normalized)continue;state.files.push(normalized)}}}catch{}return state.files}async function fallbackSearch(opts){let includeGlobs=opts.include?opts.include.split(",").map((p)=>p.trim()).filter(Boolean):[],excludeGlobs=opts.exclude?opts.exclude.split(",").map((p)=>p.trim()).filter(Boolean):[],collectState={files:[],seenRealPaths:new Set,dirCount:0,truncated:!1},files=collectFiles(opts.workspace,opts.workspace,includeGlobs,excludeGlobs,collectState),regex;try{if(opts.mode==="regex")regex=new RegExp(opts.query);else regex=new RegExp(escapeRegex4(opts.query))}catch(err2){return{error:!0,type:"invalid-query",message:err2 instanceof Error?err2.message:"Invalid regex pattern"}}let matches=[],total=0,totalBytesRead=0,truncated=collectState.truncated;for(let file3 of files){let fullPath=path296.join(opts.workspace,file3);if(!validatePathForRead2(fullPath,opts.workspace))continue;let stats2;try{if(stats2=fs180.statSync(fullPath),stats2.size>MAX_FILE_SIZE_BYTES9)continue;if(totalBytesRead+stats2.size>FALLBACK_MAX_TOTAL_BYTES){truncated=!0;break}totalBytesRead+=stats2.size}catch{continue}let content;try{content=fs180.readFileSync(fullPath,"utf-8")}catch{continue}let lines=content.split(`
6637
- `);for(let i=0;i<lines.length;i++){let line=lines[i];if(regex.test(line)){if(total++,matches.length<opts.maxResults)matches.push({file:file3,lineNumber:i+1,lineText:truncateLine(line,opts.maxLines)});regex.lastIndex=0}}}return{matches,truncated:truncated||total>opts.maxResults,total,query:opts.query,mode:opts.mode,maxResults:opts.maxResults,engine:"fallback",warning:"Fallback search uses bounded filesystem traversal and does not fully emulate ripgrep gitignore behavior."}}var search=createSwarmTool({description:"Search for text within workspace files using ripgrep-style interface. Supports literal and regex search modes with glob include/exclude filtering. Returns structured JSON output with file paths, line numbers, and line content.",args:{query:exports_external.string().describe("Search query string (literal or regex depending on mode)"),mode:exports_external.enum(["literal","regex"]).default("literal").describe("Search mode: literal for exact string match, regex for regular expression"),include:exports_external.string().optional().describe('Glob pattern for files to include (e.g., "*.ts", "src/**/*.js")'),exclude:exports_external.string().optional().describe('Glob pattern for files to exclude (e.g., "node_modules/**", "*.test.ts")'),max_results:exports_external.number().default(DEFAULT_MAX_RESULTS4).describe("Maximum number of matches to return"),max_lines:exports_external.number().default(DEFAULT_MAX_LINES).describe("Maximum characters per line in results")},execute:async(args2,directory)=>{let query,mode="literal",include,exclude,maxResults=DEFAULT_MAX_RESULTS4,maxLines=DEFAULT_MAX_LINES;try{let obj=args2;query=String(obj.query??""),mode=obj.mode==="regex"?"regex":"literal",include=typeof obj.include==="string"?obj.include:void 0,exclude=typeof obj.exclude==="string"?obj.exclude:void 0;let rawMaxResults=typeof obj.max_results==="number"?obj.max_results:DEFAULT_MAX_RESULTS4,sanitizedMaxResults=Number.isNaN(rawMaxResults)?DEFAULT_MAX_RESULTS4:rawMaxResults;maxResults=Math.min(Math.max(0,sanitizedMaxResults),HARD_CAP_RESULTS4);let rawMaxLines=typeof obj.max_lines==="number"?obj.max_lines:DEFAULT_MAX_LINES,sanitizedMaxLines=Number.isNaN(rawMaxLines)?DEFAULT_MAX_LINES:rawMaxLines;maxLines=Math.min(Math.max(0,sanitizedMaxLines),HARD_CAP_LINES)}catch{return JSON.stringify({error:!0,type:"invalid-query",message:"Could not parse search arguments"},null,2)}if(!query||query.trim()==="")return JSON.stringify({error:!0,type:"invalid-query",message:"Query cannot be empty"},null,2);if(query.length>MAX_QUERY_LENGTH)return JSON.stringify({error:!0,type:"invalid-query",message:`Query exceeds maximum length of ${MAX_QUERY_LENGTH} characters`},null,2);if(containsControlChars(query))return JSON.stringify({error:!0,type:"invalid-query",message:"Query contains invalid control characters"},null,2);if(include&&containsPathTraversal(include))return JSON.stringify({error:!0,type:"path-escape",message:"Include pattern contains path traversal sequence"},null,2);if(exclude&&containsPathTraversal(exclude))return JSON.stringify({error:!0,type:"path-escape",message:"Exclude pattern contains path traversal sequence"},null,2);if(include&&containsWindowsAttacks4(include))return JSON.stringify({error:!0,type:"path-escape",message:"Include pattern contains invalid Windows-specific sequence"},null,2);if(exclude&&containsWindowsAttacks4(exclude))return JSON.stringify({error:!0,type:"path-escape",message:"Exclude pattern contains invalid Windows-specific sequence"},null,2);if(!fs180.existsSync(directory))return JSON.stringify({error:!0,type:"unknown",message:"Workspace directory does not exist"},null,2);let result;if(_internals219.resolveRipgrepBinary())result=await ripgrepSearch({query,mode,include,exclude,maxResults,maxLines,workspace:directory});else result=await fallbackSearch({query,mode,include,exclude,maxResults,maxLines,workspace:directory});if("error"in result&&result.error)return JSON.stringify(result,null,2);return JSON.stringify(result,null,2)}}),_internals219={resolvePackagedRipgrep,resolveExecutableFromPath,resolveRipgrepBinary,runExternalTool,fallbackSearch};init_secretscan();init_zod();init_qa_gate_profile();init_manager();init_create_tool();var _internals220={setGatesForIdentity};async function executeSetQaGates(args2,directory){let plan=await loadPlanJsonOnly(directory),identity=resolveQaGatePlanIdentity(plan,args2);if(!identity.success)return{success:!1,reason:identity.reason,message:identity.message};let planId=identity.planId,currentPlanMatchesIdentity=plan?.swarm===identity.identity.swarm&&plan?.title===identity.identity.title,partial3={},gateKeys=["reviewer","test_engineer","council_mode","sme_enabled","critic_pre_plan","hallucination_guard","sast_enabled","mutation_test","phase_council","drift_check","final_council"];for(let key of gateKeys)if(args2[key]!==void 0)partial3[key]=args2[key];let bindingOnlyRequested=args2.adopt_legacy_binding_only===!0,hasGatePatch=Object.keys(partial3).length>0;if(bindingOnlyRequested&&(hasGatePatch||args2.project_type!==void 0))return{success:!1,reason:"binding_only_patch_conflict",message:"adopt_legacy_binding_only performs exact-binding recovery only. Omit all gate booleans and project_type when using it."};if(bindingOnlyRequested&&!currentPlanMatchesIdentity)return{success:!1,reason:"adopt_legacy_requires_current_plan",message:"adopt_legacy_binding_only may only target the exact current persisted plan identity. Re-run it from the active plan without replacing swarm_id or plan_title."};if(bindingOnlyRequested){let lookup=getProfileLookupForIdentity(directory,identity.identity);if(lookup.kind==="missing")return{success:!1,reason:"no_profile",plan_id:planId,message:"No legacy QA gate profile row exists for this exact current plan identity, so there is nothing to adopt."};if(lookup.kind==="bound")return{success:!0,plan_id:planId,message:`QA gate profile is already exact-bound for plan_id=${planId}; no gates or lock state changed.`,profile:{plan_id:lookup.profile.plan_id,gates:{...lookup.profile.gates},locked_at:lookup.profile.locked_at,locked_by_snapshot_seq:lookup.profile.locked_by_snapshot_seq,profile_hash:computeProfileHash(lookup.profile)}}}try{let updated=_internals220.setGatesForIdentity(directory,identity.identity,partial3,{projectType:args2.project_type,allowLegacyAdoption:currentPlanMatchesIdentity,allowLegacyCollisionCreate:!currentPlanMatchesIdentity,legacyAdoptionIdentity:plan?{swarm:plan.swarm,title:plan.title}:void 0});return{success:!0,plan_id:planId,message:bindingOnlyRequested?`Legacy QA gate profile exact-bound for plan_id=${planId} without changing gates or lock state.`:`QA gates updated for plan_id=${planId}`,profile:{plan_id:updated.plan_id,gates:{...updated.gates},locked_at:updated.locked_at,locked_by_snapshot_seq:updated.locked_by_snapshot_seq,profile_hash:computeProfileHash(updated)}}}catch(err2){let msg=err2 instanceof Error?err2.message:String(err2),lower=msg.toLowerCase(),reason="set_gates_failed";if(err2 instanceof QaGateProfileIdentityUnboundError)reason="plan_identity_unbound";if(lower.includes("locked"))reason="profile_locked";else if(lower.includes("ratchet"))reason="ratchet_violation";else if(bindingOnlyRequested)reason="binding_only_failed";return{success:!1,reason,message:err2 instanceof QaGateProfileIdentityUnboundError?`${msg} ${formatLegacyQaBindingOnlyCall(identity.identity)} is the only supported adoption path for locked or upgraded legacy rows.`:msg,plan_id:planId}}}var set_qa_gates=createSwarmTool({allowWorkingDirectoryOverride:!0,description:"Configure the QA gate profile for the current or exact future plan. Architect-only. The initial selection accepts explicit true and false values; later calls can enable additional gates but cannot disable enabled gates. Rejects writes once locked (after critic approval). Creates the initial profile atomically from defaults plus the explicit selection. Uses plan.json identity by default, or exact swarm_id + plan_title before a plan exists.",args:{swarm_id:exports_external.string().refine((value)=>value.trim().length>0,"Must not be blank").optional().describe("Exact swarm identity for pre-plan QA selection. Must be provided with plan_title."),plan_title:exports_external.string().refine((value)=>value.trim().length>0,"Must not be blank").optional().describe("Exact future plan title for pre-plan QA selection. Must be provided with swarm_id."),confirm_identity_change:exports_external.boolean().optional().describe("Confirm that an explicit swarm_id/plan_title pair intentionally replaces the current plan identity."),reviewer:exports_external.boolean().optional().describe("Select the reviewer gate; later calls cannot turn it off once enabled."),test_engineer:exports_external.boolean().optional().describe("Enable the test_engineer gate (true) — cannot be disabled once on."),council_mode:exports_external.boolean().optional().describe("Enable council mode — replaces per-task Stage B (reviewer + test_engineer) with the full 5-member council (critic, reviewer, sme, test_engineer, explorer) per task."),sme_enabled:exports_external.boolean().optional().describe("Enable SME consultation."),critic_pre_plan:exports_external.boolean().optional().describe("Enable critic_pre_plan review before plan approval."),hallucination_guard:exports_external.boolean().optional().describe("Enable hallucination_guard checks on plan and implementation claims."),sast_enabled:exports_external.boolean().optional().describe("Enable SAST scanning as a required QA gate."),mutation_test:exports_external.boolean().optional().describe("Enable the mutation-testing gate (default: off). Requires mutation tests to achieve a passing kill rate before phase completion; WARN verdict allows advancement, FAIL blocks."),phase_council:exports_external.boolean().optional().describe("Enable the phase_council gate (default: off). When on, a full 5-member council (critic, reviewer, sme, test_engineer, explorer) reviews all work completed in a phase holistically at phase_complete time. Requires council.enabled: true in config."),drift_check:exports_external.boolean().optional().describe("Enable drift verification gate (default: on). Blocks phase_complete until drift-verifier.json has an approved verdict. When disabled, drift verification is skipped entirely."),final_council:exports_external.boolean().optional().describe("Enable the final_council gate (default: off). When on, after all phases complete the architect dispatches critic, reviewer, sme, test_engineer, and explorer with project-scoped context, collects their CouncilMemberVerdict objects, and calls write_final_council_evidence. This is not General Council mode and does not require council.general.enabled."),project_type:exports_external.string().optional().describe('Project type label (e.g. "ts", "python"). Only applied when the profile is being created for the first time.'),adopt_legacy_binding_only:exports_external.boolean().optional().describe("Operational recovery for upgraded legacy rows. When true, exact-binds the existing current-plan QA profile without changing any gates or its lock. Omit all gate booleans and project_type when using this action.")},execute:async(args2,directory)=>{return JSON.stringify(await executeSetQaGates(args2??{},directory),null,2)}});init_zod();init_skill_generator();init_create_tool();var skill_apply=createSwarmTool({description:"Activate a draft skill proposal (.swarm/skills/proposals/<slug>.md) into .opencode/skills/generated/<slug>/SKILL.md.",args:{slug:exports_external.string().min(1).describe("Slug of the proposal to activate."),force:exports_external.boolean().optional().default(!1).describe("Overwrite an existing active SKILL.md even if it lacks the generator stamp. Default false."),evaluate:exports_external.boolean().optional().default(!1).describe("Validate the proposal against .swarm/skills/evals/<slug> before activation. Default false."),confirm_unevaluated:exports_external.boolean().optional().default(!1).describe('Allow activation when evaluateSkillChange returns status "unevaluated" (no eval set exists). Default false — the activation is blocked with a surfaced reason so the caller can confirm. Generated skills auto-derive an eval stub from their source directives, so this only applies to non-directive skills with no stub.')},execute:async(args2,directory)=>{let a=args2??{};if(!a.slug||typeof a.slug!=="string")return JSON.stringify({activated:!1,reason:"slug required"});let result=await activateProposal(directory,a.slug,a.force??!1,{evaluate:a.evaluate??!1,confirmUnevaluated:a.confirm_unevaluated??!1});return JSON.stringify(result,null,2)}});init_zod();init_skill_generator();init_create_tool();var skill_generate=createSwarmTool({description:'Compile mature knowledge entries into a SKILL.md. mode="draft" writes a proposal under .swarm/skills/proposals; mode="active" writes the live skill under .opencode/skills/generated and stamps source entries.',args:{source_knowledge_ids:exports_external.array(exports_external.string()).optional().describe("Optional explicit knowledge ids to compile. If omitted, all mature candidates are clustered and emitted."),slug:exports_external.string().optional().describe("Optional slug for the FIRST cluster. Sanitized; rejected if invalid."),mode:exports_external.enum(["draft","active"]).default("draft"),force:exports_external.boolean().optional().default(!1),evaluate:exports_external.boolean().optional().default(!1).describe("Validate generated skill content against .swarm/skills/evals/<slug> before writing. Default false."),min_confidence:exports_external.number().min(0).max(1).optional(),min_confirmations:exports_external.number().int().min(1).max(50).optional()},execute:async(args2,directory)=>{let a=args2??{},result=await generateSkills({directory,mode:a.mode??"draft",slug:a.slug,sourceKnowledgeIds:a.source_knowledge_ids,force:a.force??!1,evaluate:a.evaluate??!1,minConfidence:a.min_confidence,minConfirmations:a.min_confirmations});return JSON.stringify(result,null,2)}});init_zod();init_config();init_schema();init_skill_improver();init_create_tool();var skill_improve=createSwarmTool({description:'Run the skill_improver capability under daily quota. Writes a proposal under .swarm/skill-improver/proposals/<timestamp>.md. With mode="draft_skills" it also drafts SKILL.md proposals for mature clusters. Quota is enforced via .swarm/skill-improver-quota.json.',args:{targets:exports_external.array(exports_external.enum(["skills","spec","architect_prompt","knowledge"])).optional(),mode:exports_external.enum(["proposal","draft_skills"]).optional(),max_calls:exports_external.number().int().min(1).max(100).optional().describe("Override the per-run reservation count (capped by daily max)."),evaluate:exports_external.boolean().optional().default(!1).describe('When mode="draft_skills", validate generated draft skills before writing proposals. Default false.')},execute:async(args2,directory,ctx)=>{let a=args2??{},{config:config3}=loadPluginConfigWithMeta(directory),parsed=SkillImproverConfigSchema.parse(config3.skill_improver??{}),enrichmentConfig=KnowledgeConfigSchema.parse(config3.knowledge??{}).enrichment??{max_calls_per_day:30,quota_window:"utc"};if(!parsed.enabled)return JSON.stringify({ran:!1,reason:'skill_improver is disabled. Set "skill_improver.enabled": true in opencode-swarm config to use this tool.'},null,2);let result=await runSkillImprover({directory,config:parsed,targets:a.targets,mode:a.mode,maxCalls:a.max_calls,sessionId:ctx?.sessionID,enrichmentQuota:{maxCalls:enrichmentConfig.max_calls_per_day,window:enrichmentConfig.quota_window},evaluateDrafts:a.evaluate??!1});return JSON.stringify(result,null,2)}});init_zod();init_skill_generator();init_create_tool();var skill_inspect=createSwarmTool({description:"Read a generated skill (active or draft) and return its full markdown body and metadata.",args:{slug:exports_external.string().min(1).describe("Slug of the skill to inspect."),prefer:exports_external.enum(["auto","proposal","active"]).optional().default("auto")},execute:async(args2,directory)=>{let a=args2??{};if(!a.slug||typeof a.slug!=="string")return JSON.stringify({found:!1,reason:"slug required"});let result=await inspectSkill(directory,a.slug,a.prefer??"auto");return JSON.stringify(result,null,2)}});init_skill_generator();init_create_tool();var skill_list=createSwarmTool({description:"List generated skill drafts (under .swarm/skills/proposals) and active generated skills (under .opencode/skills/generated).",args:{},execute:async(_args,directory)=>{let result=await listSkills(directory);return JSON.stringify(result,null,2)}});init_zod();init_skill_generator();init_create_tool();var skill_regenerate=createSwarmTool({description:"Regenerate an active skill by re-clustering its source knowledge entries and updating the SKILL.md in place.",args:{slug:exports_external.string().min(1).describe("Slug of the active skill to regenerate."),evaluate:exports_external.boolean().optional().default(!1).describe("Validate regenerated content against .swarm/skills/evals/<slug> before writing. Default false.")},execute:async(args2,directory)=>{let a=args2??{};if(!a.slug||typeof a.slug!=="string")return JSON.stringify({regenerated:!1,reason:"slug required"});let result=await regenerateSkill(directory,a.slug,{evaluate:a.evaluate??!1});return JSON.stringify(result,null,2)}});init_zod();init_skill_generator();init_create_tool();var skill_retire=createSwarmTool({description:"Retire a generated skill by adding a retired.marker file. Retired skills are excluded from scoring and injection.",args:{slug:exports_external.string().min(1).describe("Slug of the active skill to retire."),reason:exports_external.string().optional().describe("Optional reason for retirement.")},execute:async(args2,directory)=>{let a=args2??{};if(!a.slug||typeof a.slug!=="string")return JSON.stringify({retired:!1,reason:"slug required"});let result=await retireSkill(directory,a.slug,a.reason);return JSON.stringify(result,null,2)}});init_zod();init_config();init_schema();init_file_locks();init_spec_drift_recovery();init_create_tool();import{mkdir as mkdir55,rename as rename22,writeFile as writeFile31}from"node:fs/promises";import*as path297 from"node:path";var MAX_SPEC_BYTES2=262144,spec_write=createSwarmTool({description:"Write the canonical project spec to .swarm/spec.md. Atomic write, size-bounded (256 KiB), heading-required. Honors spec_writer.allow_spec_write.",args:{content:exports_external.string().min(20).max(MAX_SPEC_BYTES2),mode:exports_external.enum(["replace","append"]).optional().default("replace")},execute:async(args2,directory)=>{let a=args2??{},content=a.content,mode=a.mode??"replace";if(typeof content!=="string"||content.length<20)return JSON.stringify({written:!1,reason:"content must be a string >=20 chars"});if(content.length>MAX_SPEC_BYTES2)return JSON.stringify({written:!1,reason:`content exceeds ${MAX_SPEC_BYTES2} bytes`});let{config:config3}=loadPluginConfigWithMeta(directory);if(!SpecWriterConfigSchema.parse(config3.spec_writer??{}).allow_spec_write)return JSON.stringify({written:!1,reason:"spec_writer.allow_spec_write is false"},null,2);if(content.indexOf("\x00")!==-1)return JSON.stringify({written:!1,reason:"content contains null byte"},null,2);if(!/^#\s+/m.test(content))return JSON.stringify({written:!1,reason:'spec must contain at least one top-level "# Heading"'},null,2);let specLock=await tryAcquireLock(directory,"spec.md","spec-write",`spec-write-${Date.now()}`);if(!specLock.acquired)return JSON.stringify({written:!1,reason:"another canonical spec write or drift recovery is in progress; retry shortly"},null,2);try{let target=path297.join(directory,".swarm","spec.md");await mkdir55(path297.dirname(target),{recursive:!0});let tmp=`${target}.tmp-${process.pid}-${Date.now()}`,finalContent=content;if(mode==="append")try{if(finalContent=`${(await(await import("node:fs/promises")).readFile(target,"utf-8")).replace(/\s+$/,"")}
6644
+ `)){if(!line.trim())continue;try{let entry=JSON.parse(line);if(entry.type==="match"){let rawPath=entry.data?.path?.text??entry.data?.path,relativePath2=typeof rawPath==="string"?toWorkspaceRelativePath2(rawPath,opts.workspace):null;if(!relativePath2)continue;if(total++,matches.length<opts.maxResults){let match={file:relativePath2,lineNumber:entry.data.line_number,lineText:truncateLine(entry.data.lines.text,opts.maxLines)};matches.push(match)}}}catch{}}return{matches,truncated:total>opts.maxResults||run.stdoutTruncated||run.stderrTruncated,total,query:opts.query,mode:opts.mode,maxResults:opts.maxResults,engine:"ripgrep",outputTruncated:run.stdoutTruncated||run.stderrTruncated}}catch(err2){return{error:!0,type:"unknown",message:err2 instanceof Error?err2.message:String(err2)}}}function escapeRegex4(str){return str.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function collectFiles(dir,workspace,includeGlobs,excludeGlobs,state,depth=0){if(depth>FALLBACK_MAX_DEPTH||state.files.length>=FALLBACK_MAX_FILES||state.dirCount>=FALLBACK_MAX_DIRS)return state.truncated=!0,state.files;try{let realDir=fs180.realpathSync(dir);if(state.seenRealPaths.has(realDir))return state.files;state.seenRealPaths.add(realDir),state.dirCount++}catch{return state.files}if(!validatePathForRead2(dir,workspace))return state.files;try{let entries=fs180.readdirSync(dir,{withFileTypes:!0});for(let entry of entries){if(state.files.length>=FALLBACK_MAX_FILES||state.dirCount>=FALLBACK_MAX_DIRS){state.truncated=!0;break}let fullPath=path296.join(dir,entry.name),relativePath2=path296.relative(workspace,fullPath);if(!validatePathForRead2(fullPath,workspace))continue;if(entry.isDirectory()){if(entry.name.toLowerCase()===".git"||DEFAULT_SKIP_DIRS.has(entry.name)&&!includeGlobs.some((g)=>g.split(/[\\/]/)[0]===entry.name))continue;collectFiles(fullPath,workspace,includeGlobs,excludeGlobs,state,depth+1)}else if(entry.isFile()){if(includeGlobs.length>0&&!matchesGlobs(relativePath2,includeGlobs))continue;if(excludeGlobs.length>0&&matchesGlobs(relativePath2,excludeGlobs))continue;let normalized=toWorkspaceRelativePath2(fullPath,workspace);if(!normalized)continue;state.files.push(normalized)}}}catch{}return state.files}async function fallbackSearch(opts){let includeGlobs=opts.include?opts.include.split(",").map((p)=>p.trim()).filter(Boolean):[],excludeGlobs=opts.exclude?opts.exclude.split(",").map((p)=>p.trim()).filter(Boolean):[],collectState={files:[],seenRealPaths:new Set,dirCount:0,truncated:!1},files=collectFiles(opts.workspace,opts.workspace,includeGlobs,excludeGlobs,collectState),regex;try{if(opts.mode==="regex")regex=new RegExp(opts.query);else regex=new RegExp(escapeRegex4(opts.query))}catch(err2){return{error:!0,type:"invalid-query",message:err2 instanceof Error?err2.message:"Invalid regex pattern"}}let matches=[],total=0,totalBytesRead=0,truncated=collectState.truncated;for(let file3 of files){let fullPath=path296.join(opts.workspace,file3);if(!validatePathForRead2(fullPath,opts.workspace))continue;let stats2;try{if(stats2=fs180.statSync(fullPath),stats2.size>MAX_FILE_SIZE_BYTES9)continue;if(totalBytesRead+stats2.size>FALLBACK_MAX_TOTAL_BYTES){truncated=!0;break}totalBytesRead+=stats2.size}catch{continue}let content;try{content=fs180.readFileSync(fullPath,"utf-8")}catch{continue}let lines=content.split(`
6645
+ `);for(let i=0;i<lines.length;i++){let line=lines[i];if(regex.test(line)){if(total++,matches.length<opts.maxResults)matches.push({file:file3,lineNumber:i+1,lineText:truncateLine(line,opts.maxLines)});regex.lastIndex=0}}}return{matches,truncated:truncated||total>opts.maxResults,total,query:opts.query,mode:opts.mode,maxResults:opts.maxResults,engine:"fallback",warning:"Fallback search uses bounded filesystem traversal and does not fully emulate ripgrep gitignore behavior."}}var search=createSwarmTool({description:"Search for text within workspace files using ripgrep-style interface. Supports literal and regex search modes with glob include/exclude filtering. Returns structured JSON output with file paths, line numbers, and line content.",args:{query:exports_external.string().describe("Search query string (literal or regex depending on mode)"),mode:exports_external.enum(["literal","regex"]).default("literal").describe("Search mode: literal for exact string match, regex for regular expression"),include:exports_external.string().optional().describe('Glob pattern for files to include (e.g., "*.ts", "src/**/*.js"). An exact repo-relative path under a dot-directory (e.g., ".swarm/bundled-skills/<slug>/SKILL.md") is searched directly, bypassing hidden-directory and ignore filtering; .git content is never searchable.'),exclude:exports_external.string().optional().describe('Glob pattern for files to exclude (e.g., "node_modules/**", "*.test.ts")'),max_results:exports_external.number().default(DEFAULT_MAX_RESULTS4).describe("Maximum number of matches to return"),max_lines:exports_external.number().default(DEFAULT_MAX_LINES).describe("Maximum characters per line in results")},execute:async(args2,directory)=>{let query,mode="literal",include,exclude,maxResults=DEFAULT_MAX_RESULTS4,maxLines=DEFAULT_MAX_LINES;try{let obj=args2;query=String(obj.query??""),mode=obj.mode==="regex"?"regex":"literal",include=typeof obj.include==="string"?obj.include:void 0,exclude=typeof obj.exclude==="string"?obj.exclude:void 0;let rawMaxResults=typeof obj.max_results==="number"?obj.max_results:DEFAULT_MAX_RESULTS4,sanitizedMaxResults=Number.isNaN(rawMaxResults)?DEFAULT_MAX_RESULTS4:rawMaxResults;maxResults=Math.min(Math.max(0,sanitizedMaxResults),HARD_CAP_RESULTS4);let rawMaxLines=typeof obj.max_lines==="number"?obj.max_lines:DEFAULT_MAX_LINES,sanitizedMaxLines=Number.isNaN(rawMaxLines)?DEFAULT_MAX_LINES:rawMaxLines;maxLines=Math.min(Math.max(0,sanitizedMaxLines),HARD_CAP_LINES)}catch{return JSON.stringify({error:!0,type:"invalid-query",message:"Could not parse search arguments"},null,2)}if(!query||query.trim()==="")return JSON.stringify({error:!0,type:"invalid-query",message:"Query cannot be empty"},null,2);if(query.length>MAX_QUERY_LENGTH)return JSON.stringify({error:!0,type:"invalid-query",message:`Query exceeds maximum length of ${MAX_QUERY_LENGTH} characters`},null,2);if(containsControlChars(query))return JSON.stringify({error:!0,type:"invalid-query",message:"Query contains invalid control characters"},null,2);if(include&&splitGlobPatterns2(include).length>MAX_INCLUDE_PATTERNS)return JSON.stringify({error:!0,type:"invalid-query",message:`Too many include patterns (max ${MAX_INCLUDE_PATTERNS})`},null,2);if(exclude&&splitGlobPatterns2(exclude).length>MAX_INCLUDE_PATTERNS)return JSON.stringify({error:!0,type:"invalid-query",message:`Too many exclude patterns (max ${MAX_INCLUDE_PATTERNS})`},null,2);if(include&&containsPathTraversal(include))return JSON.stringify({error:!0,type:"path-escape",message:"Include pattern contains path traversal sequence"},null,2);if(exclude&&containsPathTraversal(exclude))return JSON.stringify({error:!0,type:"path-escape",message:"Exclude pattern contains path traversal sequence"},null,2);if(include&&containsWindowsAttacks4(include))return JSON.stringify({error:!0,type:"path-escape",message:"Include pattern contains invalid Windows-specific sequence"},null,2);if(exclude&&containsWindowsAttacks4(exclude))return JSON.stringify({error:!0,type:"path-escape",message:"Exclude pattern contains invalid Windows-specific sequence"},null,2);if(!fs180.existsSync(directory))return JSON.stringify({error:!0,type:"unknown",message:"Workspace directory does not exist"},null,2);let result;if(_internals219.resolveRipgrepBinary())result=await ripgrepSearch({query,mode,include,exclude,maxResults,maxLines,workspace:directory});else result=await fallbackSearch({query,mode,include,exclude,maxResults,maxLines,workspace:directory});if("error"in result&&result.error)return JSON.stringify(result,null,2);return JSON.stringify(result,null,2)}}),_internals219={resolvePackagedRipgrep,resolveExecutableFromPath,resolveRipgrepBinary,runExternalTool,fallbackSearch};init_secretscan();init_zod();init_qa_gate_profile();init_manager();init_create_tool();var _internals220={setGatesForIdentity};async function executeSetQaGates(args2,directory){let plan=await loadPlanJsonOnly(directory),identity=resolveQaGatePlanIdentity(plan,args2);if(!identity.success)return{success:!1,reason:identity.reason,message:identity.message};let planId=identity.planId,currentPlanMatchesIdentity=plan?.swarm===identity.identity.swarm&&plan?.title===identity.identity.title,partial3={},gateKeys=["reviewer","test_engineer","council_mode","sme_enabled","critic_pre_plan","hallucination_guard","sast_enabled","mutation_test","phase_council","drift_check","final_council"];for(let key of gateKeys)if(args2[key]!==void 0)partial3[key]=args2[key];let bindingOnlyRequested=args2.adopt_legacy_binding_only===!0,hasGatePatch=Object.keys(partial3).length>0;if(bindingOnlyRequested&&(hasGatePatch||args2.project_type!==void 0))return{success:!1,reason:"binding_only_patch_conflict",message:"adopt_legacy_binding_only performs exact-binding recovery only. Omit all gate booleans and project_type when using it."};if(bindingOnlyRequested&&!currentPlanMatchesIdentity)return{success:!1,reason:"adopt_legacy_requires_current_plan",message:"adopt_legacy_binding_only may only target the exact current persisted plan identity. Re-run it from the active plan without replacing swarm_id or plan_title."};if(bindingOnlyRequested){let lookup=getProfileLookupForIdentity(directory,identity.identity);if(lookup.kind==="missing")return{success:!1,reason:"no_profile",plan_id:planId,message:"No legacy QA gate profile row exists for this exact current plan identity, so there is nothing to adopt."};if(lookup.kind==="bound")return{success:!0,plan_id:planId,message:`QA gate profile is already exact-bound for plan_id=${planId}; no gates or lock state changed.`,profile:{plan_id:lookup.profile.plan_id,gates:{...lookup.profile.gates},locked_at:lookup.profile.locked_at,locked_by_snapshot_seq:lookup.profile.locked_by_snapshot_seq,profile_hash:computeProfileHash(lookup.profile)}}}try{let updated=_internals220.setGatesForIdentity(directory,identity.identity,partial3,{projectType:args2.project_type,allowLegacyAdoption:currentPlanMatchesIdentity,allowLegacyCollisionCreate:!currentPlanMatchesIdentity,legacyAdoptionIdentity:plan?{swarm:plan.swarm,title:plan.title}:void 0});return{success:!0,plan_id:planId,message:bindingOnlyRequested?`Legacy QA gate profile exact-bound for plan_id=${planId} without changing gates or lock state.`:`QA gates updated for plan_id=${planId}`,profile:{plan_id:updated.plan_id,gates:{...updated.gates},locked_at:updated.locked_at,locked_by_snapshot_seq:updated.locked_by_snapshot_seq,profile_hash:computeProfileHash(updated)}}}catch(err2){let msg=err2 instanceof Error?err2.message:String(err2),lower=msg.toLowerCase(),reason="set_gates_failed";if(err2 instanceof QaGateProfileIdentityUnboundError)reason="plan_identity_unbound";if(lower.includes("locked"))reason="profile_locked";else if(lower.includes("ratchet"))reason="ratchet_violation";else if(bindingOnlyRequested)reason="binding_only_failed";return{success:!1,reason,message:err2 instanceof QaGateProfileIdentityUnboundError?`${msg} ${formatLegacyQaBindingOnlyCall(identity.identity)} is the only supported adoption path for locked or upgraded legacy rows.`:msg,plan_id:planId}}}var set_qa_gates=createSwarmTool({allowWorkingDirectoryOverride:!0,description:"Configure the QA gate profile for the current or exact future plan. Architect-only. The initial selection accepts explicit true and false values; later calls can enable additional gates but cannot disable enabled gates. Rejects writes once locked (after critic approval). Creates the initial profile atomically from defaults plus the explicit selection. Uses plan.json identity by default, or exact swarm_id + plan_title before a plan exists.",args:{swarm_id:exports_external.string().refine((value)=>value.trim().length>0,"Must not be blank").optional().describe("Exact swarm identity for pre-plan QA selection. Must be provided with plan_title."),plan_title:exports_external.string().refine((value)=>value.trim().length>0,"Must not be blank").optional().describe("Exact future plan title for pre-plan QA selection. Must be provided with swarm_id."),confirm_identity_change:exports_external.boolean().optional().describe("Confirm that an explicit swarm_id/plan_title pair intentionally replaces the current plan identity."),reviewer:exports_external.boolean().optional().describe("Select the reviewer gate; later calls cannot turn it off once enabled."),test_engineer:exports_external.boolean().optional().describe("Enable the test_engineer gate (true) — cannot be disabled once on."),council_mode:exports_external.boolean().optional().describe("Enable council mode — replaces per-task Stage B (reviewer + test_engineer) with the full 5-member council (critic, reviewer, sme, test_engineer, explorer) per task."),sme_enabled:exports_external.boolean().optional().describe("Enable SME consultation."),critic_pre_plan:exports_external.boolean().optional().describe("Enable critic_pre_plan review before plan approval."),hallucination_guard:exports_external.boolean().optional().describe("Enable hallucination_guard checks on plan and implementation claims."),sast_enabled:exports_external.boolean().optional().describe("Enable SAST scanning as a required QA gate."),mutation_test:exports_external.boolean().optional().describe("Enable the mutation-testing gate (default: off). Requires mutation tests to achieve a passing kill rate before phase completion; WARN verdict allows advancement, FAIL blocks."),phase_council:exports_external.boolean().optional().describe("Enable the phase_council gate (default: off). When on, a full 5-member council (critic, reviewer, sme, test_engineer, explorer) reviews all work completed in a phase holistically at phase_complete time. Requires council.enabled: true in config."),drift_check:exports_external.boolean().optional().describe("Enable drift verification gate (default: on). Blocks phase_complete until drift-verifier.json has an approved verdict. When disabled, drift verification is skipped entirely."),final_council:exports_external.boolean().optional().describe("Enable the final_council gate (default: off). When on, after all phases complete the architect dispatches critic, reviewer, sme, test_engineer, and explorer with project-scoped context, collects their CouncilMemberVerdict objects, and calls write_final_council_evidence. This is not General Council mode and does not require council.general.enabled."),project_type:exports_external.string().optional().describe('Project type label (e.g. "ts", "python"). Only applied when the profile is being created for the first time.'),adopt_legacy_binding_only:exports_external.boolean().optional().describe("Operational recovery for upgraded legacy rows. When true, exact-binds the existing current-plan QA profile without changing any gates or its lock. Omit all gate booleans and project_type when using this action.")},execute:async(args2,directory)=>{return JSON.stringify(await executeSetQaGates(args2??{},directory),null,2)}});init_zod();init_skill_generator();init_create_tool();var skill_apply=createSwarmTool({description:"Activate a draft skill proposal (.swarm/skills/proposals/<slug>.md) into .opencode/skills/generated/<slug>/SKILL.md.",args:{slug:exports_external.string().min(1).describe("Slug of the proposal to activate."),force:exports_external.boolean().optional().default(!1).describe("Overwrite an existing active SKILL.md even if it lacks the generator stamp. Default false."),evaluate:exports_external.boolean().optional().default(!1).describe("Validate the proposal against .swarm/skills/evals/<slug> before activation. Default false."),confirm_unevaluated:exports_external.boolean().optional().default(!1).describe('Allow activation when evaluateSkillChange returns status "unevaluated" (no eval set exists). Default false — the activation is blocked with a surfaced reason so the caller can confirm. Generated skills auto-derive an eval stub from their source directives, so this only applies to non-directive skills with no stub.')},execute:async(args2,directory)=>{let a=args2??{};if(!a.slug||typeof a.slug!=="string")return JSON.stringify({activated:!1,reason:"slug required"});let result=await activateProposal(directory,a.slug,a.force??!1,{evaluate:a.evaluate??!1,confirmUnevaluated:a.confirm_unevaluated??!1});return JSON.stringify(result,null,2)}});init_zod();init_skill_generator();init_create_tool();var skill_generate=createSwarmTool({description:'Compile mature knowledge entries into a SKILL.md. mode="draft" writes a proposal under .swarm/skills/proposals; mode="active" writes the live skill under .opencode/skills/generated and stamps source entries.',args:{source_knowledge_ids:exports_external.array(exports_external.string()).optional().describe("Optional explicit knowledge ids to compile. If omitted, all mature candidates are clustered and emitted."),slug:exports_external.string().optional().describe("Optional slug for the FIRST cluster. Sanitized; rejected if invalid."),mode:exports_external.enum(["draft","active"]).default("draft"),force:exports_external.boolean().optional().default(!1),evaluate:exports_external.boolean().optional().default(!1).describe("Validate generated skill content against .swarm/skills/evals/<slug> before writing. Default false."),min_confidence:exports_external.number().min(0).max(1).optional(),min_confirmations:exports_external.number().int().min(1).max(50).optional()},execute:async(args2,directory)=>{let a=args2??{},result=await generateSkills({directory,mode:a.mode??"draft",slug:a.slug,sourceKnowledgeIds:a.source_knowledge_ids,force:a.force??!1,evaluate:a.evaluate??!1,minConfidence:a.min_confidence,minConfirmations:a.min_confirmations});return JSON.stringify(result,null,2)}});init_zod();init_config();init_schema();init_skill_improver();init_create_tool();var skill_improve=createSwarmTool({description:'Run the skill_improver capability under daily quota. Writes a proposal under .swarm/skill-improver/proposals/<timestamp>.md. With mode="draft_skills" it also drafts SKILL.md proposals for mature clusters. Quota is enforced via .swarm/skill-improver-quota.json.',args:{targets:exports_external.array(exports_external.enum(["skills","spec","architect_prompt","knowledge"])).optional(),mode:exports_external.enum(["proposal","draft_skills"]).optional(),max_calls:exports_external.number().int().min(1).max(100).optional().describe("Override the per-run reservation count (capped by daily max)."),evaluate:exports_external.boolean().optional().default(!1).describe('When mode="draft_skills", validate generated draft skills before writing proposals. Default false.')},execute:async(args2,directory,ctx)=>{let a=args2??{},{config:config3}=loadPluginConfigWithMeta(directory),parsed=SkillImproverConfigSchema.parse(config3.skill_improver??{}),enrichmentConfig=KnowledgeConfigSchema.parse(config3.knowledge??{}).enrichment??{max_calls_per_day:30,quota_window:"utc"};if(!parsed.enabled)return JSON.stringify({ran:!1,reason:'skill_improver is disabled. Set "skill_improver.enabled": true in opencode-swarm config to use this tool.'},null,2);let result=await runSkillImprover({directory,config:parsed,targets:a.targets,mode:a.mode,maxCalls:a.max_calls,sessionId:ctx?.sessionID,enrichmentQuota:{maxCalls:enrichmentConfig.max_calls_per_day,window:enrichmentConfig.quota_window},evaluateDrafts:a.evaluate??!1});return JSON.stringify(result,null,2)}});init_zod();init_skill_generator();init_create_tool();var skill_inspect=createSwarmTool({description:"Read a generated skill (active or draft) and return its full markdown body and metadata.",args:{slug:exports_external.string().min(1).describe("Slug of the skill to inspect."),prefer:exports_external.enum(["auto","proposal","active"]).optional().default("auto")},execute:async(args2,directory)=>{let a=args2??{};if(!a.slug||typeof a.slug!=="string")return JSON.stringify({found:!1,reason:"slug required"});let result=await inspectSkill(directory,a.slug,a.prefer??"auto");return JSON.stringify(result,null,2)}});init_skill_generator();init_create_tool();var skill_list=createSwarmTool({description:"List generated skill drafts (under .swarm/skills/proposals) and active generated skills (under .opencode/skills/generated).",args:{},execute:async(_args,directory)=>{let result=await listSkills(directory);return JSON.stringify(result,null,2)}});init_zod();init_skill_generator();init_create_tool();var skill_regenerate=createSwarmTool({description:"Regenerate an active skill by re-clustering its source knowledge entries and updating the SKILL.md in place.",args:{slug:exports_external.string().min(1).describe("Slug of the active skill to regenerate."),evaluate:exports_external.boolean().optional().default(!1).describe("Validate regenerated content against .swarm/skills/evals/<slug> before writing. Default false.")},execute:async(args2,directory)=>{let a=args2??{};if(!a.slug||typeof a.slug!=="string")return JSON.stringify({regenerated:!1,reason:"slug required"});let result=await regenerateSkill(directory,a.slug,{evaluate:a.evaluate??!1});return JSON.stringify(result,null,2)}});init_zod();init_skill_generator();init_create_tool();var skill_retire=createSwarmTool({description:"Retire a generated skill by adding a retired.marker file. Retired skills are excluded from scoring and injection.",args:{slug:exports_external.string().min(1).describe("Slug of the active skill to retire."),reason:exports_external.string().optional().describe("Optional reason for retirement.")},execute:async(args2,directory)=>{let a=args2??{};if(!a.slug||typeof a.slug!=="string")return JSON.stringify({retired:!1,reason:"slug required"});let result=await retireSkill(directory,a.slug,a.reason);return JSON.stringify(result,null,2)}});init_zod();init_config();init_schema();init_file_locks();init_spec_drift_recovery();init_create_tool();import{mkdir as mkdir55,rename as rename22,writeFile as writeFile31}from"node:fs/promises";import*as path297 from"node:path";var MAX_SPEC_BYTES2=262144,spec_write=createSwarmTool({description:"Write the canonical project spec to .swarm/spec.md. Atomic write, size-bounded (256 KiB), heading-required. Honors spec_writer.allow_spec_write.",args:{content:exports_external.string().min(20).max(MAX_SPEC_BYTES2),mode:exports_external.enum(["replace","append"]).optional().default("replace")},execute:async(args2,directory)=>{let a=args2??{},content=a.content,mode=a.mode??"replace";if(typeof content!=="string"||content.length<20)return JSON.stringify({written:!1,reason:"content must be a string >=20 chars"});if(content.length>MAX_SPEC_BYTES2)return JSON.stringify({written:!1,reason:`content exceeds ${MAX_SPEC_BYTES2} bytes`});let{config:config3}=loadPluginConfigWithMeta(directory);if(!SpecWriterConfigSchema.parse(config3.spec_writer??{}).allow_spec_write)return JSON.stringify({written:!1,reason:"spec_writer.allow_spec_write is false"},null,2);if(content.indexOf("\x00")!==-1)return JSON.stringify({written:!1,reason:"content contains null byte"},null,2);if(!/^#\s+/m.test(content))return JSON.stringify({written:!1,reason:'spec must contain at least one top-level "# Heading"'},null,2);let specLock=await tryAcquireLock(directory,"spec.md","spec-write",`spec-write-${Date.now()}`);if(!specLock.acquired)return JSON.stringify({written:!1,reason:"another canonical spec write or drift recovery is in progress; retry shortly"},null,2);try{let target=path297.join(directory,".swarm","spec.md");await mkdir55(path297.dirname(target),{recursive:!0});let tmp=`${target}.tmp-${process.pid}-${Date.now()}`,finalContent=content;if(mode==="append")try{if(finalContent=`${(await(await import("node:fs/promises")).readFile(target,"utf-8")).replace(/\s+$/,"")}
6638
6646
 
6639
6647
  ${content}
6640
- `,finalContent.length>MAX_SPEC_BYTES2)return JSON.stringify({written:!1,reason:"append would exceed max spec size (256 KiB); rewrite explicitly"},null,2)}catch{}await writeFile31(tmp,finalContent,"utf-8"),await rename22(tmp,target);let specDriftRecovery;try{specDriftRecovery=await reconcileSpecDrift(directory,{mode:"repair",actor:"spec_write",specLockAlreadyHeld:!0})}catch(error93){specDriftRecovery={status:"failed",mode:"repair",message:`Spec write succeeded, but spec drift recovery failed: ${error93 instanceof Error?error93.message:String(error93)}`}}return JSON.stringify({written:!0,path:target,bytes:finalContent.length,spec_drift_recovery:specDriftRecovery},null,2)}finally{if(specLock.lock._release)await specLock.lock._release().catch(()=>{})}}});init_zod();init_knowledge_store();init_skill_generator();init_create_tool();import{existsSync as existsSync152}from"node:fs";import{readdir as readdir19,readFile as readFile55}from"node:fs/promises";import{join as join240}from"node:path";var run_stale_reconciliation=createSwarmTool({description:"Reconcile skills against the knowledge store. clear=false: mark skills stale when source knowledge is archived or deleted. clear=true: clear stale.marker on affected active skills (proposal files under .swarm/skills/proposals are scanned but not modified — they are drafts, not yet active skills).",args:{clear:exports_external.boolean().optional().default(!1).describe("If true, clear stale markers for affected skills. If false (default), mark affected skills stale.")},execute:async(args2,directory)=>{if(typeof directory!=="string"||!directory)return JSON.stringify({found:0,skills:[]},null,2);let archivedIds=await _internals221.getArchivedKnowledgeIds(directory),archivedSet=new Set(archivedIds),allKnownIds=new Set,swarmPath3=_internals221.resolveSwarmKnowledgePath(directory),hivePath=_internals221.resolveHiveKnowledgePath();try{let swarmEntries=await _internals221.readKnowledge(swarmPath3);for(let e of swarmEntries)allKnownIds.add(e.id)}catch{}try{let hiveEntries=await _internals221.readKnowledge(hivePath);for(let e of hiveEntries)allKnownIds.add(e.id)}catch{}let skillEntries=[];for(let dir of[join240(directory,".opencode","skills","generated"),join240(directory,".swarm","skills","proposals")]){if(!_internals221.existsSync(dir))continue;let entries=await _internals221.readdir(dir,{withFileTypes:!0});for(let entry of entries)if(entry.isDirectory())skillEntries.push({slug:entry.name,path:join240(dir,entry.name),isProposal:!1});else if(entry.name.endsWith(".md")){let slug=entry.name.replace(/\.md$/,"");skillEntries.push({slug,path:join240(dir,entry.name),isProposal:!0})}}let results=[];for(let{slug,path:path298,isProposal}of skillEntries){let skillMdPath=isProposal?path298:join240(path298,"SKILL.md");if(!_internals221.existsSync(skillMdPath))continue;let content=await _internals221.readFile(skillMdPath,"utf-8"),sourceIds=_internals221.parseDraftFrontmatter(content)?.sourceKnowledgeIds??[];if(sourceIds.length===0)continue;let affected=sourceIds.filter((id)=>archivedSet.has(id)||!allKnownIds.has(id));if(affected.length===0)continue;if(args2.clear){if(!isProposal){let markerPath=join240(path298,"stale.marker");if(_internals221.existsSync(markerPath))try{await _internals221.clearSkillStale(path298),results.push({slug,reason:affected.join(", "),action:"cleared"})}catch{}}}else if(!isProposal)try{await _internals221.retireOrMarkStale(directory,path298,archivedSet),results.push({slug,reason:affected.join(", "),action:"marked_stale"})}catch{}}return JSON.stringify({found:results.length,skills:results},null,2)}}),_internals221={run_stale_reconciliation,clearSkillStale,retireOrMarkStale,parseDraftFrontmatter,getArchivedKnowledgeIds,readKnowledge,resolveSwarmKnowledgePath,resolveHiveKnowledgePath:resolveHiveKnowledgePath2,readdir:readdir19,readFile:readFile55,existsSync:existsSync152};init_zod();init_loader();import{existsSync as existsSync153,mkdirSync as mkdirSync71,readFileSync as readFileSync126,renameSync as renameSync41,unlinkSync as unlinkSync40,writeFileSync as writeFileSync50}from"node:fs";import path298 from"node:path";init_config2();init_gateway();init_reward_capture();init_logger();init_swarm_artifact_cache();init_create_tool();init_resolve_working_directory();var ALL_MEMBERS2=["critic","reviewer","sme","test_engineer","explorer"],FindingSchema2=exports_external.object({severity:exports_external.enum(["CRITICAL","HIGH","MEDIUM","LOW"]),category:exports_external.string().min(1),location:exports_external.string(),detail:exports_external.string(),evidence:exports_external.string()}),VerdictSchema2=exports_external.object({agent:exports_external.enum(ALL_MEMBERS2),verdict:exports_external.enum(["APPROVE","CONCERNS","REJECT"]),confidence:exports_external.number().min(0).max(1),findings:exports_external.array(FindingSchema2),criteriaAssessed:exports_external.array(exports_external.string()),criteriaUnmet:exports_external.array(exports_external.string()),durationMs:exports_external.number().nonnegative()}),ArgsSchema4=exports_external.object({phaseNumber:exports_external.number().int().min(1),swarmId:exports_external.string().min(1),phaseSummary:exports_external.string().min(1),roundNumber:exports_external.number().int().min(1).max(10).optional(),verdicts:exports_external.array(VerdictSchema2).min(1).max(5),working_directory:exports_external.string().optional(),provenanceAgentName:exports_external.string().min(1).optional(),provenanceSessionId:exports_external.string().min(1).optional()}),submit_phase_council_verdicts=createSwarmTool({description:"Submit pre-collected phase council verdicts. The server owns the current round; roundNumber is only an optional expectation. Writes phase-council evidence after durable attempt-state preflight. Architect-only and config-gated.",args:{phaseNumber:ArgsSchema4.shape.phaseNumber.describe("Phase number being reviewed"),swarmId:ArgsSchema4.shape.swarmId.describe("Swarm identifier"),phaseSummary:ArgsSchema4.shape.phaseSummary.describe("Phase summary"),roundNumber:ArgsSchema4.shape.roundNumber.describe("Optional expected server round. Omit to use the authoritative round."),verdicts:ArgsSchema4.shape.verdicts.describe("Collected member verdicts"),working_directory:ArgsSchema4.shape.working_directory.describe("Explicit project root directory"),provenanceAgentName:ArgsSchema4.shape.provenanceAgentName.describe("Optional evidence producer name"),provenanceSessionId:ArgsSchema4.shape.provenanceSessionId.describe("Optional evidence producer session")},async execute(args2,directory,ctx){let parsed=ArgsSchema4.safeParse(args2);if(!parsed.success)return await recordUnscopedCouncilAttempt(directory,"phase","invalid_arguments",args2,parsed.error.issues.map((issue3)=>({path:issue3.path,code:issue3.code})),ctx?.sessionID)??invalidResponse2(parsed.error.issues);let input=parsed.data,resolved=resolveWorkingDirectory(input.working_directory,directory);if(!resolved.success)return await recordUnscopedCouncilAttempt(directory,"phase","invalid_working_directory",input,[],ctx?.sessionID)??JSON.stringify({success:!1,reason:resolved.message},null,2);let workingDir=resolved.directory,config3=loadPluginConfig(workingDir),councilConfig=config3.council,distinctMembers=new Set(input.verdicts.map((verdict)=>verdict.agent)),membersVoted=[...distinctMembers],membersAbsent=ALL_MEMBERS2.filter((member)=>!distinctMembers.has(member));return runCouncilAttempt({directory:workingDir,scope:{kind:"phase",phaseNumber:input.phaseNumber},clientRound:input.roundNumber,maxRounds:councilConfig?.maxRounds??3,sessionID:ctx?.sessionID,request:input,verdictCount:input.verdicts.length,members:membersVoted,probePendingEvidence:async(attemptId,round)=>hasPhaseEvidenceAttempt(workingDir,input.phaseNumber,attemptId,round),evaluate:async(authoritativeRound)=>{if(!councilConfig?.enabled)return{disposition:"council_disabled",response:{success:!1,reason:"council feature is disabled — set council.enabled: true in .opencode/opencode-swarm.json to enable"},transition:"stay",gateEffect:"none"};let effectiveMinimum=councilConfig.requireAllMembers?5:councilConfig.minimumMembers??3;if(membersVoted.length<effectiveMinimum)return{disposition:"insufficient_quorum",response:{success:!1,reason:"insufficient_quorum",message:`Phase council quorum not met: ${membersVoted.length} of ${effectiveMinimum}. Members absent: [${membersAbsent.join(", ")}].`,membersVoted,membersAbsent,quorumRequired:effectiveMinimum},transition:"stay",gateEffect:"none"};let synthesis=synthesizePhaseCouncilAdvisory(input.phaseNumber,input.phaseSummary,input.verdicts,authoritativeRound,councilConfig,workingDir),mutationGapFinding=input.verdicts.some((verdict)=>verdict.findings.some((finding)=>finding.category==="mutation_gap"))?null:getPhaseMutationGapFinding(input.phaseNumber,workingDir);if(mutationGapFinding){if(addMutationGapFindingToSynthesis(synthesis,mutationGapFinding),mutationGapFinding.severity==="CRITICAL"||mutationGapFinding.severity==="HIGH")synthesis.blockingConcernsCount++}if(synthesis.blockingConcernsCount>0)return{disposition:"blocking_concerns_unresolved",response:{success:!1,reason:"blocking_concerns_unresolved",overallVerdict:synthesis.overallVerdict,blockingConcernsCount:synthesis.blockingConcernsCount,requiredFixes:synthesis.requiredFixes,unifiedFeedbackMd:synthesis.unifiedFeedbackMd,message:"Address every requiredFix and resubmit the phase council."},transition:"advance",gateEffect:"blocked",verdict:synthesis.overallVerdict,quorumSize:membersVoted.length};let provenance=input.provenanceAgentName||input.provenanceSessionId?{agent_name:input.provenanceAgentName,session_id:input.provenanceSessionId,captured_at:new Date().toISOString()}:void 0,concernsAllowed=councilConfig.phaseConcernsAllowComplete??!0,transition=synthesis.overallVerdict==="APPROVE"||synthesis.overallVerdict==="CONCERNS"&&concernsAllowed?"close":"advance";return{disposition:`evaluated_${synthesis.overallVerdict.toLowerCase()}`,response:{success:!0,overallVerdict:synthesis.overallVerdict,vetoedBy:synthesis.vetoedBy,roundNumber:synthesis.roundNumber,allCriteriaMet:synthesis.allCriteriaMet,requiredFixesCount:synthesis.requiredFixes.length,advisoryFindingsCount:synthesis.advisoryFindings.length,unresolvedConflictsCount:synthesis.unresolvedConflicts.length,advisoryNotes:synthesis.advisoryNotes,mutationGapEmitted:mutationGapFinding!==null,membersVoted,membersAbsent,quorumSize:membersVoted.length,quorumMet:!0,evidencePath:synthesis.evidencePath,unifiedFeedbackMd:synthesis.unifiedFeedbackMd},transition,gateEffect:transition==="close"?"allowed":"blocked",verdict:synthesis.overallVerdict,quorumSize:membersVoted.length,evidence:{reference:synthesis.evidencePath,commit:async(attemptId)=>writePhaseCouncilEvidence(workingDir,synthesis,provenance,attemptId)},afterCommit:async()=>applyPhaseCouncilReward(workingDir,synthesis,config3,ctx)}}})}});function invalidResponse2(issues){return JSON.stringify({success:!1,reason:"invalid arguments",errors:issues.map((issue3)=>({path:issue3.path.join("."),message:issue3.message}))},null,2)}async function applyPhaseCouncilReward(workingDir,synthesis,config3,ctx){try{let memoryConfig=config3.memory;if(memoryConfig?.enabled!==!0||!ctx?.sessionID)return;let provider=createConfiguredMemoryProvider(workingDir,memoryConfig);try{let summary={scope:"phase",phaseNumber:synthesis.phaseNumber,overallVerdict:synthesis.overallVerdict,allCriteriaMet:synthesis.allCriteriaMet,requiredFixesCount:synthesis.requiredFixes.length,roundNumber:synthesis.roundNumber,quorumSize:synthesis.quorumSize},verdictSynthesisJson=JSON.stringify(summary),cap2=memoryConfig.qLearning.verdictPayloadCapBytes;if(typeof cap2==="number"&&cap2>0&&verdictSynthesisJson.length>cap2)verdictSynthesisJson=JSON.stringify(truncateObjectForJson(summary,cap2));await applyCouncilReward(provider,{runId:ctx.sessionID,unitId:void 0,reward:COUNCIL_VERDICT_REWARDS[synthesis.overallVerdict],eta:memoryConfig.qLearning.learningRate,initialQValue:memoryConfig.qLearning.initialQValue,qLearning:memoryConfig.qLearning,verdictSynthesisJson,timestamp:new Date().toISOString(),verdictLabel:synthesis.overallVerdict})}finally{await provider.close?.()}}catch(error93){warn(`[submit-phase-council-verdicts] phase council reward capture failed: ${error93 instanceof Error?error93.message:String(error93)}`)}}function phaseEvidencePath2(workingDir,phaseNumber){return path298.join(workingDir,".swarm","evidence",String(phaseNumber),"phase-council.json")}function hasPhaseEvidenceAttempt(workingDir,phaseNumber,attemptId,round){try{let parsed=JSON.parse(readFileSync126(phaseEvidencePath2(workingDir,phaseNumber),"utf8"));return Boolean(parsed.entries?.some((entry)=>entry.type==="phase-council"&&entry.attemptId===attemptId&&entry.roundNumber===round))}catch{return!1}}async function writePhaseCouncilEvidence(workingDir,synthesis,provenance,attemptId){let evidenceFile=phaseEvidencePath2(workingDir,synthesis.phaseNumber);mkdirSync71(path298.dirname(evidenceFile),{recursive:!0});let content={entries:[{type:"phase-council",phase_number:synthesis.phaseNumber,scope:"phase",timestamp:synthesis.timestamp,verdict:synthesis.overallVerdict,quorumSize:synthesis.quorumSize,phaseSummary:synthesis.phaseSummary??"",requiredFixes:synthesis.requiredFixes,advisoryNotes:synthesis.advisoryNotes,advisoryFindings:synthesis.advisoryFindings,roundNumber:synthesis.roundNumber,allCriteriaMet:synthesis.allCriteriaMet,attemptId,...provenance?{provenance}:{}}]},tempFile=`${evidenceFile}.tmp-${Date.now()}`;try{writeFileSync50(tempFile,JSON.stringify(content,null,2),"utf8"),renameSync41(tempFile,evidenceFile),invalidateCachedArtifact(evidenceFile)}finally{if(existsSync153(tempFile))unlinkSync40(tempFile)}}function getPhaseMutationGapFinding(phaseNumber,workingDir){let mutationGatePath=path298.join(workingDir,".swarm","evidence",String(phaseNumber),"mutation-gate.json"),mutationGateLocation=`.swarm/evidence/${phaseNumber}/mutation-gate.json`;try{let entry=JSON.parse(readFileSync126(mutationGatePath,"utf8")).entries?.find((candidate2)=>candidate2.type==="mutation-gate");if(!entry)return mutationFinding("HIGH",mutationGateLocation,"Mutation gate evidence is missing a mutation-gate entry.");if(entry.verdict==="skip")return mutationFinding("MEDIUM",mutationGateLocation,"Mutation testing was skipped.");if(entry.verdict==="warn")return mutationFinding("LOW",mutationGateLocation,"Mutation gate reported WARN.");if(entry.verdict==="fail")return mutationFinding("HIGH",mutationGateLocation,"Mutation gate reported FAIL.");return null}catch(error93){let missing=error93.code==="ENOENT";return mutationFinding(missing?"HIGH":"MEDIUM",mutationGateLocation,missing?"Mutation gate evidence is missing.":"Mutation gate evidence could not be read.",error93 instanceof Error?error93.message:String(error93))}}function mutationFinding(severity,location,detail,evidence2=detail){return{severity,category:"mutation_gap",location,detail,evidence:evidence2}}function addMutationGapFindingToSynthesis(synthesis,finding){if(["CRITICAL","HIGH","MEDIUM"].includes(finding.severity))synthesis.requiredFixes.push(finding);else synthesis.advisoryFindings.push(finding);synthesis.unifiedFeedbackMd+=`
6648
+ `,finalContent.length>MAX_SPEC_BYTES2)return JSON.stringify({written:!1,reason:"append would exceed max spec size (256 KiB); rewrite explicitly"},null,2)}catch{}await writeFile31(tmp,finalContent,"utf-8"),await rename22(tmp,target);let specDriftRecovery;try{specDriftRecovery=await reconcileSpecDrift(directory,{mode:"repair",actor:"spec_write",specLockAlreadyHeld:!0})}catch(error93){specDriftRecovery={status:"failed",mode:"repair",message:`Spec write succeeded, but spec drift recovery failed: ${error93 instanceof Error?error93.message:String(error93)}`}}return JSON.stringify({written:!0,path:target,bytes:finalContent.length,spec_drift_recovery:specDriftRecovery},null,2)}finally{if(specLock.lock._release)await specLock.lock._release().catch(()=>{})}}});init_zod();init_knowledge_store();init_skill_generator();init_create_tool();import{existsSync as existsSync153}from"node:fs";import{readdir as readdir19,readFile as readFile55}from"node:fs/promises";import{join as join240}from"node:path";var run_stale_reconciliation=createSwarmTool({description:"Reconcile skills against the knowledge store. clear=false: mark skills stale when source knowledge is archived or deleted. clear=true: clear stale.marker on affected active skills (proposal files under .swarm/skills/proposals are scanned but not modified — they are drafts, not yet active skills).",args:{clear:exports_external.boolean().optional().default(!1).describe("If true, clear stale markers for affected skills. If false (default), mark affected skills stale.")},execute:async(args2,directory)=>{if(typeof directory!=="string"||!directory)return JSON.stringify({found:0,skills:[]},null,2);let archivedIds=await _internals221.getArchivedKnowledgeIds(directory),archivedSet=new Set(archivedIds),allKnownIds=new Set,swarmPath3=_internals221.resolveSwarmKnowledgePath(directory),hivePath=_internals221.resolveHiveKnowledgePath();try{let swarmEntries=await _internals221.readKnowledge(swarmPath3);for(let e of swarmEntries)allKnownIds.add(e.id)}catch{}try{let hiveEntries=await _internals221.readKnowledge(hivePath);for(let e of hiveEntries)allKnownIds.add(e.id)}catch{}let skillEntries=[];for(let dir of[join240(directory,".opencode","skills","generated"),join240(directory,".swarm","skills","proposals")]){if(!_internals221.existsSync(dir))continue;let entries=await _internals221.readdir(dir,{withFileTypes:!0});for(let entry of entries)if(entry.isDirectory())skillEntries.push({slug:entry.name,path:join240(dir,entry.name),isProposal:!1});else if(entry.name.endsWith(".md")){let slug=entry.name.replace(/\.md$/,"");skillEntries.push({slug,path:join240(dir,entry.name),isProposal:!0})}}let results=[];for(let{slug,path:path298,isProposal}of skillEntries){let skillMdPath=isProposal?path298:join240(path298,"SKILL.md");if(!_internals221.existsSync(skillMdPath))continue;let content=await _internals221.readFile(skillMdPath,"utf-8"),sourceIds=_internals221.parseDraftFrontmatter(content)?.sourceKnowledgeIds??[];if(sourceIds.length===0)continue;let affected=sourceIds.filter((id)=>archivedSet.has(id)||!allKnownIds.has(id));if(affected.length===0)continue;if(args2.clear){if(!isProposal){let markerPath=join240(path298,"stale.marker");if(_internals221.existsSync(markerPath))try{await _internals221.clearSkillStale(path298),results.push({slug,reason:affected.join(", "),action:"cleared"})}catch{}}}else if(!isProposal)try{await _internals221.retireOrMarkStale(directory,path298,archivedSet),results.push({slug,reason:affected.join(", "),action:"marked_stale"})}catch{}}return JSON.stringify({found:results.length,skills:results},null,2)}}),_internals221={run_stale_reconciliation,clearSkillStale,retireOrMarkStale,parseDraftFrontmatter,getArchivedKnowledgeIds,readKnowledge,resolveSwarmKnowledgePath,resolveHiveKnowledgePath:resolveHiveKnowledgePath2,readdir:readdir19,readFile:readFile55,existsSync:existsSync153};init_zod();init_loader();import{existsSync as existsSync154,mkdirSync as mkdirSync71,readFileSync as readFileSync126,renameSync as renameSync40,unlinkSync as unlinkSync41,writeFileSync as writeFileSync50}from"node:fs";import path298 from"node:path";init_config2();init_gateway();init_reward_capture();init_logger();init_swarm_artifact_cache();init_create_tool();init_resolve_working_directory();var ALL_MEMBERS2=["critic","reviewer","sme","test_engineer","explorer"],FindingSchema2=exports_external.object({severity:exports_external.enum(["CRITICAL","HIGH","MEDIUM","LOW"]),category:exports_external.string().min(1),location:exports_external.string(),detail:exports_external.string(),evidence:exports_external.string()}),VerdictSchema2=exports_external.object({agent:exports_external.enum(ALL_MEMBERS2),verdict:exports_external.enum(["APPROVE","CONCERNS","REJECT"]),confidence:exports_external.number().min(0).max(1),findings:exports_external.array(FindingSchema2),criteriaAssessed:exports_external.array(exports_external.string()),criteriaUnmet:exports_external.array(exports_external.string()),durationMs:exports_external.number().nonnegative()}),ArgsSchema4=exports_external.object({phaseNumber:exports_external.number().int().min(1),swarmId:exports_external.string().min(1),phaseSummary:exports_external.string().min(1),roundNumber:exports_external.number().int().min(1).max(10).optional(),verdicts:exports_external.array(VerdictSchema2).min(1).max(5),working_directory:exports_external.string().optional(),provenanceAgentName:exports_external.string().min(1).optional(),provenanceSessionId:exports_external.string().min(1).optional()}),submit_phase_council_verdicts=createSwarmTool({description:"Submit pre-collected phase council verdicts. The server owns the current round; roundNumber is only an optional expectation. Writes phase-council evidence after durable attempt-state preflight. Architect-only and config-gated.",args:{phaseNumber:ArgsSchema4.shape.phaseNumber.describe("Phase number being reviewed"),swarmId:ArgsSchema4.shape.swarmId.describe("Swarm identifier"),phaseSummary:ArgsSchema4.shape.phaseSummary.describe("Phase summary"),roundNumber:ArgsSchema4.shape.roundNumber.describe("Optional expected server round. Omit to use the authoritative round."),verdicts:ArgsSchema4.shape.verdicts.describe("Collected member verdicts"),working_directory:ArgsSchema4.shape.working_directory.describe("Explicit project root directory"),provenanceAgentName:ArgsSchema4.shape.provenanceAgentName.describe("Optional evidence producer name"),provenanceSessionId:ArgsSchema4.shape.provenanceSessionId.describe("Optional evidence producer session")},async execute(args2,directory,ctx){let parsed=ArgsSchema4.safeParse(args2);if(!parsed.success)return await recordUnscopedCouncilAttempt(directory,"phase","invalid_arguments",args2,parsed.error.issues.map((issue3)=>({path:issue3.path,code:issue3.code})),ctx?.sessionID)??invalidResponse2(parsed.error.issues);let input=parsed.data,resolved=resolveWorkingDirectory(input.working_directory,directory);if(!resolved.success)return await recordUnscopedCouncilAttempt(directory,"phase","invalid_working_directory",input,[],ctx?.sessionID)??JSON.stringify({success:!1,reason:resolved.message},null,2);let workingDir=resolved.directory,config3=loadPluginConfig(workingDir),councilConfig=config3.council,distinctMembers=new Set(input.verdicts.map((verdict)=>verdict.agent)),membersVoted=[...distinctMembers],membersAbsent=ALL_MEMBERS2.filter((member)=>!distinctMembers.has(member));return runCouncilAttempt({directory:workingDir,scope:{kind:"phase",phaseNumber:input.phaseNumber},clientRound:input.roundNumber,maxRounds:councilConfig?.maxRounds??3,sessionID:ctx?.sessionID,request:input,verdictCount:input.verdicts.length,members:membersVoted,probePendingEvidence:async(attemptId,round)=>hasPhaseEvidenceAttempt(workingDir,input.phaseNumber,attemptId,round),evaluate:async(authoritativeRound)=>{if(!councilConfig?.enabled)return{disposition:"council_disabled",response:{success:!1,reason:"council feature is disabled — set council.enabled: true in .opencode/opencode-swarm.json to enable"},transition:"stay",gateEffect:"none"};let effectiveMinimum=councilConfig.requireAllMembers?5:councilConfig.minimumMembers??3;if(membersVoted.length<effectiveMinimum)return{disposition:"insufficient_quorum",response:{success:!1,reason:"insufficient_quorum",message:`Phase council quorum not met: ${membersVoted.length} of ${effectiveMinimum}. Members absent: [${membersAbsent.join(", ")}].`,membersVoted,membersAbsent,quorumRequired:effectiveMinimum},transition:"stay",gateEffect:"none"};let synthesis=synthesizePhaseCouncilAdvisory(input.phaseNumber,input.phaseSummary,input.verdicts,authoritativeRound,councilConfig,workingDir),mutationGapFinding=input.verdicts.some((verdict)=>verdict.findings.some((finding)=>finding.category==="mutation_gap"))?null:getPhaseMutationGapFinding(input.phaseNumber,workingDir);if(mutationGapFinding){if(addMutationGapFindingToSynthesis(synthesis,mutationGapFinding),mutationGapFinding.severity==="CRITICAL"||mutationGapFinding.severity==="HIGH")synthesis.blockingConcernsCount++}if(synthesis.blockingConcernsCount>0)return{disposition:"blocking_concerns_unresolved",response:{success:!1,reason:"blocking_concerns_unresolved",overallVerdict:synthesis.overallVerdict,blockingConcernsCount:synthesis.blockingConcernsCount,requiredFixes:synthesis.requiredFixes,unifiedFeedbackMd:synthesis.unifiedFeedbackMd,message:"Address every requiredFix and resubmit the phase council."},transition:"advance",gateEffect:"blocked",verdict:synthesis.overallVerdict,quorumSize:membersVoted.length};let provenance=input.provenanceAgentName||input.provenanceSessionId?{agent_name:input.provenanceAgentName,session_id:input.provenanceSessionId,captured_at:new Date().toISOString()}:void 0,concernsAllowed=councilConfig.phaseConcernsAllowComplete??!0,transition=synthesis.overallVerdict==="APPROVE"||synthesis.overallVerdict==="CONCERNS"&&concernsAllowed?"close":"advance";return{disposition:`evaluated_${synthesis.overallVerdict.toLowerCase()}`,response:{success:!0,overallVerdict:synthesis.overallVerdict,vetoedBy:synthesis.vetoedBy,roundNumber:synthesis.roundNumber,allCriteriaMet:synthesis.allCriteriaMet,requiredFixesCount:synthesis.requiredFixes.length,advisoryFindingsCount:synthesis.advisoryFindings.length,unresolvedConflictsCount:synthesis.unresolvedConflicts.length,advisoryNotes:synthesis.advisoryNotes,mutationGapEmitted:mutationGapFinding!==null,membersVoted,membersAbsent,quorumSize:membersVoted.length,quorumMet:!0,evidencePath:synthesis.evidencePath,unifiedFeedbackMd:synthesis.unifiedFeedbackMd},transition,gateEffect:transition==="close"?"allowed":"blocked",verdict:synthesis.overallVerdict,quorumSize:membersVoted.length,evidence:{reference:synthesis.evidencePath,commit:async(attemptId)=>writePhaseCouncilEvidence(workingDir,synthesis,provenance,attemptId)},afterCommit:async()=>applyPhaseCouncilReward(workingDir,synthesis,config3,ctx)}}})}});function invalidResponse2(issues){return JSON.stringify({success:!1,reason:"invalid arguments",errors:issues.map((issue3)=>({path:issue3.path.join("."),message:issue3.message}))},null,2)}async function applyPhaseCouncilReward(workingDir,synthesis,config3,ctx){try{let memoryConfig=config3.memory;if(memoryConfig?.enabled!==!0||!ctx?.sessionID)return;let provider=createConfiguredMemoryProvider(workingDir,memoryConfig);try{let summary={scope:"phase",phaseNumber:synthesis.phaseNumber,overallVerdict:synthesis.overallVerdict,allCriteriaMet:synthesis.allCriteriaMet,requiredFixesCount:synthesis.requiredFixes.length,roundNumber:synthesis.roundNumber,quorumSize:synthesis.quorumSize},verdictSynthesisJson=JSON.stringify(summary),cap2=memoryConfig.qLearning.verdictPayloadCapBytes;if(typeof cap2==="number"&&cap2>0&&verdictSynthesisJson.length>cap2)verdictSynthesisJson=JSON.stringify(truncateObjectForJson(summary,cap2));await applyCouncilReward(provider,{runId:ctx.sessionID,unitId:void 0,reward:COUNCIL_VERDICT_REWARDS[synthesis.overallVerdict],eta:memoryConfig.qLearning.learningRate,initialQValue:memoryConfig.qLearning.initialQValue,qLearning:memoryConfig.qLearning,verdictSynthesisJson,timestamp:new Date().toISOString(),verdictLabel:synthesis.overallVerdict})}finally{await provider.close?.()}}catch(error93){warn(`[submit-phase-council-verdicts] phase council reward capture failed: ${error93 instanceof Error?error93.message:String(error93)}`)}}function phaseEvidencePath2(workingDir,phaseNumber){return path298.join(workingDir,".swarm","evidence",String(phaseNumber),"phase-council.json")}function hasPhaseEvidenceAttempt(workingDir,phaseNumber,attemptId,round){try{let parsed=JSON.parse(readFileSync126(phaseEvidencePath2(workingDir,phaseNumber),"utf8"));return Boolean(parsed.entries?.some((entry)=>entry.type==="phase-council"&&entry.attemptId===attemptId&&entry.roundNumber===round))}catch{return!1}}async function writePhaseCouncilEvidence(workingDir,synthesis,provenance,attemptId){let evidenceFile=phaseEvidencePath2(workingDir,synthesis.phaseNumber);mkdirSync71(path298.dirname(evidenceFile),{recursive:!0});let content={entries:[{type:"phase-council",phase_number:synthesis.phaseNumber,scope:"phase",timestamp:synthesis.timestamp,verdict:synthesis.overallVerdict,quorumSize:synthesis.quorumSize,phaseSummary:synthesis.phaseSummary??"",requiredFixes:synthesis.requiredFixes,advisoryNotes:synthesis.advisoryNotes,advisoryFindings:synthesis.advisoryFindings,roundNumber:synthesis.roundNumber,allCriteriaMet:synthesis.allCriteriaMet,attemptId,...provenance?{provenance}:{}}]},tempFile=`${evidenceFile}.tmp-${Date.now()}`;try{writeFileSync50(tempFile,JSON.stringify(content,null,2),"utf8"),renameSync40(tempFile,evidenceFile),invalidateCachedArtifact(evidenceFile)}finally{if(existsSync154(tempFile))unlinkSync41(tempFile)}}function getPhaseMutationGapFinding(phaseNumber,workingDir){let mutationGatePath=path298.join(workingDir,".swarm","evidence",String(phaseNumber),"mutation-gate.json"),mutationGateLocation=`.swarm/evidence/${phaseNumber}/mutation-gate.json`;try{let entry=JSON.parse(readFileSync126(mutationGatePath,"utf8")).entries?.find((candidate2)=>candidate2.type==="mutation-gate");if(!entry)return mutationFinding("HIGH",mutationGateLocation,"Mutation gate evidence is missing a mutation-gate entry.");if(entry.verdict==="skip")return mutationFinding("MEDIUM",mutationGateLocation,"Mutation testing was skipped.");if(entry.verdict==="warn")return mutationFinding("LOW",mutationGateLocation,"Mutation gate reported WARN.");if(entry.verdict==="fail")return mutationFinding("HIGH",mutationGateLocation,"Mutation gate reported FAIL.");return null}catch(error93){let missing=error93.code==="ENOENT";return mutationFinding(missing?"HIGH":"MEDIUM",mutationGateLocation,missing?"Mutation gate evidence is missing.":"Mutation gate evidence could not be read.",error93 instanceof Error?error93.message:String(error93))}}function mutationFinding(severity,location,detail,evidence2=detail){return{severity,category:"mutation_gap",location,detail,evidence:evidence2}}function addMutationGapFindingToSynthesis(synthesis,finding){if(["CRITICAL","HIGH","MEDIUM"].includes(finding.severity))synthesis.requiredFixes.push(finding);else synthesis.advisoryFindings.push(finding);synthesis.unifiedFeedbackMd+=`
6641
6649
 
6642
6650
  ### Mutation Coverage Gap
6643
6651
  - **[${finding.severity}]** \`${finding.location}\` (${finding.category}) — ${finding.detail}