opencode-swarm 7.198.0 → 7.198.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/binaries/win32-arm64/swarm-sandbox-runner.exe +0 -0
- package/binaries/win32-x64/swarm-sandbox-runner.exe +0 -0
- package/dist/cli/{auto-checkpoint-3mmvyd3g.js → auto-checkpoint-ekp5j5v5.js} +4 -4
- package/dist/cli/{checkpoint-e43t6f2b.js → checkpoint-30yrbqee.js} +8 -8
- package/dist/cli/{coder-settlement-kb2827hb.js → coder-settlement-t3zcgsd6.js} +3 -3
- package/dist/cli/{config-doctor-06jwks34.js → config-doctor-6w105xpy.js} +7 -7
- package/dist/cli/{core-sqqs0k1q.js → core-6hyt1hg6.js} +1 -1
- package/dist/cli/{curator-dm4nm95q.js → curator-bzy7cess.js} +25 -25
- package/dist/cli/{curator-drift-0502msxm.js → curator-drift-z83e3a60.js} +5 -5
- package/dist/cli/{curator-llm-factory-54v33gz2.js → curator-llm-factory-ykpty14a.js} +25 -25
- package/dist/cli/{doctor-knowledge-receipt-phase-id-zm56sg6v.js → doctor-knowledge-receipt-phase-id-8av1860z.js} +4 -4
- package/dist/cli/{evidence-summary-service-ejmywz5a.js → evidence-summary-service-ym7y7w5k.js} +9 -9
- package/dist/cli/{gate-evidence-rqev8f8q.js → gate-evidence-vvhtzwry.js} +2 -2
- package/dist/cli/{guardrail-explain-0z5cyah2.js → guardrail-explain-1ethgkvp.js} +26 -26
- package/dist/cli/{guardrail-log-yjbyf5sc.js → guardrail-log-4f0jxq61.js} +3 -3
- package/dist/cli/{guardrail-reset-4zrb40d3.js → guardrail-reset-cqq3yk9s.js} +25 -25
- package/dist/cli/{hive-promoter-swgaebae.js → hive-promoter-vvgdsx8s.js} +25 -25
- package/dist/cli/{index-pn6xqhp2.js → index-0ap067j7.js} +1 -1
- package/dist/cli/{index-gyz3kvvm.js → index-0y5yvag6.js} +6 -6
- package/dist/cli/{index-p44wgqhb.js → index-166xny29.js} +65 -64
- package/dist/cli/{index-006b796n.js → index-59w9zfc5.js} +1 -1
- package/dist/cli/{index-pfwhq6p5.js → index-5h5tj8wc.js} +27 -27
- package/dist/cli/{index-z127nfqd.js → index-5hbb3088.js} +1 -1
- package/dist/cli/{index-9628q121.js → index-6pc5j9rb.js} +3 -3
- package/dist/cli/{index-rjcxke49.js → index-7e9mqse6.js} +1 -1
- package/dist/cli/{index-9fdddqtn.js → index-9keabj7d.js} +3 -3
- package/dist/cli/{index-hh0at0tt.js → index-bczx8jcg.js} +3 -3
- package/dist/cli/{index-pkdyys9n.js → index-bd4szzja.js} +1 -1
- package/dist/cli/{index-jj9kzye7.js → index-bj916p5e.js} +1 -1
- package/dist/cli/{index-q9zg0ckd.js → index-cfs1k1eh.js} +1 -1
- package/dist/cli/{index-c4fkfbfz.js → index-d9jrzepr.js} +1 -1
- package/dist/cli/{index-ndvnxxbm.js → index-drf91t9h.js} +2 -2
- package/dist/cli/{index-gp9rhg5m.js → index-ehw0s6xa.js} +1 -1
- package/dist/cli/{index-730ajx2g.js → index-gc9dvmy7.js} +2 -2
- package/dist/cli/{index-rvn7wbj9.js → index-h86e4jp9.js} +1 -1
- package/dist/cli/{index-a71vh07f.js → index-hd3d7rcw.js} +3 -3
- package/dist/cli/{index-kpngvt4q.js → index-mx74665q.js} +2 -2
- package/dist/cli/{index-fv6eab1b.js → index-rfcb9f54.js} +1 -1
- package/dist/cli/{index-715d35v8.js → index-rnjtf5kn.js} +2 -2
- package/dist/cli/{index-qnkk509y.js → index-tnnxvq2f.js} +3 -3
- package/dist/cli/{index-fd105270.js → index-v85gn9jm.js} +2 -2
- package/dist/cli/{index-0caf038s.js → index-vjwmcxz4.js} +4 -4
- package/dist/cli/{index-wemkaxc2.js → index-wg1mt92h.js} +1 -1
- package/dist/cli/{index-f0hpw2f8.js → index-whmby20t.js} +25 -25
- package/dist/cli/{index-r5f6q2v4.js → index-xrghsqg3.js} +1 -1
- package/dist/cli/{index-rj4a1206.js → index-xxb2depv.js} +3 -3
- package/dist/cli/{index-vhcgtmpg.js → index-y81sw9vt.js} +5 -5
- package/dist/cli/index.js +26 -26
- package/dist/cli/{knowledge-escalator-rjcg7k03.js → knowledge-escalator-8hrnc4bd.js} +7 -7
- package/dist/cli/{knowledge-events-rnf6kgdn.js → knowledge-events-v2abqt9z.js} +5 -5
- package/dist/cli/{knowledge-store-gm8j7krw.js → knowledge-store-9y17zzce.js} +1 -1
- package/dist/cli/{knowledge-validator-98456296.js → knowledge-validator-7red2zwb.js} +2 -2
- package/dist/cli/{mcp-ngs269rj.js → mcp-gbyndb15.js} +1 -1
- package/dist/cli/{model-preflight-g7yhtdrp.js → model-preflight-1tsaksc7.js} +25 -25
- package/dist/cli/{pending-delegations-dv9j31c3.js → pending-delegations-yg769m4y.js} +2 -2
- package/dist/cli/{pr-subscriptions-ya88xjph.js → pr-subscriptions-mc2mvjkj.js} +1 -1
- package/dist/cli/{pr-workflow-gate-wzatxzej.js → pr-workflow-gate-0fb280b2.js} +25 -25
- package/dist/cli/{scan-cursor-aygzmf34.js → scan-cursor-g74j6gcr.js} +2 -2
- package/dist/cli/{schema-eppnz9vx.js → schema-q2v7px9y.js} +1 -1
- package/dist/cli/{scope-persistence-v5bs3jqt.js → scope-persistence-g88f0163.js} +5 -5
- package/dist/cli/{server-t5vtzm9e.js → server-j3a7q7gg.js} +25 -25
- package/dist/cli/{skill-generator-mvm55q78.js → skill-generator-30bjrvcc.js} +8 -8
- package/dist/cli/{snapshot-coordination-init-ne7q5x7q.js → snapshot-coordination-init-9ekvft16.js} +25 -25
- package/dist/cli/{speckit-checkoff-pctc95h1.js → speckit-checkoff-sx24fz29.js} +3 -3
- package/dist/cli/{worktree-collision-ownership-cgvdsx3n.js → worktree-collision-ownership-shtk6dsk.js} +2 -2
- package/dist/cli/{worktree-isolation-afq0jh6n.js → worktree-isolation-x41cgd9n.js} +25 -25
- package/dist/hooks/guardrails/tool-before.d.ts +5 -2
- package/dist/index.js +4 -4
- 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.198.0",description:"Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",main:"dist/index.js",types:"dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",default:"./dist/index.js"},"./package.json":"./package.json"},bin:{"opencode-swarm":"./dist/cli/index.js"},type:"module",engines:{bun:">=1.3.13",node:">=22.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/swarm-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/swarm-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","tests/fixtures/memory-recall-heldout","opencode-swarm.schema.json","README.md","LICENSE"],scripts:{clean:`bun -e "require('fs').rmSync('dist',{recursive:true,force:true})"`,build:"bun run clean && bun run scripts/generate-config-schema.ts && 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","validate:repo":"bun scripts/ci/repository-validation.ts","drift:check":"bun run scripts/drift-check.ts","check:pre-push":"bun run scripts/drift-check.ts --enforce --no-report && bun run check:registry-citations","schema:generate":"bun run scripts/generate-config-schema.ts","generate:commands-docs":"bun run scripts/generate-commands-docs.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:2669":"node scripts/repro-2669.mjs","repro:2670":"node scripts/repro-2670.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","repro:2487":"bun build scripts/repro-2487-parity-entry.ts --outdir dist-build-test/repro-2487 --target node --format esm && node scripts/repro-2487-parity.mjs","check:events":"bun run scripts/check-event-contract.ts","check:retention":"bun run scripts/check-retention-registry.ts","check:core-events":"bun run scripts/check-core-events-usage.ts","check:shell-audit":"bun run scripts/check-shell-audit-usage.ts","check:trajectory-store":"bun run scripts/check-trajectory-store-usage.ts","check:mock-cleanup":"bun run scripts/check-mock-cleanup.ts","check:invariants":"bun run scripts/check-invariants.ts","check:token-formula":"bun run scripts/check-token-formula.ts","check:cross-contamination":"bun run scripts/check-cross-contamination.ts","check:test-clock":"bun run scripts/check-test-clock.ts","check:test-file-cap":"bun run scripts/check-test-file-cap.ts","check:test-tmpdir":"bun run scripts/check-test-tmpdir.ts","check:bash-portability":"bun run scripts/check-bash-portability.ts","check:pending-fragment":"bun run scripts/check-pending-fragment.ts","check:gate-portability":"bun run scripts/check-gate-portability.ts","check:bare-spawn":"bun run scripts/check-bare-executable-spawn.ts","check:error-channel-discard":"bun run scripts/check-error-channel-discard.ts","check:path-identity":"bun run scripts/check-path-identity.ts","check:registry-citations":"bun run scripts/check-registry-citations.ts","check:memory-recall":"bun run scripts/memory-recall-regression.ts","check:retrieval-quality":"bun run scripts/retrieval-quality-regression.ts"},dependencies:{"@modelcontextprotocol/sdk":"^1.30.0","@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.3.6"},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"},peerDependencies:{"@xenova/transformers":"^2.17.2"},peerDependenciesMeta:{"@xenova/transformers":{optional:!0}}}});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, Python, Rust, Go, Dart, Ruby, PHP, and Java",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; with task_id, records the high-priority count as todo_scan gate evidence",agents:["architect","researcher","docs","explorer","coder"],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"]},authorize_pr_review_reentry:{description:"issue a one-use, identity-bound reviewer/test_engineer re-entry authorization for the active PR_REVIEW workflow (issue #2383)",agents:["architect"]},submit_pr_review_result:{description:"submit one child-bound typed result for an active PR-review base or micro discovery lane",agents:[],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},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), or as the sanctioned recovery for a bookkeeping-grade hashed-field repair under the critic-gate PLAN FREEZE rule (the reason must state which case applies)",agents:["architect"]},approve_retry_sounding_board:{description:"record a MANUAL critic_sounding_board gate entry to unblock the coder retry circuit-breaker gate when the sounding board returned APPROVED but the mechanical recorder missed it (issue #2703)",agents:["architect"]},recover_rework_task:{description:"recover a task wedged at rework_required when the reviewer/test_engineer verdict did not require a code change: write a supervised stage_a_passed so those gates can be re-dispatched without re-running the coder (issue #2755)",agents:["architect"]},recover_stage_a_task:{description:"recover a task wedged in the settlement-backed Stage A deadlock — workflow at idle/blocked while a COMMITTED accepted coder settlement and green post-settlement pre-check proof justify Stage A: write a settlement-backed stage_a_passed so reviewer/test_engineer can be dispatched, without re-running the coder (issue #2828)",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"]},invalidate_pr_feedback_publication:{description:"invalidate the armed PR_FEEDBACK publication generation so approved content can change, superseding every content-dependent approval and reopening the exact scoped rework + fresh-review path (issue #2108)",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, related-problems results) so the /swarm issue --trace workflow can satisfy its recurrence gate before commit-pr handoff",agents:["architect"]},record_branch_freshness:{description:"record the Phase 0 branch-freshness outcome (synced / behind:<n> / fetch-failed:<reason> plus optional user override) so the /swarm issue --trace workflow can pass its freshness gate before transitioning to PLAN (issue #2564)",agents:["architect"]},record_trace_validation:{description:"record one per-phase trace-check.sh validator outcome (phase, pass/fail, reviewedCommit, treeId) so the /swarm issue --trace workflow can satisfy its validator-receipt gate before commit-pr handoff (issue #2564)",agents:["architect"]},record_merge_approval:{description:"record the human merge approval bound to the exact PR head SHA so the /swarm issue --trace workflow reaches its terminal merge_approval_recorded state — recorded for audit only, never certified or driven by the plugin (issue #2564)",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; a destructive restore previews first and requires the confirm_token issued in the preview (#2946)",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; reviewer verdicts marked `UNVERIFIED` persist to the findings ledger as `PENDING` records routed back to the reviewer — do not resubmit a row whose verdict is already recorded",agents:["architect"]},pr_review_submission:{description:"submit a settled, head-bound PR review to GitHub through the gh PR Review API after the PR_REVIEW gate clears; architect-only, refuses while a gate is active or the run was aborted after settlement",agents:["architect"]},export_pr_review_partial_results:{description:"export the validated partial results of an ABORTED PR_REVIEW run as a partial, non-authoritative artifact bound per-item to receipt-authenticated findings; architect-only, requires the gate cleared and an abort event binding session and head, never implies completion or feedback consent",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; test selection comes from explicit files (override) or source_files derived via the impact analyzer with a typed bounded fallback",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:"preflight every applicable phase gate, report all blockers, and atomically commit a current passing snapshot",agents:["architect"]},run_phase_review:{description:"run the bounded phase-final review engine and persist complete content-addressed review evidence",agents:["architect"]},repair_gate_evidence:{description:"quarantine recoverable exact-task gate evidence, rebuild from durable requirements, recover receipt-backed legacy marker wedges or the exact sentinel-only historical reset, and refuse every other receipt-less reconstruction",agents:["architect"]},repair_knowledge_receipt_ledger:{description:"validate or repair authoritative knowledge receipts, preserve corrupt authority in bounded quarantine, require scoped re-evaluation, and backfill stable phase ids across the whole ledger (operation backfill_phase_id; phase/session_id do not scope the backfill)",agents:["architect"]},record_directive_override:{description:"record an audited architect override for identified critical-directive violations without bypassing unreadable authority",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"]},scope_validate:{description:"validate shell writes against an inline file scope",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, usageSource (provider|estimated), model-limit with provenance (modelLimitSource: host|override|provider_cap|native|fallback; modelLimitResolution: user_provider_model|user_model|user_default|live_model_limit|static_provider_cap|static_native|static_default; fallbackActive: true when the denominator came from a static table or the flat 128k default — treat headroom as uncertain), 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 and the PR_FEEDBACK publication-generation section (state, attempts, invalidation reason, recovery guidance). For an active PR_REVIEW gate it also projects that derived state read-only: per-boundary settlement (post_explorer / post_reviewer / post_critic), per-lane coverage (accepted, rejected, one-line latest finding), and the bounded candidate inventory, each degrading to a typed unavailable state rather than an absence claim. 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","test_engineer"],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, profile hash, the calling session’s ratchet-tighter overrides, and the EFFECTIVE gates (profile merged with those overrides; durable across restart). 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_receipt_status:{description:"receipt status",agents:["architect"]},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_memory_outcome:{description:"record useful, dead-end, or corrected outcomes and, when enabled, synchronously refresh deterministic memory lessons",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; each lane agent must be a registered generated agent name (unregistered bare roles are refused on multi-swarm hosts); launch_timeout_ms is only a promptAsync acceptance budget, not a lane runtime timeout; poll incrementally with collect_lane_results (wait omitted), or join with wait: true for all results",agents:["architect"]},collect_lane_results:{description:"collect/poll a dispatch_lanes_async batch — OBSERVATION ONLY; it can never cancel or abort a lane. A presumed-stale sweep runs on every call, settling lanes past the horizon: idle host to stale, unobservable host to a typed liveness error. The wait budget (timeout_ms) bounds this observer call only — its expiry, a missing messages client, or a degraded liveness probe never kills a lane, never proves it died, and never settles anything. If a collection returns pending lanes, poll again first; busy/retry host status is live evidence, not failure. Cancellation is a distinct, explicit, authorized, potentially destructive action: use cancel_lane_batch (confirm: true + reason), never this tool. An explicit operator cancellation settles as the distinct operator_cancelled class — not liveness. Unsettled lanes are reported in pending_lanes (batch_id, lane_id, status, output_ref) regardless of include_pending. Does not advance workflow gates. Settled-lane inline output is delivered once: later polls set output_omitted_repeat: true and omit output but keep output_ref for retrieval via retrieve_lane_output.",agents:["architect"]},cancel_lane_batch:{description:"cancel ACTIVE lanes of a dispatch_lanes_async batch — the only cancellation surface (collect_lane_results cannot cancel). Destructive and authorization-gated: requires confirm: true + a bounded reason, recorded on cancelled terminals as the distinct operator_cancelled class (never liveness; not auto-retryable, never consumes retry budget — re-dispatch explicitly). Race-safe per lane: busy/retry refused (live work is never destroyed — human force path: /swarm abort-pr-workflow); degraded/absent status probe refuses the whole batch fail-closed; idle or host-unknown sessions may be cancelled; a child completing in the race window is preserved; an abort timeout never claims cancellation.",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_critic:{description:"dispatch a read-only critic agent to evaluate boundary conditions for a completed Lean Turbo phase (satisfies the turbo.lean.phase_critic gate)",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_next_wave:{description:"Epic Mode: the single, idempotent way forward while an epic is open. Closes the active wave once every task is resolved (recording per-task outcomes and declared-vs-actual divergence, which Epic learning uses to plan later waves), keeps phases in order, and issues the next wave of disjoint tasks with dispatch instructions. Returns a status: dispatch | declare-scopes | in-progress | blocked | phase-ready-for-review | epic-complete | refused. Requires `epic.mode.enabled: true` and an epic opened by `/swarm epic start`.",agents:[]},epic_phase_review:{description:"Epic Mode phase readiness: dispatch a read-only phase reviewer, then (only if it APPROVES) a read-only phase critic over the completed phase; parse both verdicts from the agents and record them to .swarm/evidence/{phase}/epic-phase-review.json. Required by phase_complete while an epic is open for the current plan; re-run after any fix (evidence is bound to the plan and phase task evidence).",agents:[]}},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 scanOverrideForDangerousKeys(value,path,depth){if(depth>=10)return;if(Array.isArray(value)){for(let i=0;i<value.length;i++)scanOverrideForDangerousKeys(value[i],`${path}[${i}]`,depth+1);return}if(typeof value!=="object"||value===null)return;for(let key of Object.keys(value)){if(DANGEROUS_MERGE_KEYS.has(key))throw new DangerousMergeKeyError(key,path);scanOverrideForDangerousKeys(value[key],`${path}.${key}`,depth+1)}}function deepMergeInternal(base,override,depth,path){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,`${path}.${key}`);else result[key]=overrideVal}return result}function deepMerge(base,override){if(!base)return override;if(!override)return base;return scanOverrideForDangerousKeys(override,"$",0),deepMergeInternal(base,override,0,"$")}var MAX_MERGE_DEPTH=10,DANGEROUS_MERGE_KEYS,DangerousMergeKeyError;var init_merge=__esm(()=>{DANGEROUS_MERGE_KEYS=new Set(["__proto__","constructor","prototype"]);DangerousMergeKeyError=class DangerousMergeKeyError extends Error{key;path;constructor(key,path){super(`deepMerge refused dangerous key "${key}" at "${path}": prototype-pollution carriers (__proto__/constructor/prototype) are never merged`);this.key=key;this.path=path;this.name="DangerousMergeKeyError"}}});function freezeSet(items,name="CLAUDE_CODE_NATIVE_COMMANDS"){let set=new Set(items),proxy=new Proxy(set,{get(target,prop){if(prop==="add"||prop==="delete"||prop==="clear")return()=>{throw TypeError(`${name} 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(`${name} is readonly`)},deleteProperty(){throw TypeError(`${name} is readonly`)},defineProperty(){throw TypeError(`${name} is readonly`)},setPrototypeOf(){throw TypeError(`${name} 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,OPENCODE_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,EPIC_TOOL_NAMES,EPIC_AGENT_TOOL_MAP,SKILL_TOOL_NAMES,SKILL_AGENT_TOOL_MAP,PR_REVIEW_CHILD_TOOL_NAMES,PR_REVIEW_CHILD_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.198.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",node:">=22.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/swarm-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/swarm-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","tests/fixtures/memory-recall-heldout","opencode-swarm.schema.json","README.md","LICENSE"],scripts:{clean:`bun -e "require('fs').rmSync('dist',{recursive:true,force:true})"`,build:"bun run clean && bun run scripts/generate-config-schema.ts && 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","validate:repo":"bun scripts/ci/repository-validation.ts","drift:check":"bun run scripts/drift-check.ts","check:pre-push":"bun run scripts/drift-check.ts --enforce --no-report && bun run check:registry-citations","schema:generate":"bun run scripts/generate-config-schema.ts","generate:commands-docs":"bun run scripts/generate-commands-docs.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:2669":"node scripts/repro-2669.mjs","repro:2670":"node scripts/repro-2670.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","repro:2487":"bun build scripts/repro-2487-parity-entry.ts --outdir dist-build-test/repro-2487 --target node --format esm && node scripts/repro-2487-parity.mjs","check:events":"bun run scripts/check-event-contract.ts","check:retention":"bun run scripts/check-retention-registry.ts","check:core-events":"bun run scripts/check-core-events-usage.ts","check:shell-audit":"bun run scripts/check-shell-audit-usage.ts","check:trajectory-store":"bun run scripts/check-trajectory-store-usage.ts","check:mock-cleanup":"bun run scripts/check-mock-cleanup.ts","check:invariants":"bun run scripts/check-invariants.ts","check:token-formula":"bun run scripts/check-token-formula.ts","check:cross-contamination":"bun run scripts/check-cross-contamination.ts","check:test-clock":"bun run scripts/check-test-clock.ts","check:test-file-cap":"bun run scripts/check-test-file-cap.ts","check:test-tmpdir":"bun run scripts/check-test-tmpdir.ts","check:bash-portability":"bun run scripts/check-bash-portability.ts","check:pending-fragment":"bun run scripts/check-pending-fragment.ts","check:gate-portability":"bun run scripts/check-gate-portability.ts","check:bare-spawn":"bun run scripts/check-bare-executable-spawn.ts","check:error-channel-discard":"bun run scripts/check-error-channel-discard.ts","check:path-identity":"bun run scripts/check-path-identity.ts","check:registry-citations":"bun run scripts/check-registry-citations.ts","check:memory-recall":"bun run scripts/memory-recall-regression.ts","check:retrieval-quality":"bun run scripts/retrieval-quality-regression.ts"},dependencies:{"@modelcontextprotocol/sdk":"^1.30.0","@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.3.6"},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"},peerDependencies:{"@xenova/transformers":"^2.17.2"},peerDependenciesMeta:{"@xenova/transformers":{optional:!0}}}});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, Python, Rust, Go, Dart, Ruby, PHP, and Java",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; with task_id, records the high-priority count as todo_scan gate evidence",agents:["architect","researcher","docs","explorer","coder"],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"]},authorize_pr_review_reentry:{description:"issue a one-use, identity-bound reviewer/test_engineer re-entry authorization for the active PR_REVIEW workflow (issue #2383)",agents:["architect"]},submit_pr_review_result:{description:"submit one child-bound typed result for an active PR-review base or micro discovery lane",agents:[],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},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), or as the sanctioned recovery for a bookkeeping-grade hashed-field repair under the critic-gate PLAN FREEZE rule (the reason must state which case applies)",agents:["architect"]},approve_retry_sounding_board:{description:"record a MANUAL critic_sounding_board gate entry to unblock the coder retry circuit-breaker gate when the sounding board returned APPROVED but the mechanical recorder missed it (issue #2703)",agents:["architect"]},recover_rework_task:{description:"recover a task wedged at rework_required when the reviewer/test_engineer verdict did not require a code change: write a supervised stage_a_passed so those gates can be re-dispatched without re-running the coder (issue #2755)",agents:["architect"]},recover_stage_a_task:{description:"recover a task wedged in the settlement-backed Stage A deadlock — workflow at idle/blocked while a COMMITTED accepted coder settlement and green post-settlement pre-check proof justify Stage A: write a settlement-backed stage_a_passed so reviewer/test_engineer can be dispatched, without re-running the coder (issue #2828)",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"]},invalidate_pr_feedback_publication:{description:"invalidate the armed PR_FEEDBACK publication generation so approved content can change, superseding every content-dependent approval and reopening the exact scoped rework + fresh-review path (issue #2108)",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, related-problems results) so the /swarm issue --trace workflow can satisfy its recurrence gate before commit-pr handoff",agents:["architect"]},record_branch_freshness:{description:"record the Phase 0 branch-freshness outcome (synced / behind:<n> / fetch-failed:<reason> plus optional user override) so the /swarm issue --trace workflow can pass its freshness gate before transitioning to PLAN (issue #2564)",agents:["architect"]},record_trace_validation:{description:"record one per-phase trace-check.sh validator outcome (phase, pass/fail, reviewedCommit, treeId) so the /swarm issue --trace workflow can satisfy its validator-receipt gate before commit-pr handoff (issue #2564)",agents:["architect"]},record_merge_approval:{description:"record the human merge approval bound to the exact PR head SHA so the /swarm issue --trace workflow reaches its terminal merge_approval_recorded state — recorded for audit only, never certified or driven by the plugin (issue #2564)",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; a destructive restore previews first and requires the confirm_token issued in the preview (#2946)",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; reviewer verdicts marked `UNVERIFIED` persist to the findings ledger as `PENDING` records routed back to the reviewer — do not resubmit a row whose verdict is already recorded",agents:["architect"]},pr_review_submission:{description:"submit a settled, head-bound PR review to GitHub through the gh PR Review API after the PR_REVIEW gate clears; architect-only, refuses while a gate is active or the run was aborted after settlement",agents:["architect"]},export_pr_review_partial_results:{description:"export the validated partial results of an ABORTED PR_REVIEW run as a partial, non-authoritative artifact bound per-item to receipt-authenticated findings; architect-only, requires the gate cleared and an abort event binding session and head, never implies completion or feedback consent",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; test selection comes from explicit files (override) or source_files derived via the impact analyzer with a typed bounded fallback",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:"preflight every applicable phase gate, report all blockers, and atomically commit a current passing snapshot",agents:["architect"]},run_phase_review:{description:"run the bounded phase-final review engine and persist complete content-addressed review evidence",agents:["architect"]},repair_gate_evidence:{description:"quarantine recoverable exact-task gate evidence, rebuild from durable requirements, recover receipt-backed legacy marker wedges or the exact sentinel-only historical reset, and refuse every other receipt-less reconstruction",agents:["architect"]},repair_knowledge_receipt_ledger:{description:"validate or repair authoritative knowledge receipts, preserve corrupt authority in bounded quarantine, require scoped re-evaluation, and backfill stable phase ids across the whole ledger (operation backfill_phase_id; phase/session_id do not scope the backfill)",agents:["architect"]},record_directive_override:{description:"record an audited architect override for identified critical-directive violations without bypassing unreadable authority",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"]},scope_validate:{description:"validate shell writes against an inline file scope",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, usageSource (provider|estimated), model-limit with provenance (modelLimitSource: host|override|provider_cap|native|fallback; modelLimitResolution: user_provider_model|user_model|user_default|live_model_limit|static_provider_cap|static_native|static_default; fallbackActive: true when the denominator came from a static table or the flat 128k default — treat headroom as uncertain), 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 and the PR_FEEDBACK publication-generation section (state, attempts, invalidation reason, recovery guidance). For an active PR_REVIEW gate it also projects that derived state read-only: per-boundary settlement (post_explorer / post_reviewer / post_critic), per-lane coverage (accepted, rejected, one-line latest finding), and the bounded candidate inventory, each degrading to a typed unavailable state rather than an absence claim. 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","test_engineer"],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, profile hash, the calling session’s ratchet-tighter overrides, and the EFFECTIVE gates (profile merged with those overrides; durable across restart). 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_receipt_status:{description:"receipt status",agents:["architect"]},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_memory_outcome:{description:"record useful, dead-end, or corrected outcomes and, when enabled, synchronously refresh deterministic memory lessons",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; each lane agent must be a registered generated agent name (unregistered bare roles are refused on multi-swarm hosts); launch_timeout_ms is only a promptAsync acceptance budget, not a lane runtime timeout; poll incrementally with collect_lane_results (wait omitted), or join with wait: true for all results",agents:["architect"]},collect_lane_results:{description:"collect/poll a dispatch_lanes_async batch — OBSERVATION ONLY; it can never cancel or abort a lane. A presumed-stale sweep runs on every call, settling lanes past the horizon: idle host to stale, unobservable host to a typed liveness error. The wait budget (timeout_ms) bounds this observer call only — its expiry, a missing messages client, or a degraded liveness probe never kills a lane, never proves it died, and never settles anything. If a collection returns pending lanes, poll again first; busy/retry host status is live evidence, not failure. Cancellation is a distinct, explicit, authorized, potentially destructive action: use cancel_lane_batch (confirm: true + reason), never this tool. An explicit operator cancellation settles as the distinct operator_cancelled class — not liveness. Unsettled lanes are reported in pending_lanes (batch_id, lane_id, status, output_ref) regardless of include_pending. Does not advance workflow gates. Settled-lane inline output is delivered once: later polls set output_omitted_repeat: true and omit output but keep output_ref for retrieval via retrieve_lane_output.",agents:["architect"]},cancel_lane_batch:{description:"cancel ACTIVE lanes of a dispatch_lanes_async batch — the only cancellation surface (collect_lane_results cannot cancel). Destructive and authorization-gated: requires confirm: true + a bounded reason, recorded on cancelled terminals as the distinct operator_cancelled class (never liveness; not auto-retryable, never consumes retry budget — re-dispatch explicitly). Race-safe per lane: busy/retry refused (live work is never destroyed — human force path: /swarm abort-pr-workflow); degraded/absent status probe refuses the whole batch fail-closed; idle or host-unknown sessions may be cancelled; a child completing in the race window is preserved; an abort timeout never claims cancellation.",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_critic:{description:"dispatch a read-only critic agent to evaluate boundary conditions for a completed Lean Turbo phase (satisfies the turbo.lean.phase_critic gate)",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_next_wave:{description:"Epic Mode: the single, idempotent way forward while an epic is open. Closes the active wave once every task is resolved (recording per-task outcomes and declared-vs-actual divergence, which Epic learning uses to plan later waves), keeps phases in order, and issues the next wave of disjoint tasks with dispatch instructions. Returns a status: dispatch | declare-scopes | in-progress | blocked | phase-ready-for-review | epic-complete | refused. Requires `epic.mode.enabled: true` and an epic opened by `/swarm epic start`.",agents:[]},epic_phase_review:{description:"Epic Mode phase readiness: dispatch a read-only phase reviewer, then (only if it APPROVES) a read-only phase critic over the completed phase; parse both verdicts from the agents and record them to .swarm/evidence/{phase}/epic-phase-review.json. Required by phase_complete while an epic is open for the current plan; re-run after any fix (evidence is bound to the plan and phase task evidence).",agents:[]}},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 scanOverrideForDangerousKeys(value,path,depth){if(depth>=10)return;if(Array.isArray(value)){for(let i=0;i<value.length;i++)scanOverrideForDangerousKeys(value[i],`${path}[${i}]`,depth+1);return}if(typeof value!=="object"||value===null)return;for(let key of Object.keys(value)){if(DANGEROUS_MERGE_KEYS.has(key))throw new DangerousMergeKeyError(key,path);scanOverrideForDangerousKeys(value[key],`${path}.${key}`,depth+1)}}function deepMergeInternal(base,override,depth,path){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,`${path}.${key}`);else result[key]=overrideVal}return result}function deepMerge(base,override){if(!base)return override;if(!override)return base;return scanOverrideForDangerousKeys(override,"$",0),deepMergeInternal(base,override,0,"$")}var MAX_MERGE_DEPTH=10,DANGEROUS_MERGE_KEYS,DangerousMergeKeyError;var init_merge=__esm(()=>{DANGEROUS_MERGE_KEYS=new Set(["__proto__","constructor","prototype"]);DangerousMergeKeyError=class DangerousMergeKeyError extends Error{key;path;constructor(key,path){super(`deepMerge refused dangerous key "${key}" at "${path}": prototype-pollution carriers (__proto__/constructor/prototype) are never merged`);this.key=key;this.path=path;this.name="DangerousMergeKeyError"}}});function freezeSet(items,name="CLAUDE_CODE_NATIVE_COMMANDS"){let set=new Set(items),proxy=new Proxy(set,{get(target,prop){if(prop==="add"||prop==="delete"||prop==="clear")return()=>{throw TypeError(`${name} 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(`${name} is readonly`)},deleteProperty(){throw TypeError(`${name} is readonly`)},defineProperty(){throw TypeError(`${name} is readonly`)},setPrototypeOf(){throw TypeError(`${name} 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,OPENCODE_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,EPIC_TOOL_NAMES,EPIC_AGENT_TOOL_MAP,SKILL_TOOL_NAMES,SKILL_AGENT_TOOL_MAP,PR_REVIEW_CHILD_TOOL_NAMES,PR_REVIEW_CHILD_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
|
|
|
@@ -1170,7 +1170,7 @@ in`);return tk},In(tk,iterable){if((iterable.behind(1)||tokens.mkToken("EMPTY"))
|
|
|
1170
1170
|
Expecting `+expected.join(", ")+", got '"+(this.terminals_[symbol3]||symbol3)+"'";else errStr="Parse error on line "+(yylineno+1)+": Unexpected "+(symbol3==EOF?"end of input":"'"+(this.terminals_[symbol3]||symbol3)+"'");this.parseError(errStr,{text:lexer.match,token:this.terminals_[symbol3]||symbol3,line:lexer.yylineno,loc:yyloc,expected})}if(action[0]instanceof Array&&action.length>1)throw Error("Parse Error: multiple actions possible at state: "+state2+", token: "+symbol3);switch(action[0]){case 1:if(stack.push(symbol3),vstack.push(lexer.yytext),lstack.push(lexer.yylloc),stack.push(action[1]),symbol3=null,!preErrorSymbol){if(yyleng=lexer.yyleng,yytext=lexer.yytext,yylineno=lexer.yylineno,yyloc=lexer.yylloc,recovering>0)recovering--}else symbol3=preErrorSymbol,preErrorSymbol=null;break;case 2:if(len=this.productions_[action[1]][1],yyval.$=vstack[vstack.length-len],yyval._$={first_line:lstack[lstack.length-(len||1)].first_line,last_line:lstack[lstack.length-1].last_line,first_column:lstack[lstack.length-(len||1)].first_column,last_column:lstack[lstack.length-1].last_column},ranges)yyval._$.range=[lstack[lstack.length-(len||1)].range[0],lstack[lstack.length-1].range[1]];if(r=this.performAction.apply(yyval,[yytext,yyleng,yylineno,sharedState.yy,action[1],vstack,lstack].concat(args2)),typeof r<"u")return r;if(len)stack=stack.slice(0,-1*len*2),vstack=vstack.slice(0,-1*len),lstack=lstack.slice(0,-1*len);stack.push(this.productions_[action[1]][0]),vstack.push(yyval.$),lstack.push(yyval._$),newState2=table[stack[stack.length-2]][stack[stack.length-1]],stack.push(newState2);break;case 3:return!0}}return!0}};function Parser(){this.yy={}}return Parser.prototype=parser2,parser2.Parser=Parser,new Parser}();if(typeof exports<"u")exports.parser=parser,exports.Parser=parser.Parser,exports.parse=function(){return parser.parse.apply(parser,arguments)},exports.main=function(args2){if(!args2[1])console.log("Usage: "+args2[0]+" FILE"),process.exit(1);var source=__require("fs").readFileSync(__require("path").normalize(args2[1]),"utf8");return exports.parser.parse(source)}});var require_posix=__commonJS((exports,module)=>{var astBuilder=require_ast_builder(),tokenizer=require_tokenizer(),phaseCatalog=require_rules(),grammarSource=require_grammar(),enums=require_enums(),lexerPhases=()=>[phaseCatalog.newLineList,phaseCatalog.operatorTokens,phaseCatalog.separator,phaseCatalog.reservedWords,phaseCatalog.linebreakIn,phaseCatalog.ioNumber,phaseCatalog.identifyMaybeSimpleCommands,phaseCatalog.assignmentWord,phaseCatalog.parameterExpansion,phaseCatalog.arithmeticExpansion,phaseCatalog.commandExpansion,phaseCatalog.forNameVariable,phaseCatalog.functionName,phaseCatalog.identifySimpleCommandNames,phaseCatalog.aliasSubstitution,phaseCatalog.tildeExpanding,phaseCatalog.parameterExpansion.resolve,phaseCatalog.commandExpansion.resolve,phaseCatalog.arithmeticExpansion.resolve,phaseCatalog.fieldSplitting.split,phaseCatalog.pathExpansion,phaseCatalog.quoteRemoval,phaseCatalog.syntaxerrorOnContinue,phaseCatalog.defaultNodeType];module.exports={inherits:null,init:(posixMode,utils)=>{let grammar=null;try{grammar=require_built_grammar()}catch(err){}return{enums,phaseCatalog,lexerPhases:lexerPhases(utils),tokenizer,grammarSource,grammar,astBuilder}}}});var require_word_expansion=__commonJS((exports,module)=>{var map3=require_map_iterable(),tokenOrEmpty=require_tokens().tokenOrEmpty,convertToWord=()=>map3((tk)=>{if(tk.is("TOKEN"))return tk.changeTokenType("WORD",tk.value);return tk});function start(state2,source,reducers){let char=source&&source.shift();if(char===void 0)return{nextReduction:reducers.end,tokensToEmit:tokenOrEmpty(state2),nextState:state2.resetCurrent().saveCurrentLocAsStart()};if(state2.escaping&&char===`
|
|
1171
1171
|
`)return{nextReduction:reducers.start,nextState:state2.setEscaping(!1).removeLastChar()};if(!state2.escaping&&char==="\\")return{nextReduction:reducers.start,nextState:state2.setEscaping(!0).appendChar(char)};if(!state2.escaping&&char==="'")return{nextReduction:reducers.singleQuoting,nextState:state2.appendChar(char)};if(!state2.escaping&&char==='"')return{nextReduction:reducers.doubleQuoting,nextState:state2.appendChar(char)};if(!state2.escaping&&char==="$")return{nextReduction:reducers.expansionStart,nextState:state2.appendChar(char).appendEmptyExpansion()};if(!state2.escaping&&char==="`")return{nextReduction:reducers.expansionCommandTick,nextState:state2.appendChar(char).appendEmptyExpansion()};return{nextReduction:reducers.start,nextState:state2.appendChar(char).setEscaping(!1)}}module.exports={inherits:"posix",init:(posixMode)=>{let phaseCatalog=posixMode.phaseCatalog,lexerPhases=[convertToWord,phaseCatalog.parameterExpansion,phaseCatalog.arithmeticExpansion,phaseCatalog.commandExpansion,phaseCatalog.tildeExpanding,phaseCatalog.parameterExpansion.resolve,phaseCatalog.commandExpansion.resolve,phaseCatalog.arithmeticExpansion.resolve,phaseCatalog.fieldSplitting.split,phaseCatalog.pathExpansion,phaseCatalog.quoteRemoval,phaseCatalog.defaultNodeType],reducers=Object.assign({},posixMode.tokenizer.reducers,{start});return Object.assign({},posixMode,{lexerPhases,tokenizer:()=>posixMode.tokenizer({},reducers)})}}});var require_src=__commonJS((exports,module)=>{var shellLexer=require_shell_lexer(),utils=require_utils2(),modes={bash:require_bash(),posix:require_posix(),"word-expansion":require_word_expansion()};function loadPlugin(name){let modePlugin=modes[name];if(modePlugin.inherits)return modePlugin.init(loadPlugin(modePlugin.inherits),utils);return modePlugin.init(null,utils)}module.exports=function(sourceCode,options){try{options=options||{},options.mode=options.mode||"posix";let mode=loadPlugin(options.mode),Parser=mode.grammar.Parser,astBuilder=mode.astBuilder,parser=new Parser;return parser.lexer=shellLexer(mode,options),parser.yy=astBuilder(options),parser.parse(sourceCode)}catch(err){if(err instanceof SyntaxError)throw err;throw Error(err.stack||err.message)}}});import*as path95 from"node:path";function unsafeShellCommandTextReason(value){return unsafePathTextReason(value.replace(/[\r\n]/g,""))}function mergeWriteAnalyses(primary,additional,additionalIsAuthoritative=!0,wrapperDeclared=!1){if(additional.writes.length===0&&!additional.hasWrites)return primary;let posixAuthoritative=wrapperDeclared?!1:!additionalIsAuthoritative||!primary.parseError,authority=posixAuthoritative?primary:additional,supplementary=posixAuthoritative?additional:primary,authorityConstructs=new Set(authority.writes.map((write)=>`${write.category}|${write.operator}`)),authorityKeys=new Set(authority.writes.map((write)=>buildDedupeKey(write.category,write.operator,write.path))),stripQuotes2=(p)=>p===null||p===void 0?p:p.replace(/^['"]+/,"").replace(/['"]+$/,""),isQuoteArtifact=(write)=>{let stripped=stripQuotes2(write.path);if(stripped===write.path)return!1;return authority.writes.some((other)=>other.category===write.category&&other.operator===write.operator&&stripQuotes2(other.path)===stripped)},seen=new Set,writes=[];for(let write of[...authority.writes,...supplementary.writes]){if(supplementary.writes.includes(write))if(wrapperDeclared){let construct=`${write.category}|${write.operator}`;if(authorityConstructs.has(construct))continue}else{let key3=buildDedupeKey(write.category,write.operator,write.path);if(authorityKeys.has(key3))continue;if(isQuoteArtifact(write))continue}let key2=buildDedupeKey(write.category,write.operator,write.path);if(seen.has(key2))continue;seen.add(key2),writes.push(write)}return{writes,hasWrites:writes.length>0||primary.hasWrites||additional.hasWrites,parseError:primary.parseError}}function buildDedupeKey(category,operator,path96){return`${category}|${operator}|${path96??"null"}`}function unquotedWordTokens(command){let tokens=[],current="",quote=null,flush=()=>{if(current.length>0)tokens.push(current);current=""};for(let i=0;i<command.length;i+=1){let ch=command[i];if(quote){if(ch===quote)quote=null;continue}if(ch==='"'||ch==="'"){flush(),quote=ch;continue}if(/\s/.test(ch)){flush();continue}current+=ch}return flush(),tokens.map((token)=>token.replace(/^[({]+/,"").replace(/[)}]+$/,""))}function isPowerShellShaped(command){if(!command)return!1;return unquotedWordTokens(command).some((token)=>{let lower=token.toLowerCase();return POWERSHELL_WRITE_CMDLETS.has(lower)||POWERSHELL_READ_ONLY_COMMANDS.has(lower)})}function isReadOnlyScriptBlockBody(body){if(/[()[\]=@|`;]/.test(body)||body.includes("::")||body.includes("$("))return!1;let tokens=body.match(/"[^"]*"|'[^']*'|\S+/g)?.map((token)=>token.replace(/^[({]+/,"").replace(/[)}]+$/,""))??[];if(tokens.length===0)return!1;for(let token of tokens){if(token===",")continue;if(/^(?:"[^"]*"|'[^']*')$/.test(token))continue;if(/^-?\d+(?:\.\d+)?$/.test(token))continue;if(READ_ONLY_SCRIPT_BLOCK_OPERATORS.has(token.toLowerCase()))continue;if(/^(?:\$_|\$this)(?:\.[A-Za-z_]\w*)*$/.test(token))continue;return!1}return!0}function extractScriptBlockBodies(command){let bodies=[],depth=0,start=-1,quote=null;for(let i=0;i<command.length;i+=1){let ch=command[i];if(quote){if(ch===quote)quote=null;continue}if(ch==='"'||ch==="'"){quote=ch;continue}if(ch==="{"){if(depth===0)start=i+1;depth+=1;continue}if(ch==="}"){if(depth-=1,depth<0)return null;if(depth===0&&start>=0)bodies.push(command.slice(start,i)),start=-1}}if(quote!==null||depth!==0)return null;return bodies}function isPowerShellReadOnlyPipeline(command){if(!command)return!1;if(/[>;&`\r\n]/.test(command)||/\$\(/.test(command))return!1;let quote=null,braceDepth=0;for(let ch of command){if(quote){if(ch===quote)quote=null;continue}if(ch==='"'||ch==="'"){quote=ch;continue}if(ch==="{")braceDepth+=1;if(ch==="}")braceDepth-=1;if(braceDepth<0)return!1}if(quote!==null||braceDepth!==0)return!1;for(let token of unquotedWordTokens(command)){let lower=token.toLowerCase();if(POWERSHELL_WRITE_CMDLETS.has(lower)||AMBIGUOUS_WRITE_ALIASES.has(lower)||POSIX_WRITE_TOKENS.has(lower))return!1;if((token==="sed"||token==="perl"||token==="awk")&&/(^|[\s'"])--?[a-zA-Z-]*(?:\bi|\bin-place|\bpi)\b/.test(command))return!1}let bodies=extractScriptBlockBodies(command);if(bodies===null)return!1;for(let body of bodies)if(!isReadOnlyScriptBlockBody(body))return!1;let segments=[],current="";quote=null;for(let i=0;i<command.length;i+=1){let ch=command[i];if(quote){if(ch===quote)quote=null;current+=ch;continue}if(ch==='"'||ch==="'"){quote=ch,current+=ch;continue}if(ch==="|"){segments.push(current),current="";continue}current+=ch}segments.push(current);for(let segment of segments){let tokens=unquotedWordTokens(segment.trim());if(tokens.length===0)return!1;if(!POWERSHELL_READ_ONLY_COMMANDS.has(tokens[0].toLowerCase()))return!1}return segments.length>0}function detectProcessSubstitutionWrites(command){let results=[],writeProcSubPattern=/>\s*\(([^)]+)\)/g;while(!0){let match=writeProcSubPattern.exec(command);if(match===null)break;let innerCommand=match[1].trim();if(!innerCommand)continue;let stages=innerCommand.split("|").map((s)=>s.trim());for(let stage of stages){let builtinResult=detectBuiltinWritesFromString(stage);if(builtinResult)results.push(builtinResult);let appendMatch=stage.match(/^\s*(.*?)\s*>>(\s*)(\S+)\s*$/);if(appendMatch){let path96=appendMatch[3];if(path96&&!isNullDevice(path96))results.push({category:"redirect",operator:">>",path:path96})}else{let writeMatch=stage.match(/^\s*(.*?)\s*>(?!>)(\s*)(\S+)\s*$/);if(writeMatch){let path96=writeMatch[3];if(path96&&!isNullDevice(path96))results.push({category:"redirect",operator:">",path:path96})}}}}return results}function detectBuiltinWritesFromString(cmd){let tokens=cmd.trim().split(/\s+/);if(tokens.length===0)return null;let name=tokens[0].toLowerCase();if(name==="rmdir"&&tokens.some((token)=>/^\/(?:s|q)$/i.test(token)))return null;if(BUILTIN_WRITE_COMMANDS.has(name)){for(let i=tokens.length-1;i>=1;i--)if(!tokens[i].startsWith("-"))return{category:"builtin_write",operator:name,path:tokens[i]}}return null}function wordText(node){if(!node||typeof node!=="object")return null;if(isBashWord(node))return node.text;return null}function isBashWord(node){return!!node&&typeof node==="object"&&node.type==="Word"&&typeof node.text==="string"}function annotateRawWordText(node,source){let unitIndex=null;if(/[\uD800-\uDFFF]/.test(source)){unitIndex=[];let u=0;for(let cp2 of source)unitIndex.push(u),u+=cp2.length;unitIndex.push(u)}let toUnit=(cp2)=>unitIndex===null?cp2:unitIndex[cp2],stack=[node],seen=new Set;while(stack.length>0){let n=stack.pop();if(!n||typeof n!=="object"||seen.has(n))continue;if(seen.add(n),isBashWord(n)){let loc=n.loc,start=loc?.start?.char,end=loc?.end?.char;if(typeof start==="number"&&typeof end==="number"&&end>=start){let from=toUnit(start),to=toUnit(end+1);if(from!==void 0&&to!==void 0)RAW_WORD_TEXT.set(n,source.slice(from,to))}}for(let value of Object.values(n))if(value&&typeof value==="object")stack.push(value)}}function hasUnquotedGlob(word){let projection=unquotedProjection(word);return projection===null||/[*?[]/.test(projection)}function hasUnquotedBraceExpansion(word,text){let projection=unquotedProjection(word);return BRACE_EXPANSION.test(projection===null?text:projection)}function unquotedProjection(word){if(!word||typeof word!=="object")return null;let raw=RAW_WORD_TEXT.get(word);if(raw===void 0)return null;let{projection,dequoted}=scanQuoting(raw),hasExpansion=Array.isArray(word.expansion)&&(word.expansion.length??0)>0,text=word.text;if(!hasExpansion&&dequoted!==text&&decodeParserEscapes(dequoted)!==text)return null;return projection}function scanQuoting(raw){let state2="none",projection="",dequoted="";for(let c=0;c<raw.length;c++){let ch=raw[c];if(state2==="single")if(ch==="'")state2="none";else dequoted+=ch,projection+="\x00";else if(ch==="\\"){let next=raw[c+1]??"";if(state2==="double"&&!/[$`"\\\n]/.test(next)){dequoted+=ch,projection+="\x00";continue}if(next!==`
|
|
1172
1172
|
`)dequoted+=next,projection+="\x00";c++}else if(ch==='"')state2=state2==="double"?"none":"double";else if(state2==="none"&&ch==="'")state2="single";else dequoted+=ch,projection+=state2==="none"?ch:"\x00"}return{projection,dequoted}}function decodeParserEscapes(s){return s.replace(/\\(?:x([0-9A-Fa-f]{2})|u([0-9A-Fa-f]{4})|U([0-9A-Fa-f]{8})|([0-7]{1,3})|([\\tnrbfv"']))/g,(m,x,u,big,octal,c)=>{let hex5=x??u??big;if(hex5!==void 0){let cp2=Number.parseInt(hex5,16);return cp2<=1114111?String.fromCodePoint(cp2):m}if(octal!==void 0)return String.fromCodePoint(Number.parseInt(octal,8));return PARSER_CHAR_ESCAPES[c]??c})}function collectLeafCommands(node,out){if(!node||typeof node!=="object")return;switch(node.type){case"Script":if(Array.isArray(node.commands))for(let cmd of node.commands)collectLeafCommands(cmd,out);break;case"Pipeline":case"Sequence":if(Array.isArray(node.commands))for(let cmd of node.commands)collectLeafCommands(cmd,out);break;case"CompoundList":if(out.push(node),Array.isArray(node.commands))for(let cmd of node.commands)collectLeafCommands(cmd,out);break;case"LogicalExpression":if(node.left)collectLeafCommands(node.left,out);if(node.right)collectLeafCommands(node.right,out);break;case"And":case"Or":if(node.left)collectLeafCommands(node.left,out);if(node.right)collectLeafCommands(node.right,out);break;case"Subshell":if(out.push(node),node.list)collectLeafCommands(node.list,out);break;case"ProcessSubstitution":{let opNode=node.op;if(opNode&&typeof opNode==="object"){if(opNode.type?.toUpperCase()==="GREAT"){if(node.command)collectLeafCommands(node.command,out)}}}break;case"If":if(out.push(node),node.clause)collectLeafCommands(node.clause,out);if(node.then)collectLeafCommands(node.then,out);if(node.else)collectLeafCommands(node.else,out);break;case"While":case"Until":if(out.push(node),node.clause)collectLeafCommands(node.clause,out);if(node.do)collectLeafCommands(node.do,out);break;case"For":if(out.push(node),node.do)collectLeafCommands(node.do,out);break;case"Case":if(out.push(node),Array.isArray(node.cases)){for(let entry of node.cases)if(entry?.body)collectLeafCommands(entry.body,out)}break;case"Function":if(out.push(node),node.body)collectLeafCommands(node.body,out);break;default:out.push(node);break}}function getCommandName(cmd){if(!cmd||typeof cmd!=="object")return null;let c=cmd;if(typeof c.name==="string")return c.name;return wordText(c.name)}function getSuffixWords(cmd){if(!cmd||typeof cmd!=="object")return[];let suffix=cmd.suffix;if(!Array.isArray(suffix))return[];let words=[];for(let s of suffix){let text=wordText(s);if(text!==null)words.push(text)}return words}function getSuffixWordExpansionFlags(cmd){if(!cmd||typeof cmd!=="object")return[];let suffix=cmd.suffix;if(!Array.isArray(suffix))return[];let flags=[];for(let s of suffix){if(!isBashWord(s))continue;let expansion=s.expansion;flags.push(Array.isArray(expansion)&&expansion.length>0)}return flags}function getSuffixWordUnquotedExpansionFlags(cmd){if(!cmd||typeof cmd!=="object")return[];let suffix=cmd.suffix;if(!Array.isArray(suffix))return[];let flags=[];for(let s of suffix){if(!isBashWord(s))continue;let expansion=s.expansion;if(!Array.isArray(expansion)||expansion.length===0){flags.push(!1);continue}let text=s.text,hasSubstitution=/\$\(|`/.test(text),hasListExpansion=/\$\{?[!#]?[A-Za-z0-9_]*(?:\[[@*]\]|@|\*)/.test(text)||/\$\{?[!#]?[@*]|\[[@*]\]/.test(text);if(hasSubstitution||hasListExpansion){flags.push(!0);continue}let quotedAt=[],state2="none";for(let c=0;c<text.length;c++){let ch=text[c];if(quotedAt[c]=state2!=="none",state2==="single"){if(ch==="'")state2="none"}else if(ch==="\\")quotedAt[c+1]=!0,c++;else if(ch==='"')state2=state2==="double"?"none":"double";else if(ch==="'"&&state2==="none")state2="single"}flags.push(expansion.some((e)=>{let start=e.loc?.start;return typeof start!=="number"||quotedAt[start]!==!0}))}return flags}function getRedirections(cmd){if(!cmd||typeof cmd!=="object")return[];let c=cmd;if(Array.isArray(c.redirections))return c.redirections;let results=[],suffix=c.suffix,prefix=c.prefix;if(Array.isArray(suffix)){for(let item of suffix)if(isRedirectNode(item))results.push(item)}if(Array.isArray(prefix)){for(let item of prefix)if(isRedirectNode(item))results.push(item)}return results}function isRedirectNode(node){return!!(node&&typeof node==="object"&&node.type==="Redirect")}function operatorLabel(op){if(!op||typeof op!=="object")return"unknown";let opType=op.type?.toUpperCase();switch(opType){case"GREAT":return">";case"DGREAT":return">>";case"CLOBBER":return">|";case"LESS":return"<";case"DLESS":return"<<";case"DLESSDASH":return"<<-";case"LESSAND":return"<&";case"GREATAND":return">&";case"LESSGREAT":return"<>";default:return opType||"unknown"}}function extractRedirectPath(fileNode){let text=wordText(fileNode);if(!text)return null;return text}function isNullDevice(path96){return path96==="/dev/null"||path96==="/dev/zero"||path96==="/dev/urandom"}function isNullDeviceWord(word,path96){if(!isNullDevice(path96)||!word||typeof word!=="object")return!1;let raw=RAW_WORD_TEXT.get(word);return raw!==void 0&&isNullDevice(scanQuoting(raw).dequoted)}function isNumeric(s){return/^\d+$/.test(s)}function isNonFileGreatAndTarget(path96){return path96!==null&&(isNumeric(path96)||path96==="-")}function detectRedirects(cmd){let results=[];results.push(...detectHereDocMarkers(cmd));let redirections=getRedirections(cmd);for(let redirect of redirections){if(!redirect||typeof redirect!=="object")continue;let r=redirect,opNode=r.op;if(!opNode||typeof opNode!=="object")continue;let opType=opNode.type?.toUpperCase();if(!opType||!REDIRECT_ALL_WRITE_TOKENS.has(opType))continue;let fileNode=r.file,path96=extractRedirectPath(fileNode),opLabel=operatorLabel(opNode);if(REDIRECT_WRITE_TOKENS.has(opType)||REDIRECT_GREATAND_TOKENS.has(opType)&&!isNonFileGreatAndTarget(path96)){if(path96!==null&&isNullDeviceWord(fileNode,path96))continue;results.push({category:"redirect",operator:opLabel,path:path96})}else if(REDIRECT_HERE_TOKENS.has(opType))results.push({category:"here_doc",operator:opLabel,path:path96})}return results}function detectHereDocMarkers(cmd){let results=[];if(!cmd||typeof cmd!=="object")return results;let suffix=cmd.suffix;if(!Array.isArray(suffix))return results;for(let item of suffix){if(!item||typeof item!=="object")continue;if(isHereDocMarker(item))results.push({category:"here_doc",operator:item.text==="<<-"?"<<-":"<<",path:null})}return results}function isHereDocMarker(node){if(!node||typeof node!=="object")return!1;let type=node.type?.toLowerCase();return type==="dless"||type==="dlessdash"}function detectBuiltinWrites(cmd){let results=[],name=getCommandName(cmd);if(!name)return results;let lowerName=name.toLowerCase();if(lowerName==="dd"){let suffixWords2=getSuffixWords(cmd);for(let word of suffixWords2)if(word.startsWith("of=")){let path96=word.slice(3);if(path96&&!isNullDevice(path96))results.push({category:"builtin_write",operator:"dd of=",path:path96})}return results}if(lowerName==="tee"){let suffixWords2=getSuffixWords(cmd),pastDoubleDash=!1;for(let word of suffixWords2){if(word==="--"){pastDoubleDash=!0;continue}if(!pastDoubleDash&&word.startsWith("-"))continue;if(word&&!isNullDevice(word))results.push({category:"builtin_write",operator:"tee",path:word})}return results}if(!BUILTIN_WRITE_COMMANDS.has(lowerName))return results;let suffixWords=getSuffixWords(cmd);if(lowerName==="rmdir"&&suffixWords.some((word)=>/^\/(?:s|q)$/i.test(word)))return results;if(lowerName==="truncate"){for(let word of suffixWords)if(!word.startsWith("-")&&!isNumeric(word)){results.push({category:"builtin_write",operator:"truncate",path:word});break}}else for(let i=suffixWords.length-1;i>=0;i--){let word=suffixWords[i];if(!word.startsWith("-")){results.push({category:"builtin_write",operator:name,path:word});break}}return results}function looksLikeSedScript(w){if(hasParentComponent(w)||/^[A-Za-z]:[\\/]/.test(w))return!1;return/^(?:(?:[0-9]+|\$)(?:,(?:[0-9]+|\$))?!?|!)[a-zA-Z=]$/.test(w)||/[;{}]/.test(w)&&!/[\\/:]/.test(w)&&!w.startsWith(".")||/^s([^A-Za-z0-9\s\\])(?:\\.|(?!\1)[^\\])*\1(?:\\.|(?!\1)[^\\])*\1[gpiImMe0-9]*$/.test(w)||/^y([^A-Za-z0-9\s\\])(?:\\.|(?!\1)[^\\])*\1(?:\\.|(?!\1)[^\\])*\1$/.test(w)}function hasParentComponent(w){return w.split(/[\\/]/).includes("..")}function detectInplaceEdit(cmd){let results=[],name=getCommandName(cmd);if(!name)return results;let lowerName=name.toLowerCase();if(!INPLACE_EDIT_COMMANDS.has(lowerName))return[];let suffixWords=getSuffixWords(cmd);if(!suffixWords.some((word)=>{if(lowerName==="sed")return word.startsWith("-i")&&word.length>1||/^--i(?:n(?:-(?:p(?:l(?:a(?:c(?:e)?)?)?)?)?)?)?(?:=|$)/.test(word);return word==="-i"||word.startsWith("-i")}))return[];let scriptPattern=/^[ssy]\/.*\/[gim]*$/,quotedScriptPattern=/^["'].*["']$/,isScriptShaped=(w)=>scriptPattern.test(w)&&!hasParentComponent(w),isScriptWord=(i)=>{let w=suffixWords[i];if(quotedScriptPattern.test(w))return unquotedExpansionFlags[i]!==!0&&isScriptShaped(w.slice(1,-1));return isScriptShaped(w)},flagArgs=lowerName==="sed"?new Set(["-e","-f","--expression","--file"]):lowerName==="perl"?new Set(["-e","-E"]):new Set(["-f","-e","-v","-F"]),combinedFlagArgs=/^-[0-9AacSlnpstTuUwWX]+[eE]$/,perlAttachedScript=/^-[0-9AacSlnpstTuUwWX]*[eE]./,sedScriptBundle=/^-[nrEszub]*[ef]$/,sedAttachedScript=/^-[nrEszub]*[ef]./,consumesNext=(w)=>flagArgs.has(w)||lowerName==="sed"&&sedScriptBundle.test(w)||lowerName==="perl"&&combinedFlagArgs.test(w),suppliesScript=(w)=>{if(lowerName==="awk")return w==="-f"||w==="-e"||/^-[fe]./.test(w)||w.startsWith("--file=")||w.startsWith("--source=");if(lowerName==="sed")return consumesNext(w)||sedAttachedScript.test(w)||/^--(?:expression|file)=/.test(w);return consumesNext(w)||perlAttachedScript.test(w)},expansionFlags=getSuffixWordExpansionFlags(cmd),unquotedExpansionFlags=getSuffixWordUnquotedExpansionFlags(cmd),suffixNodes=(Array.isArray(cmd.suffix)?cmd.suffix:[]).filter((s)=>wordText(s)!==null),mayExpandToSeveralWords=(i)=>unquotedExpansionFlags[i]===!0||hasUnquotedBraceExpansion(suffixNodes[i],suffixWords[i]),isKnownOption=(w)=>{if(w==="-"||w==="--")return!0;if(lowerName==="sed")return/^-[nrEszub]+$/.test(w)||/^-[nrEszub]*[ef]/.test(w)||/^-[nrEszub]*l/.test(w)||/^-i/.test(w)||SED_LONG_SWITCHES.has(w)||/^--(?:expression|file|line-length|in-place)(?:=|$)/.test(w);if(lowerName==="perl")return/^-[0-9AacSlnpstTuUwWX]*(?:[eE].*)?$/.test(w)||/^-i/.test(w)||/^-I./.test(w);return/^-[fevFil]/.test(w)||/^-[PcrSVh]$/.test(w)||AWK_LONG_SWITCHES.has(w)||/^--(?:file|source|lint)=/.test(w)},isOpaqueFlag=(i)=>suffixWords[i].startsWith("-")&&(mayExpandToSeveralWords(i)||!isKnownOption(suffixWords[i])),sedOptionArg=(w)=>lowerName==="sed"&&(/^-[nrEszub]*l$/.test(w)||w==="--line-length"),takesDetachedArg=(w)=>consumesNext(w)||sedOptionArg(w)||lowerName==="awk"&&w==="-i",fileArgOption=(w)=>lowerName==="sed"&&(/^-[nrEszub]*f$/.test(w)||w==="--file")||lowerName==="awk"&&(w==="-f"||w==="-i"),detachedArgMaySplit=(option,i)=>mayExpandToSeveralWords(i)||(fileArgOption(option)?/[*?[]/.test(suffixWords[i]):hasUnquotedGlob(suffixNodes[i])),permutes=lowerName==="sed",operandsFrom=suffixWords.length,optionArgs=new Set,expandingOptionArgs=new Set;for(let i=0;i<suffixWords.length;i++){let w=suffixWords[i];if(w==="--"){if(!permutes)operandsFrom=i+1;break}if(!w.startsWith("-")){if(!permutes){operandsFrom=i;break}continue}if(isOpaqueFlag(i)){if(!permutes){operandsFrom=i+1;break}continue}if(!takesDetachedArg(w))continue;if(i+1<suffixWords.length){if(optionArgs.add(i+1),detachedArgMaySplit(w,i+1)){if(expandingOptionArgs.add(i+1),!permutes){operandsFrom=i+2;break}}}i++}let inOptionArea=(i)=>i<operandsFrom,hasExplicitScript=!1;for(let i=0;i<suffixWords.length&&inOptionArea(i);i++){if(optionArgs.has(i))continue;let w=suffixWords[i];if(w==="--")break;if(!w.startsWith("-")||isOpaqueFlag(i))continue;if(expandingOptionArgs.has(i+1)){i++;continue}if(suppliesScript(w)){hasExplicitScript=!0;break}if(consumesNext(w)||lowerName==="awk"&&w==="-i")i++}let skipIndices=new Set,isDetachedSuffix=(w)=>lowerName==="sed"&&w!==void 0&&(w===""||w.startsWith(".")),isLiteralWord=(i)=>expansionFlags[i]!==!0&&!/[*?[]/.test(suffixWords[i])&&!/\{[^{}]*(?:,|\.\.)[^{}]*\}/.test(suffixWords[i]),isLiteralSedScript=(i)=>isLiteralWord(i)&&looksLikeSedScript(suffixWords[i]),isReportableWord=(i)=>suffixWords[i]!==""&&!isScriptWord(i)&&!isLiteralSedScript(i),firstPositionalFrom=(from)=>{let j=from;while(j<suffixWords.length&&(inOptionArea(j)&&suffixWords[j].startsWith("-")||optionArgs.has(j)))j++;return j},dashDash=suffixWords.findIndex((w,i)=>w==="--"&&!optionArgs.has(i)&&inOptionArea(i)),hasOpaqueFlag=suffixWords.some((_w,i)=>(dashDash<0||i<dashDash)&&inOptionArea(i)&&!optionArgs.has(i)&&isOpaqueFlag(i)),implicitScriptPlaced=hasOpaqueFlag||expandingOptionArgs.size>0;if(lowerName==="sed"&&!hasExplicitScript&&!implicitScriptPlaced)for(let i=0;i<suffixWords.length;i++){if(optionArgs.has(i))continue;let w=suffixWords[i];if(w==="--"||w.startsWith("-i")||w.startsWith("--in-place"))break;if(w.startsWith("-"))continue;if(!mayExpandToSeveralWords(i))skipIndices.add(i);implicitScriptPlaced=!0;break}let consumeImplicitScript=(from,bareInplace)=>{if(implicitScriptPlaced)return;implicitScriptPlaced=!0;let j=firstPositionalFrom(from);if(j>=suffixWords.length||mayExpandToSeveralWords(j))return;if(skipIndices.add(j),!bareInplace||!isDetachedSuffix(suffixWords[j]))return;let k=firstPositionalFrom(j+1);if(k>=suffixWords.length||!isLiteralSedScript(k))return;for(let m=firstPositionalFrom(k+1);m<suffixWords.length;){if(isReportableWord(m)){skipIndices.add(k);return}m=firstPositionalFrom(m+1)}},isConventionalBackupSuffix=(w)=>isDetachedSuffix(w)&&!w.includes("/")&&/^\.(?:bak|orig|old|save|backup|tmp|swp|~)$/i.test(w),dotWordAfterBareInplace=null,pastDoubleDash=!1,awkProgramSeen=!1;for(let i=0;i<suffixWords.length;i++){let word=suffixWords[i];if(optionArgs.has(i)){if(!expandingOptionArgs.has(i))skipIndices.add(i);continue}if(!pastDoubleDash&&word==="--"&&inOptionArea(i)){skipIndices.add(i),pastDoubleDash=!0;continue}if(!pastDoubleDash&&inOptionArea(i)&&word.startsWith("-")){if(isOpaqueFlag(i))continue;skipIndices.add(i);let next=suffixWords[i+1];if(lowerName==="sed"&&(word==="--in-place"||word.startsWith("--in-place="))){if(!hasExplicitScript)consumeImplicitScript(i+1,!1);continue}if(word==="-i"){if(next===void 0)continue;if(lowerName==="awk"){if(!expandingOptionArgs.has(i+1))skipIndices.add(i+1)}else if(!hasExplicitScript)consumeImplicitScript(i+1,!0);else if(isConventionalBackupSuffix(next))skipIndices.add(i+1),dotWordAfterBareInplace=next;continue}if(/^-i.+/.test(word)){if(lowerName!=="awk"&&!hasExplicitScript)consumeImplicitScript(i+1,!1);continue}if(consumesNext(word)||sedOptionArg(word)){if(next!==void 0&&!expandingOptionArgs.has(i+1))skipIndices.add(i+1)}continue}if(skipIndices.has(i))continue;if(lowerName==="awk"){if(!hasExplicitScript&&!hasOpaqueFlag&&expandingOptionArgs.size===0&&!awkProgramSeen)awkProgramSeen=!0,skipIndices.add(i);continue}if(isScriptWord(i))skipIndices.add(i)}let candidates=suffixWords.map((word,i)=>({word,i})).filter(({word,i})=>word!==""&&!skipIndices.has(i));if(candidates.length===0&&dotWordAfterBareInplace!==null)candidates.push({word:dotWordAfterBareInplace,i:-1});if(candidates.length>0)for(let{word}of candidates)results.push({category:"inplace_edit",operator:`${name} -i`,path:word});return results}function detectInterpreterEval(cmd){let results=[],name=getCommandName(cmd);if(!name)return results;let lowerName=name.toLowerCase();if(!INTERPRETER_EVAL_COMMANDS.has(lowerName))return[];let suffixWords=getSuffixWords(cmd),evalFlags={python:["-c"],python3:["-c"],python2:["-c"],node:["-e","-p","-pe"],bun:["-e","-p","-pe"],ruby:["-e"],perl:["-e","-E"],php:["-r","-R","-F"],bash:["-c"],sh:["-c"],dash:["-c"],zsh:["-c"],ksh:["-c"]};if(lowerName==="eval")return results.push({category:"interpreter_eval",operator:"eval",path:null}),results;let relevantFlags=evalFlags[lowerName]??[];if(!suffixWords.some((word)=>relevantFlags.some((f)=>word===f||word.startsWith(f)&&word.length>f.length)))return[];return results.push({category:"interpreter_eval",operator:`${name} [eval]`,path:null}),results}function detectNetworkDownloaders(cmd){let results=[],name=getCommandName(cmd);if(!name)return results;let lowerName=name.toLowerCase();if(!NETWORK_DOWNLOAD_COMMANDS.has(lowerName))return[];let suffixWords=getSuffixWords(cmd);if(lowerName==="curl")for(let i=0;i<suffixWords.length;i++){let word=suffixWords[i];if(word==="-o"&&i+1<suffixWords.length){let path96=suffixWords[i+1];if(!path96.startsWith("-"))results.push({category:"network_download",operator:"curl -o",path:path96})}else if(word.startsWith("-o")&&word.length>2)results.push({category:"network_download",operator:"curl -o",path:word.slice(2)})}else if(lowerName==="wget")for(let i=0;i<suffixWords.length;i++){let word=suffixWords[i];if(word==="-O"&&i+1<suffixWords.length){let path96=suffixWords[i+1];if(!path96.startsWith("-"))results.push({category:"network_download",operator:"wget -O",path:path96})}else if(word.startsWith("-O")&&word.length>2)results.push({category:"network_download",operator:"wget -O",path:word.slice(2)})}else if(lowerName==="scp")for(let i=suffixWords.length-1;i>=0;i--){let word=suffixWords[i];if(!word.startsWith("-")&&(word.includes(":")||word.startsWith("/")||word.startsWith("."))){results.push({category:"network_download",operator:"scp",path:word});break}}return results}function detectArchiveExtract(cmd){let results=[],name=getCommandName(cmd);if(!name)return results;let lowerName=name.toLowerCase();if(!ARCHIVE_EXTRACT_COMMANDS.has(lowerName))return[];let suffixWords=getSuffixWords(cmd);if(lowerName==="tar"){if(suffixWords.some((word)=>{if(word==="--extract"||word==="--get")return!0;if(word.startsWith("-")&&word.includes("x"))return!0;return!1}))for(let i=suffixWords.length-1;i>=0;i--){let word=suffixWords[i];if(!word.startsWith("-")){results.push({category:"archive_extract",operator:"tar -x",path:word});break}if(word.startsWith("--file=")&&word.length>7){results.push({category:"archive_extract",operator:"tar -x",path:word.slice(7)});break}}}else if(lowerName==="unzip")for(let i=suffixWords.length-1;i>=0;i--){let word=suffixWords[i];if(!word.startsWith("-")){results.push({category:"archive_extract",operator:"unzip",path:word});break}}else if(lowerName==="gunzip"||lowerName==="gzip"||lowerName==="bzip2"||lowerName==="xz"||lowerName==="7z"||lowerName==="rar"){if(suffixWords.includes("-d")||suffixWords.includes("--decompress")||lowerName==="gunzip")for(let i=suffixWords.length-1;i>=0;i--){let word=suffixWords[i];if(!word.startsWith("-")){results.push({category:"archive_extract",operator:`${name} [decompress]`,path:word});break}}}return results}function detectGitDestructive(cmd){let results=[],name=getCommandName(cmd);if(!name)return results;if(name.toLowerCase()!==GIT_COMMAND)return[];let suffixWords=getSuffixWords(cmd);if(suffixWords.length===0)return[];let first=suffixWords[0].toLowerCase();if(first==="checkout"){let dashDashIdx=suffixWords.indexOf("--");if(dashDashIdx!==-1&&dashDashIdx+1<suffixWords.length){let path96=suffixWords[dashDashIdx+1],op=path96==="."?"git checkout -- .":"git checkout --";results.push({category:"git_destructive",operator:op,path:path96})}}else if(first==="restore"){let hasHard=suffixWords.some((w)=>w==="--hard"||w==="-H"||w.startsWith("-")&&w.includes("H")),hasForce=suffixWords.some((w)=>w==="--force"||w==="-f"||w.startsWith("-")&&w.includes("f"));if(hasHard||hasForce){let dashDashIdx=suffixWords.indexOf("--");if(dashDashIdx!==-1&&dashDashIdx+1<suffixWords.length)results.push({category:"git_destructive",operator:"git restore",path:suffixWords[dashDashIdx+1]});else results.push({category:"git_destructive",operator:"git restore",path:null})}}else if(first==="reset"){if(suffixWords.some((w)=>w==="--hard"||w==="-H"||w.startsWith("-")&&w.includes("H")))results.push({category:"git_destructive",operator:"git reset --hard",path:null})}else if(first==="clean"){if(suffixWords.some((w)=>w==="-n"||w==="--dry-run"||w.startsWith("-")&&w.includes("n")))return results;let hasForce=suffixWords.some((w)=>w==="-f"||w==="--force"||w.startsWith("-")&&w.includes("f")),hasDir=suffixWords.some((w)=>w==="-d"||w==="--dir"||w.startsWith("-")&&w.includes("d"));if(hasForce&&hasDir)results.push({category:"git_destructive",operator:"git clean -fd",path:null})}return results}function splitWindowsCommands(command,shell){let commands=[],current="",inSingleQuote=!1,inDoubleQuote=!1,parenDepth=0;for(let i=0;i<command.length;i++){let ch=command[i];if(shell==="powershell"&&ch==="'"&&!inDoubleQuote)inSingleQuote=!inSingleQuote;else if(ch==='"'&&!inSingleQuote)inDoubleQuote=!inDoubleQuote;else if(ch==="("&&!inSingleQuote&&!inDoubleQuote)parenDepth++;else if(ch===")"&&!inSingleQuote&&!inDoubleQuote)parenDepth--;if(ch===`
|
|
1173
|
-
`&&!inSingleQuote&&!inDoubleQuote&&parenDepth===0){if(current.trim())commands.push(current.trim());current="";continue}if(shell==="powershell"&&(ch===";"||ch==="{"||ch==="}")&&!inSingleQuote&&!inDoubleQuote&&parenDepth===0){if(current.trim())commands.push(current.trim());current="";continue}if(ch==="|"&&!inSingleQuote&&!inDoubleQuote&&parenDepth===0){if(current.trim())commands.push(current.trim());current="";continue}if((ch==="&"||ch==="|")&&i+1<command.length&&command[i+1]===ch&&!inSingleQuote&&!inDoubleQuote&&parenDepth===0){if(current.trim())commands.push(current.trim());commands.push(ch==="&"?"&&":"||"),current="",i++;continue}if(ch==="&"&&!inSingleQuote&&!inDoubleQuote&&parenDepth===0){if(command[i-1]===">"){current+=ch;continue}if(!(i+1<command.length&&command[i+1]==="&")){if(current.trim())commands.push(current.trim());current="";continue}}current+=ch}if(current.trim())commands.push(current.trim());return commands.filter((c)=>c!=="&&"&&c!=="||")}function detectPowerShellRedirects(command){let results=[],inSingleQuote=!1,inDoubleQuote=!1,isBoundary=(character)=>character===void 0||/[\s;|&()]/.test(character);for(let index=0;index<command.length;index++){let character=command[index];if(inSingleQuote){if(character==="'")if(command[index+1]==="'")index++;else inSingleQuote=!1;continue}if(inDoubleQuote){if(character==="`"&&index+1<command.length){index++;continue}if(character==='"')inDoubleQuote=!1;continue}if(character==="'"){inSingleQuote=!0;continue}if(character==='"'){inDoubleQuote=!0;continue}if(character===">"&&command[index-1]==="^")continue;if(character!==">")continue;let operator=command[index+1]===">"?">>":">",cursor=index+operator.length;while(/\s/.test(command[cursor]??""))cursor++;if(command[cursor]==="&"){cursor++;while(/\s/.test(command[cursor]??""))cursor++;let descriptorStart=cursor;while(/\d/.test(command[cursor]??""))cursor++;if(command.slice(descriptorStart,cursor)&&isBoundary(command[cursor])){index=Math.max(index,cursor-1);continue}results.push({category:"redirect",operator,path:null}),index=Math.max(index,cursor-1);continue}let pathValue=null;if(cursor<command.length){let quote=command[cursor];if(quote==='"'||quote==="'"){cursor++;let pathStart=cursor,closed=!1;while(cursor<command.length){if(quote==='"'&&command[cursor]==="`"){cursor+=2;continue}if(command[cursor]===quote){if(quote==="'"&&command[cursor+1]==="'"){cursor+=2;continue}pathValue=command.slice(pathStart,cursor),cursor++,closed=!0;break}cursor++}if(!closed)pathValue=null}else{let pathStart=cursor;while(cursor<command.length&&!/\s|[;|&()<>]/.test(command[cursor]??""))cursor++;if(cursor>pathStart)pathValue=command.slice(pathStart,cursor)}}results.push({category:"redirect",operator,path:pathValue}),index=Math.max(index,cursor-1)}if(inSingleQuote||inDoubleQuote)results.push({category:"redirect",operator:">",path:null});return results}function detectPowerShellWrites(command){let results=[],trimmed=command.trim();if(!trimmed)return results;if(/^(?:powershell|pwsh)(?:\.exe)?\s+/i.test(trimmed)&&/(?:^|\s)-(?:e|ec|enc|encodedcommand)(?=\s|=|$)/i.test(trimmed))return results.push({category:"interpreter_eval",operator:"PowerShell -EncodedCommand",path:null}),results;let innerCommand=trimmed,cmdMatch=trimmed.match(new RegExp(`${PS_STRIP_PREFIX.source}(.*)$`,"i"));if(cmdMatch){if(innerCommand=cmdMatch[1].trim(),innerCommand.startsWith('"')&&innerCommand.endsWith('"')||innerCommand.startsWith("'")&&innerCommand.endsWith("'"))innerCommand=innerCommand.slice(1,-1)}if(/(?:^|[;{}|&])\s*(?:Set-Location|Push-Location|Pop-Location|cd|chdir|sl)\b/i.test(innerCommand))results.push({category:"builtin_write",operator:"working-directory mutation",path:null});if(/[({]\s*(?:Out-File|Set-Content|Add-Content|Clear-Content|Copy-Item|Move-Item|Remove-Item)\b/i.test(innerCommand))results.push({category:"interpreter_eval",operator:"nested PowerShell script block",path:null});if(/(?:^|[;|])\s*&\s*(?:['"$({]|\S+\s*\()/i.test(innerCommand)||/(?:^|[;|])\s*(?:Invoke-Expression|IEX)\b/i.test(innerCommand))results.push({category:"interpreter_eval",operator:"dynamic PowerShell invocation",path:null});results.push(...detectPowerShellRedirects(innerCommand));let iwrMatch=trimmed.match(/^(?:Invoke-WebRequest|curl)\s.*?(?:-OutFile\s+(\S+)|-o\s+(\S+))/i);if(iwrMatch){let path96=iwrMatch[1]||iwrMatch[2];if(path96)results.push({category:"network_download",operator:"Invoke-WebRequest -OutFile",path:path96})}function detectPsContentCmdlet(cmd){let cmdletMatch=cmd.match(/^(Out-File|Set-Content|Add-Content|Clear-Content)\b/i);if(!cmdletMatch)return[];let cmdletName=cmdletMatch[1],rest=cmd.slice(cmdletMatch[0].length).trim(),pathFlagMatch=rest.match(/(?:-Path|-FilePath|-LiteralPath)\s+((?:"[^"]*"|'[^']*'|[^,\s]+)(?:\s*,\s*(?:"[^"]*"|'[^']*'|[^,\s]+))*)/i);if(pathFlagMatch)return pathFlagMatch[1].split(/\s*,\s*/).map((value)=>value.replace(/^(["'])|(["'])$/g,"")).map((path96)=>({category:"redirect",operator:cmdletName,path:path96||null}));if(/(?:-Path|-FilePath|-LiteralPath)(?:\s|$)/i.test(rest))return[{category:"redirect",operator:cmdletName,path:null}];let tokens=rest.match(/(?:[^\s"-]+|"[^"]*"|'[^']*'|-[^\s]+)/g)??[];for(let token of tokens){if(token.startsWith("-"))continue;let path96=token.replace(/^["']|["']$/g,"");return[{category:"redirect",operator:cmdletName,path:path96}]}return[]}results.push(...detectPsContentCmdlet(innerCommand));let pipeContentMatch=innerCommand.match(/\|\s*(Out-File|Set-Content|Add-Content|Clear-Content)\b\s*(.*)$/i);if(pipeContentMatch){let cmdletName=pipeContentMatch[1],tokens=pipeContentMatch[2].trim().match(/(?:[^\s"-]+|"[^"]*"|'[^']*'|-[^\s]+)/g)??[];for(let token of tokens){if(token.startsWith("-"))continue;let path96=token.replace(/^["']|["']$/g,"");if(path96){results.push({category:"redirect",operator:cmdletName,path:path96});break}}}function detectPsFileOp(cmd){let opMatch=cmd.match(/^(Copy-Item|Move-Item|Remove-Item)\b/i);if(!opMatch)return null;let cmdletName=opMatch[1],rest=cmd.slice(opMatch[0].length).trim(),destFlagMatch=rest.match(/-Destination\s+(\S+|"[^"]+"|'[^']+')/i);if(destFlagMatch){let path96=destFlagMatch[1].replace(/^["']|["']$/g,"");return{category:"builtin_write",operator:cmdletName,path:path96}}let tokens=[],flagTakingValue=new Set(["-Path","-LiteralPath","-Exclude","-Include","-Filter"]),switchFlags=new Set(["-Recurse","-Force","-Confirm","-WhatIf","-PassThru","-Verbose","-Debug"]),parts=rest.match(/(?:[^\s"-]+|"[^"]*"|'[^']*'|-[^\s]+)/g)??[],i=0;while(i<parts.length){let part=parts[i];if(flagTakingValue.has(part)&&i+1<parts.length){let value=parts[i+1];if(!value.startsWith("-"))tokens.push(value);i+=2}else if(switchFlags.has(part))i++;else if(part.startsWith("-"))i++;else tokens.push(part),i++}if(tokens.length>=2){let path96=tokens[tokens.length-1].replace(/^["']|["']$/g,"");return{category:"builtin_write",operator:cmdletName,path:path96}}else if(tokens.length===1){let path96=tokens[0].replace(/^["']|["']$/g,"");return{category:"builtin_write",operator:cmdletName,path:path96}}return null}function detectPsNewItem(cmd){let opMatch=cmd.match(/^(?:New-Item|ni)\b/i);if(!opMatch)return null;let rest=cmd.slice(opMatch[0].length).trim(),SWITCH_FLAGS=new Set(["-force","-confirm","-whatif"]),VALUE_FLAGS=new Set(["-itemtype","-value","-description"]),PATH_FLAGS=new Set(["-path","-literalpath"]),tokens=rest.match(/"[^"]*"|'[^']*'|\S+/g)??[],unquote=(value)=>value.replace(/^["']|["']$/g,""),pathValue=null,nameValue=null,positional=null;for(let i=0;i<tokens.length;i+=1){let token=tokens[i],flag=token.toLowerCase();if(PATH_FLAGS.has(flag)){pathValue=unquote(tokens[i+1]??""),i+=1;continue}if(flag==="-name"){nameValue=unquote(tokens[i+1]??""),i+=1;continue}if(VALUE_FLAGS.has(flag)){i+=1;continue}if(SWITCH_FLAGS.has(flag))continue;if(flag.startsWith("-"))continue;if(positional===null)positional=unquote(token)}let basePath=(pathValue??positional)?.replace(/\/+$/,"")??null;if(basePath!==null&&nameValue){let base=basePath;return{category:"builtin_write",operator:"New-Item",path:base?`${base}/${nameValue}`:nameValue}}if(pathValue)return{category:"builtin_write",operator:"New-Item",path:pathValue};if(positional)return{category:"builtin_write",operator:"New-Item",path:positional};if(nameValue)return{category:"builtin_write",operator:"New-Item",path:nameValue};return{category:"builtin_write",operator:"New-Item",path:null}}let fileOp=detectPsFileOp(innerCommand)??detectPsNewItem(innerCommand);if(fileOp)results.push(fileOp);let pipeFileOpMatch=innerCommand.match(/\|\s*(Copy-Item|Move-Item)\b\s*(.*)$/i);if(pipeFileOpMatch){let cmdletName=pipeFileOpMatch[1],afterCmdlet=pipeFileOpMatch[2].trim(),destFlagMatch=afterCmdlet.match(/-Destination\s+(\S+|"[^"]+"|'[^']+')/i);if(destFlagMatch){let path96=destFlagMatch[1].replace(/^["']|["']$/g,"");results.push({category:"builtin_write",operator:cmdletName,path:path96})}else{let nonFlagTokens=(afterCmdlet.match(/(?:[^\s"-]+|"[^"]*"|'[^']*'|-[^\s]+)/g)??[]).filter((t)=>!t.startsWith("-")&&t.length>0);if(nonFlagTokens.length>0){let path96=nonFlagTokens[nonFlagTokens.length-1].replace(/^["']|["']$/g,"");results.push({category:"builtin_write",operator:cmdletName,path:path96})}}}return results}function tokenizeCmdArguments(command){let tokens=[],current="",inDoubleQuote=!1;for(let index=0;index<command.length;index++){let character=command[index];if(character==="^"&&!inDoubleQuote){if(index+1<command.length)current+=command[++index];continue}if(character==='"'){inDoubleQuote=!inDoubleQuote;continue}if(/\s/.test(character)&&!inDoubleQuote){if(current)tokens.push(current),current="";continue}current+=character}if(current)tokens.push(current);return tokens}function detectCmdRedirects(command){let results=[],inDoubleQuote=!1,isTokenBoundary=(character)=>character===void 0||/[\s&|()]/.test(character);for(let index=0;index<command.length;index++){let character=command[index];if(character==="^"&&!inDoubleQuote){index++;continue}if(character==='"'){inDoubleQuote=!inDoubleQuote;continue}if(inDoubleQuote||character!==">")continue;let operator=command[index+1]===">"?">>":">",cursor=index+operator.length;while(/\s/.test(command[cursor]??""))cursor++;if(command[cursor]==="&"){cursor++;while(/\s/.test(command[cursor]??""))cursor++;let descriptorStart=cursor;while(/\d/.test(command[cursor]??""))cursor++;if(command.slice(descriptorStart,cursor)&&isTokenBoundary(command[cursor])){index=Math.max(index,cursor-1);continue}results.push({category:"redirect",operator,path:null}),index=Math.max(index,cursor-1);continue}let pathValue=null;if(cursor<command.length){let quote=command[cursor];if(quote==='"'){let closingQuote=command.indexOf(quote,cursor+1);if(closingQuote!==-1)pathValue=command.slice(cursor+1,closingQuote),cursor=closingQuote+1}else{let pathStart=cursor;while(cursor<command.length&&!/[\s&|()<>]/.test(command[cursor]??""))cursor++;if(cursor>pathStart)pathValue=command.slice(pathStart,cursor)}}results.push({category:"redirect",operator,path:pathValue}),index=Math.max(index,cursor-1)}if(inDoubleQuote)results.push({category:"redirect",operator:">",path:null});return results}function detectCmdWrites(command){let results=[],trimmed=command.trim();if(!trimmed)return results;let innerCommand=trimmed,cmdWrapperMatch=trimmed.match(new RegExp(`${CMD_STRIP_PREFIX.source}(.*)$`,"i"));if(cmdWrapperMatch){if(innerCommand=cmdWrapperMatch[1].trim(),innerCommand.startsWith('"')&&innerCommand.endsWith('"')||innerCommand.startsWith("'")&&innerCommand.endsWith("'"))innerCommand=innerCommand.slice(1,-1)}if(/^(?:powershell|pwsh)(?:\.exe)?\s+/i.test(innerCommand))results.push(...detectPowerShellWrites(innerCommand));results.push(...detectCmdRedirects(innerCommand));function detectCmdCopy(cmd){let commandMatch=cmd.match(new RegExp(`^${CMD_BUILTIN_PREFIX.source}copy(?=\\s|$)`,"i"));if(commandMatch){let start=(commandMatch.index??0)+commandMatch[0].length,positional=tokenizeCmdArguments(cmd.slice(start)).filter((token)=>!_CMD_COPY_MOVE_SWITCHES.has(token.toLowerCase()));if(positional.length<2)return null;return{category:"builtin_write",operator:"copy",path:positional[positional.length-1]}}return null}function detectCmdMove(cmd){let commandMatch=cmd.match(new RegExp(`^${CMD_BUILTIN_PREFIX.source}move(?=\\s|$)`,"i"));if(commandMatch){let start=(commandMatch.index??0)+commandMatch[0].length,positional=tokenizeCmdArguments(cmd.slice(start)).filter((token)=>!_CMD_COPY_MOVE_SWITCHES.has(token.toLowerCase()));if(positional.length<2)return null;return{category:"builtin_write",operator:"move",path:positional[positional.length-1]}}return null}let copyResult=detectCmdCopy(innerCommand);if(copyResult)results.push(copyResult);let moveResult=detectCmdMove(innerCommand);if(moveResult)results.push(moveResult);let renMatch=innerCommand.match(/^ren\s+(\S+|"[^"]+"|'[^']+')\s+(\S+|"[^"]+"|'[^']+')/i);if(renMatch){let dest=(renMatch[2]||"").replace(/^["']|["']$/g,"");if(dest)results.push({category:"builtin_write",operator:"ren",path:dest})}function detectCmdDel(cmd){let delMatch=cmd.match(/^del\s+/i);if(!delMatch)return null;let tokens=(cmd.slice(delMatch[0].length).trim().match(/(\/?[^\s]+|"[^"]*"|'[^']*')/g)??[]).filter((t)=>!t.startsWith("/"));if(tokens.length>0)return{category:"builtin_write",operator:"del",path:tokens[0].replace(/^["']|["']$/g,"")};return null}let delResult=detectCmdDel(innerCommand);if(delResult)results.push(delResult);let rdMatch=innerCommand.match(/^rd\s+(?:\/s\s+|\/q\s+)*(\S+)/i);if(rdMatch){let path96=rdMatch[1].replace(/^["']|["']$/g,"");if(!path96.startsWith("/"))results.push({category:"builtin_write",operator:"rd",path:path96})}let mdMatch=trimmed.match(/^md\s+(\S+)/i);if(mdMatch){let path96=mdMatch[1].replace(/^["']|["']$/g,"");if(!path96.startsWith("/"))results.push({category:"builtin_write",operator:"md",path:path96})}return results}function detectInteractiveSession(command,shell){if(!command||typeof command!=="string")return!1;let trimmed=command.trim();if(shell==="posix"){let lower=trimmed.toLowerCase();if(/^watch(\s|$)/.test(lower))return!0;if(/^screen(\s|$)/.test(lower))return!0;if(/^tmux(\s+new-session(\s+.*)?)?$/.test(lower))return!0}else if(shell==="powershell"){if(/^Start-Process\s/i.test(trimmed))return!0}return!1}function detectPosixWrites(command){if(!command||typeof command!=="string")return{writes:[],hasWrites:!1};if(unsafeShellCommandTextReason(command))return{writes:[{category:"interpreter_eval",operator:"unsafe command text",path:null}],hasWrites:!0,parseError:!0};let ast,parseFailed=!1;try{ast=import_bash_parser.default(command,{mode:"posix",insertLOC:!0}),annotateRawWordText(ast,command)}catch{parseFailed=!0}let allWrites=[];if(!parseFailed&&ast&&typeof ast==="object"){let leafCommands=[];collectLeafCommands(ast,leafCommands);for(let cmd of leafCommands)allWrites.push(...detectRedirects(cmd)),allWrites.push(...detectBuiltinWrites(cmd)),allWrites.push(...detectInplaceEdit(cmd)),allWrites.push(...detectInterpreterEval(cmd)),allWrites.push(...detectNetworkDownloaders(cmd)),allWrites.push(...detectArchiveExtract(cmd)),allWrites.push(...detectGitDestructive(cmd))}if(parseFailed){let procSubWrites=detectProcessSubstitutionWrites(command);allWrites.push(...procSubWrites)}let seen=new Set,writes=allWrites.filter((wt)=>{let key2=buildDedupeKey(wt.category,wt.operator,wt.path);if(seen.has(key2))return!1;return seen.add(key2),!0});return{writes,hasWrites:writes.length>0,parseError:parseFailed&&writes.length===0?!0:void 0}}function detectWindowsWrites(command,shell){if(!command||typeof command!=="string")return{writes:[],hasWrites:!1};if(unsafeShellCommandTextReason(command))return{writes:[{category:"interpreter_eval",operator:"unsafe command text",path:null}],hasWrites:!0,parseError:!0};try{let subCommands=splitWindowsCommands(command,shell),allWrites=[];for(let subCmd of subCommands){let psWrites=detectPowerShellWrites(subCmd),psFiltered=shell==="powershell"?psWrites:psWrites.filter((w)=>w.operator!=="working-directory mutation");allWrites.push(...psFiltered);let cmdWrites=detectCmdWrites(subCmd),cmdFiltered=shell==="powershell"?cmdWrites.filter((w)=>w.category!=="redirect"):cmdWrites;allWrites.push(...cmdFiltered)}let stripQuotes2=(p)=>p===null||p===void 0?p:p.replace(/^['"]+/,"").replace(/['"]+$/,""),seen=new Set,seenStripped=[],writes=allWrites.filter((wt)=>{let key2=buildDedupeKey(wt.category,wt.operator,wt.path);if(seen.has(key2))return!1;let stripped=stripQuotes2(wt.path);if(stripped!==wt.path){if(seenStripped.some((other)=>other.category===wt.category&&other.operator===wt.operator&&stripQuotes2(other.path)===stripped))return!1}return seen.add(key2),seenStripped.push({category:wt.category,operator:wt.operator,path:wt.path}),!0});return{writes,hasWrites:writes.length>0}}catch{return{writes:[],hasWrites:!1,parseError:!0}}}function isDynamicPath(pathText){if(pathText===null||pathText===void 0)return!1;if(/\$[A-Za-z_][A-Za-z0-9_]*/.test(pathText))return!0;if(/\$\{[^}]+\}/.test(pathText))return!0;if(/%[A-Za-z_][A-Za-z0-9_]*%/.test(pathText))return!0;if(/\$\([^)]+\)/.test(pathText))return!0;if(/`[^`]+`/.test(pathText))return!0;if(/^~(?:[^/\\\s]*)?(?:[/\\]|$)/.test(pathText))return!0;if(/%~[A-Za-z]*(?:\d+|\*)/.test(pathText))return!0;if(/%(?:\d+|\*)/.test(pathText))return!0;return!1}function resolvePath(pathText,cwd){if(pathText===null)return null;if(isDynamicPath(pathText))return null;if(/^[a-zA-Z]:[\\\\/]/.test(cwd)||cwd.includes("\\"))return path95.win32.resolve(cwd,pathText);let normalizedRelativeWindowsPath=!path95.posix.isAbsolute(pathText)&&!/^[a-zA-Z]:[\\/]/.test(pathText)?pathText.replace(/\\/g,"/"):pathText;return path95.posix.resolve(cwd,normalizedRelativeWindowsPath)}function getCdTarget(cmd){if(!cmd||typeof cmd!=="object")return null;let c=cmd;if(c.type!=="SimpleCommand"&&c.type!=="Command")return null;let name=c.name;if(!name||typeof name!=="object")return null;let n=name;if(n.type!=="Word")return null;if(n.text!=="cd")return null;let suffix=c.suffix;if(!Array.isArray(suffix)||suffix.length===0)return null;let first=suffix[0];if(!first||typeof first!=="object")return null;let firstWord=first;if(firstWord.type!=="Word")return null;let target=firstWord.text;if(target==="-"||target==="~"||target==="~/")return null;return target}function collectWritesWithNodes(node,out,cwdStack){if(!node||typeof node!=="object")return;switch(node.type){case"Script":{let _globalCwd=cwdStack[0]??"/";if(Array.isArray(node.commands))for(let cmd of node.commands)collectWritesWithNodes(cmd,out,cwdStack);break}case"Subshell":{let effectiveCwd=cwdStack[0]??"/",subshellRedirs=node.redirections;if(Array.isArray(subshellRedirs))for(let redirect of subshellRedirs){let writesFromRedirect=getWritesFromRedirectNode(redirect,effectiveCwd);for(let w of writesFromRedirect)out.push({write:w,context:effectiveCwd})}if(node.list){let subStack=[...cwdStack];collectWritesWithNodes(node.list,out,subStack)}break}case"CompoundList":{if(Array.isArray(node.commands)){let currentStack=cwdStack;for(let cmd of node.commands){let cdTarget=getCdTarget(cmd);if(cdTarget)currentStack[0]=path95.posix.resolve(currentStack[0]??"/",cdTarget);else collectWritesWithNodes(cmd,out,currentStack)}}break}case"Pipeline":case"Sequence":{if(Array.isArray(node.commands))for(let cmd of node.commands)collectWritesWithNodes(cmd,out,cwdStack);break}case"LogicalExpression":{if(node.left){collectWritesWithNodes(node.left,out,cwdStack);let leftContext=cwdStack[0]??"/";if(node.right){let rightStack=[leftContext];collectWritesWithNodes(node.right,out,rightStack)}}break}case"And":case"Or":{if(node.left){collectWritesWithNodes(node.left,out,cwdStack);let leftContext=cwdStack[0]??"/";if(node.right){let rightStack=[leftContext];collectWritesWithNodes(node.right,out,rightStack)}}break}case"If":{let effectiveCwd=cwdStack[0]??"/";if(Array.isArray(node.redirections))for(let redirect of node.redirections)for(let w of getWritesFromRedirectNode(redirect,effectiveCwd))out.push({write:w,context:effectiveCwd});for(let body of[node.clause,node.then,node.else])if(body)collectWritesWithNodes(body,out,[...cwdStack]);break}case"While":case"Until":{let effectiveCwd=cwdStack[0]??"/";if(Array.isArray(node.redirections))for(let redirect of node.redirections)for(let w of getWritesFromRedirectNode(redirect,effectiveCwd))out.push({write:w,context:effectiveCwd});if(node.clause)collectWritesWithNodes(node.clause,out,[...cwdStack]);if(node.do)collectWritesWithNodes(node.do,out,[...cwdStack]);break}case"For":{let effectiveCwd=cwdStack[0]??"/";if(Array.isArray(node.redirections))for(let redirect of node.redirections)for(let w of getWritesFromRedirectNode(redirect,effectiveCwd))out.push({write:w,context:effectiveCwd});if(node.do)collectWritesWithNodes(node.do,out,[...cwdStack]);break}case"Case":{let effectiveCwd=cwdStack[0]??"/";if(Array.isArray(node.redirections))for(let redirect of node.redirections)for(let w of getWritesFromRedirectNode(redirect,effectiveCwd))out.push({write:w,context:effectiveCwd});if(Array.isArray(node.cases)){for(let entry of node.cases)if(entry?.body)collectWritesWithNodes(entry.body,out,[...cwdStack])}break}case"Function":{let effectiveCwd=cwdStack[0]??"/";if(Array.isArray(node.redirections))for(let redirect of node.redirections)for(let w of getWritesFromRedirectNode(redirect,effectiveCwd))out.push({write:w,context:effectiveCwd});if(node.body)collectWritesWithNodes(node.body,out,[...cwdStack]);break}case"Command":case"SimpleCommand":{let effectiveCwd=cwdStack[0]??"/",cdTarget=getCdTarget(node);if(cdTarget){cwdStack[0]=path95.posix.resolve(cwdStack[0]??"/",cdTarget);return}let writesFromRedirs=getWritesFromCommandRedirs(node,effectiveCwd);for(let w of writesFromRedirs)out.push({write:w,context:effectiveCwd});let builtinWrites=detectBuiltinWrites(node);for(let w of builtinWrites)out.push({write:w,context:effectiveCwd});let inplaceWrites=detectInplaceEdit(node);for(let w of inplaceWrites)out.push({write:w,context:effectiveCwd});let interpreterWrites=detectInterpreterEval(node);for(let w of interpreterWrites)out.push({write:w,context:effectiveCwd});let networkWrites=detectNetworkDownloaders(node);for(let w of networkWrites)out.push({write:w,context:effectiveCwd});let archiveWrites=detectArchiveExtract(node);for(let w of archiveWrites)out.push({write:w,context:effectiveCwd});let gitWrites=detectGitDestructive(node);for(let w of gitWrites)out.push({write:w,context:effectiveCwd});break}}}function getWritesFromRedirectNode(redirect,_context){if(!redirect||typeof redirect!=="object")return[];let r=redirect,opNode=r.op;if(!opNode||typeof opNode!=="object")return[];let opType=opNode.type?.toUpperCase();if(!opType||!REDIRECT_ALL_WRITE_TOKENS.has(opType))return[];let fileNode=r.file,path96=extractRedirectPath(fileNode),opLabel=operatorLabel(opNode);if(REDIRECT_WRITE_TOKENS.has(opType)||REDIRECT_GREATAND_TOKENS.has(opType)&&!isNonFileGreatAndTarget(path96)){if(path96!==null&&isNullDevice(path96))return[];return[{category:"redirect",operator:opLabel,path:path96}]}else if(REDIRECT_HERE_TOKENS.has(opType))return[{category:"here_doc",operator:opLabel,path:path96}];return[]}function getWritesFromCommandRedirs(cmd,context){if(!cmd||typeof cmd!=="object")return[];let c=cmd,results=[];results.push(...detectHereDocMarkers(cmd));let{suffix,prefix}=c;if(Array.isArray(suffix)){for(let item of suffix)if(isRedirectNode(item)){let writes=getWritesFromRedirectNode(item,context);results.push(...writes)}}if(Array.isArray(prefix)){for(let item of prefix)if(isRedirectNode(item)){let writes=getWritesFromRedirectNode(item,context);results.push(...writes)}}return results}function resolveWriteTargets(command,writes,cwd){if(!writes||writes.length===0)return[];if(!command||typeof command!=="string")return writes.map((original)=>({original,resolvedPath:resolvePath(original.path,cwd),resolved:original.path!==null&&!isDynamicPath(original.path)}));let ast;try{ast=import_bash_parser.default(command,{mode:"posix",insertLOC:!0}),annotateRawWordText(ast,command)}catch{ast=null}if(!ast||typeof ast!=="object")return writes.map((original)=>({original,resolvedPath:resolvePath(original.path,cwd),resolved:original.path!==null&&!isDynamicPath(original.path)}));let cwdStack=[cwd],writesWithNodes=[];collectWritesWithNodes(ast,writesWithNodes,cwdStack);let seen=new Set,deduplicated=writesWithNodes.filter((wwn)=>{let key2=buildDedupeKey(wwn.write.category,wwn.write.operator,wwn.write.path);if(seen.has(key2))return!1;return seen.add(key2),!0}),resolvedMap=new Map;for(let{write,context}of deduplicated){let resolvedPath=resolvePath(write.path,context),resolved=write.path!==null&&!isDynamicPath(write.path),key2=buildDedupeKey(write.category,write.operator,write.path);resolvedMap.set(key2,{resolvedPath,resolved})}return writes.map((original)=>{let key2=buildDedupeKey(original.category,original.operator,original.path),resolved=resolvedMap.get(key2);if(resolved)return{original,resolvedPath:resolved.resolvedPath,resolved:resolved.resolved};return{original,resolvedPath:resolvePath(original.path,cwd),resolved:original.path!==null&&!isDynamicPath(original.path)}})}var import_bash_parser,REDIRECT_WRITE_TOKENS,REDIRECT_HERE_TOKENS,REDIRECT_GREATAND_TOKENS,REDIRECT_ALL_WRITE_TOKENS,BUILTIN_WRITE_COMMANDS,INPLACE_EDIT_COMMANDS,SED_LONG_SWITCHES,AWK_LONG_SWITCHES,INTERPRETER_EVAL_COMMANDS,NETWORK_DOWNLOAD_COMMANDS,ARCHIVE_EXTRACT_COMMANDS,GIT_COMMAND="git",POWERSHELL_WRITE_CMDLETS,AMBIGUOUS_WRITE_ALIASES,POWERSHELL_READ_ONLY_COMMANDS,POSIX_WRITE_TOKENS,READ_ONLY_SCRIPT_BLOCK_OPERATORS,RAW_WORD_TEXT,BRACE_EXPANSION,PARSER_CHAR_ESCAPES,_CMD_COPY_MOVE_SWITCHES;var init_shell_write_detect=__esm(()=>{init_path_identity();init_shell_executor_context();import_bash_parser=__toESM(require_src(),1);REDIRECT_WRITE_TOKENS=new Set(["GREAT","DGREAT","CLOBBER","LESSGREAT"]),REDIRECT_HERE_TOKENS=new Set(["DLESS","DLESSDASH"]),REDIRECT_GREATAND_TOKENS=new Set(["GREATAND"]),REDIRECT_ALL_WRITE_TOKENS=new Set([...REDIRECT_WRITE_TOKENS,...REDIRECT_HERE_TOKENS,...REDIRECT_GREATAND_TOKENS]),BUILTIN_WRITE_COMMANDS=new Set(["cp","mv","install","ln","truncate","unlink","rmdir"]),INPLACE_EDIT_COMMANDS=new Set(["sed","perl","awk"]),SED_LONG_SWITCHES=new Set(["--quiet","--silent","--debug","--follow-symlinks","--binary","--posix","--regexp-extended","--separate","--sandbox","--unbuffered","--null-data","--zero-terminated","--help","--version"]),AWK_LONG_SWITCHES=new Set(["--posix","--traditional","--lint","--re-interval","--sandbox","--version","--help"]),INTERPRETER_EVAL_COMMANDS=new Set(["python","python3","python2","node","bun","ruby","perl","php","bash","sh","dash","zsh","ksh","eval"]),NETWORK_DOWNLOAD_COMMANDS=new Set(["curl","wget","scp"]),ARCHIVE_EXTRACT_COMMANDS=new Set(["tar","unzip","gunzip","gzip","bzip2","xz","7z","rar"]),POWERSHELL_WRITE_CMDLETS=new Set(["set-content","add-content","out-file","clear-content","copy-item","move-item","remove-item","new-item","ni","ac","sc","epcsv"]),AMBIGUOUS_WRITE_ALIASES=new Set(["cp","cpi","mv","rm","del","ren","rd","md","type"]),POWERSHELL_READ_ONLY_COMMANDS=new Set(["get-content","gc","get-item","gi","get-childitem","gci","get-location","pwd","get-command","get-member","get-date","get-help","get-itemproperty","select-string","select-object","where-object","foreach-object","sort-object","group-object","measure-object","compare-object","resolve-path","test-path","format-table","out-string","write-output","write-host","write-verbose","write-warning"]),POSIX_WRITE_TOKENS=new Set(["cp","mv","rm","rmdir","tee","dd","ln","touch","truncate","unlink","install"]);READ_ONLY_SCRIPT_BLOCK_OPERATORS=new Set(["-gt","-ge","-lt","-le","-eq","-ne","-match","-notmatch","-like","-notlike","-replace","-contains","-notcontains","-in","-notin","-is","-isnot","-join","-split","-f","-band","-bor","-bnot","-shl","-shr","-and","-or","-not","-xor"].map((op)=>op.toLowerCase()));RAW_WORD_TEXT=new WeakMap;BRACE_EXPANSION=/\{[^{}]*(?:,|\.\.)[^{}]*\}/;PARSER_CHAR_ESCAPES={t:"\t",n:`
|
|
1173
|
+
`&&!inSingleQuote&&!inDoubleQuote&&parenDepth===0){if(current.trim())commands.push(current.trim());current="";continue}if(shell==="powershell"&&(ch===";"||ch==="{"||ch==="}")&&!inSingleQuote&&!inDoubleQuote&&parenDepth===0){if(current.trim())commands.push(current.trim());current="";continue}if(ch==="|"&&!inSingleQuote&&!inDoubleQuote&&parenDepth===0){if(current.trim())commands.push(current.trim());current="";continue}if((ch==="&"||ch==="|")&&i+1<command.length&&command[i+1]===ch&&!inSingleQuote&&!inDoubleQuote&&parenDepth===0){if(current.trim())commands.push(current.trim());commands.push(ch==="&"?"&&":"||"),current="",i++;continue}if(ch==="&"&&!inSingleQuote&&!inDoubleQuote&&parenDepth===0){if(command[i-1]===">"){current+=ch;continue}if(!(i+1<command.length&&command[i+1]==="&")){if(current.trim())commands.push(current.trim());current="";continue}}current+=ch}if(current.trim())commands.push(current.trim());return commands.filter((c)=>c!=="&&"&&c!=="||")}function detectPowerShellRedirects(command){let results=[],inSingleQuote=!1,inDoubleQuote=!1,isBoundary=(character)=>character===void 0||/[\s;|&()]/.test(character);for(let index=0;index<command.length;index++){let character=command[index];if(inSingleQuote){if(character==="'")if(command[index+1]==="'")index++;else inSingleQuote=!1;continue}if(inDoubleQuote){if(character==="`"&&index+1<command.length){index++;continue}if(character==='"')inDoubleQuote=!1;continue}if(character==="'"){inSingleQuote=!0;continue}if(character==='"'){inDoubleQuote=!0;continue}if(character===">"&&command[index-1]==="^")continue;if(character!==">")continue;let operator=command[index+1]===">"?">>":">",cursor=index+operator.length;while(/\s/.test(command[cursor]??""))cursor++;if(command[cursor]==="&"){cursor++;while(/\s/.test(command[cursor]??""))cursor++;let descriptorStart=cursor;while(/\d/.test(command[cursor]??""))cursor++;if(command.slice(descriptorStart,cursor)&&isBoundary(command[cursor])){index=Math.max(index,cursor-1);continue}results.push({category:"redirect",operator,path:null}),index=Math.max(index,cursor-1);continue}let pathValue=null;if(cursor<command.length){let quote=command[cursor];if(quote==='"'||quote==="'"){cursor++;let pathStart=cursor,closed=!1;while(cursor<command.length){if(quote==='"'&&command[cursor]==="`"){cursor+=2;continue}if(command[cursor]===quote){if(quote==="'"&&command[cursor+1]==="'"){cursor+=2;continue}pathValue=command.slice(pathStart,cursor),cursor++,closed=!0;break}cursor++}if(!closed)pathValue=null}else{let pathStart=cursor;while(cursor<command.length&&!/\s|[;|&()<>]/.test(command[cursor]??""))cursor++;if(cursor>pathStart)pathValue=command.slice(pathStart,cursor)}}results.push({category:"redirect",operator,path:pathValue}),index=Math.max(index,cursor-1)}if(inSingleQuote||inDoubleQuote)results.push({category:"redirect",operator:">",path:null});return results}function detectPowerShellWrites(command){let results=[],trimmed=command.trim();if(!trimmed)return results;if(/^(?:powershell|pwsh)(?:\.exe)?\s+/i.test(trimmed)&&/(?:^|\s)-(?:e|ec|enc|encodedcommand)(?=\s|=|$)/i.test(trimmed))return results.push({category:"interpreter_eval",operator:"PowerShell -EncodedCommand",path:null}),results;let innerCommand=trimmed,cmdMatch=trimmed.match(new RegExp(`${PS_STRIP_PREFIX.source}(.*)$`,"i"));if(cmdMatch){if(innerCommand=cmdMatch[1].trim(),innerCommand.startsWith('"')&&innerCommand.endsWith('"')||innerCommand.startsWith("'")&&innerCommand.endsWith("'"))innerCommand=innerCommand.slice(1,-1)}if(/(?:^|[;{}|&])\s*(?:Set-Location|Push-Location|Pop-Location|cd|chdir|sl)\b/i.test(innerCommand))results.push({category:"builtin_write",operator:"working-directory mutation",path:null});if(/[({]\s*(?:Out-File|Set-Content|Add-Content|Clear-Content|Copy-Item|Move-Item|Remove-Item)\b/i.test(innerCommand))results.push({category:"interpreter_eval",operator:"nested PowerShell script block",path:null});if(/(?:^|[;|])\s*&\s*(?:['"$({]|\S+\s*\()/i.test(innerCommand)||/(?:^|[;|])\s*(?:Invoke-Expression|IEX)\b/i.test(innerCommand))results.push({category:"interpreter_eval",operator:"dynamic PowerShell invocation",path:null});results.push(...detectPowerShellRedirects(innerCommand));let iwrMatch=trimmed.match(/^(?:Invoke-WebRequest|curl)\s.*?(?:-OutFile\s+(\S+)|-o\s+(\S+))/i);if(iwrMatch){let path96=iwrMatch[1]||iwrMatch[2];if(path96)results.push({category:"network_download",operator:"Invoke-WebRequest -OutFile",path:path96})}function detectPsContentCmdlet(cmd){let cmdletMatch=cmd.match(/^(Out-File|Set-Content|Add-Content|Clear-Content)\b/i);if(!cmdletMatch)return[];let cmdletName=cmdletMatch[1],rest=cmd.slice(cmdletMatch[0].length).trim(),pathFlagMatch=rest.match(/(?:-Path|-FilePath|-LiteralPath)\s+((?:"[^"]*"|'[^']*'|[^,\s]+)(?:\s*,\s*(?:"[^"]*"|'[^']*'|[^,\s]+))*)/i);if(pathFlagMatch)return pathFlagMatch[1].split(/\s*,\s*/).map((value)=>value.replace(/^(["'])|(["'])$/g,"")).map((path96)=>({category:"redirect",operator:cmdletName,path:path96||null}));if(/(?:-Path|-FilePath|-LiteralPath)(?:\s|$)/i.test(rest))return[{category:"redirect",operator:cmdletName,path:null}];let tokens=rest.match(/(?:[^\s"-]+|"[^"]*"|'[^']*'|-[^\s]+)/g)??[];for(let token of tokens){if(token.startsWith("-"))continue;let path96=token.replace(/^["']|["']$/g,"");return[{category:"redirect",operator:cmdletName,path:path96}]}return[]}results.push(...detectPsContentCmdlet(innerCommand));let pipeContentMatch=innerCommand.match(/\|\s*(Out-File|Set-Content|Add-Content|Clear-Content)\b\s*(.*)$/i);if(pipeContentMatch){let cmdletName=pipeContentMatch[1],tokens=pipeContentMatch[2].trim().match(/(?:[^\s"-]+|"[^"]*"|'[^']*'|-[^\s]+)/g)??[];for(let token of tokens){if(token.startsWith("-"))continue;let path96=token.replace(/^["']|["']$/g,"");if(path96){results.push({category:"redirect",operator:cmdletName,path:path96});break}}}function detectPsFileOp(cmd){let opMatch=cmd.match(/^(Copy-Item|Move-Item|Remove-Item)\b/i);if(!opMatch)return null;let cmdletName=opMatch[1],rest=cmd.slice(opMatch[0].length).trim(),destFlagMatch=rest.match(/-Destination\s+(\S+|"[^"]+"|'[^']+')/i);if(destFlagMatch){let path96=destFlagMatch[1].replace(/^["']|["']$/g,"");return{category:"builtin_write",operator:cmdletName,path:path96}}let tokens=[],flagTakingValue=new Set(["-Path","-LiteralPath","-Exclude","-Include","-Filter"]),switchFlags=new Set(["-Recurse","-Force","-Confirm","-WhatIf","-PassThru","-Verbose","-Debug"]),parts=rest.match(/(?:[^\s"-]+|"[^"]*"|'[^']*'|-[^\s]+)/g)??[],i=0;while(i<parts.length){let part=parts[i];if(flagTakingValue.has(part)&&i+1<parts.length){let value=parts[i+1];if(!value.startsWith("-"))tokens.push(value);i+=2}else if(switchFlags.has(part))i++;else if(part.startsWith("-"))i++;else tokens.push(part),i++}if(tokens.length>=2){let path96=tokens[tokens.length-1].replace(/^["']|["']$/g,"");return{category:"builtin_write",operator:cmdletName,path:path96}}else if(tokens.length===1){let path96=tokens[0].replace(/^["']|["']$/g,"");return{category:"builtin_write",operator:cmdletName,path:path96}}return null}function detectPsNewItem(cmd){let opMatch=cmd.match(/^(?:New-Item|ni)\b/i);if(!opMatch)return null;let rest=cmd.slice(opMatch[0].length).trim(),SWITCH_FLAGS=new Set(["-force","-confirm","-whatif"]),VALUE_FLAGS=new Set(["-itemtype","-value","-description"]),PATH_FLAGS=new Set(["-path","-literalpath"]),tokens=rest.match(/"[^"]*"|'[^']*'|\S+/g)??[],unquote=(value)=>value.replace(/^["']|["']$/g,""),pathValue=null,nameValue=null,positional=null;for(let i=0;i<tokens.length;i+=1){let token=tokens[i],flag=token.toLowerCase();if(PATH_FLAGS.has(flag)){pathValue=unquote(tokens[i+1]??""),i+=1;continue}if(flag==="-name"){nameValue=unquote(tokens[i+1]??""),i+=1;continue}if(VALUE_FLAGS.has(flag)){i+=1;continue}if(SWITCH_FLAGS.has(flag))continue;if(flag.startsWith("-"))continue;if(positional===null)positional=unquote(token)}let basePath=(pathValue??positional)?.replace(/\/+$/,"")??null;if(basePath!==null&&nameValue){let base=basePath;return{category:"builtin_write",operator:"New-Item",path:base?`${base}/${nameValue}`:nameValue}}if(pathValue)return{category:"builtin_write",operator:"New-Item",path:pathValue};if(positional)return{category:"builtin_write",operator:"New-Item",path:positional};if(nameValue)return{category:"builtin_write",operator:"New-Item",path:nameValue};return{category:"builtin_write",operator:"New-Item",path:null}}let fileOp=detectPsFileOp(innerCommand)??detectPsNewItem(innerCommand);if(fileOp)results.push(fileOp);let pipeFileOpMatch=innerCommand.match(/\|\s*(Copy-Item|Move-Item)\b\s*(.*)$/i);if(pipeFileOpMatch){let cmdletName=pipeFileOpMatch[1],afterCmdlet=pipeFileOpMatch[2].trim(),destFlagMatch=afterCmdlet.match(/-Destination\s+(\S+|"[^"]+"|'[^']+')/i);if(destFlagMatch){let path96=destFlagMatch[1].replace(/^["']|["']$/g,"");results.push({category:"builtin_write",operator:cmdletName,path:path96})}else{let nonFlagTokens=(afterCmdlet.match(/(?:[^\s"-]+|"[^"]*"|'[^']*'|-[^\s]+)/g)??[]).filter((t)=>!t.startsWith("-")&&t.length>0);if(nonFlagTokens.length>0){let path96=nonFlagTokens[nonFlagTokens.length-1].replace(/^["']|["']$/g,"");results.push({category:"builtin_write",operator:cmdletName,path:path96})}}}return results}function tokenizeCmdArguments(command){let tokens=[],current="",inDoubleQuote=!1;for(let index=0;index<command.length;index++){let character=command[index];if(character==="^"&&!inDoubleQuote){if(index+1<command.length)current+=command[++index];continue}if(character==='"'){inDoubleQuote=!inDoubleQuote;continue}if(/\s/.test(character)&&!inDoubleQuote){if(current)tokens.push(current),current="";continue}current+=character}if(current)tokens.push(current);return tokens}function detectCmdRedirects(command){let results=[],inDoubleQuote=!1,isTokenBoundary=(character)=>character===void 0||/[;\s&|()]/.test(character);for(let index=0;index<command.length;index++){let character=command[index];if(character==="^"&&!inDoubleQuote){index++;continue}if(character==='"'){inDoubleQuote=!inDoubleQuote;continue}if(inDoubleQuote||character!==">")continue;let operator=command[index+1]===">"?">>":">",cursor=index+operator.length;while(/\s/.test(command[cursor]??""))cursor++;if(command[cursor]==="&"){cursor++;while(/\s/.test(command[cursor]??""))cursor++;let descriptorStart=cursor;while(/\d/.test(command[cursor]??""))cursor++;if(command.slice(descriptorStart,cursor)&&isTokenBoundary(command[cursor])){index=Math.max(index,cursor-1);continue}results.push({category:"redirect",operator,path:null}),index=Math.max(index,cursor-1);continue}let pathValue=null;if(cursor<command.length){let quote=command[cursor];if(quote==='"'){let closingQuote=command.indexOf(quote,cursor+1);if(closingQuote!==-1)pathValue=command.slice(cursor+1,closingQuote),cursor=closingQuote+1}else{let pathStart=cursor;while(cursor<command.length&&!/[\s&|()<>]/.test(command[cursor]??""))cursor++;if(cursor>pathStart)pathValue=command.slice(pathStart,cursor)}}results.push({category:"redirect",operator,path:pathValue}),index=Math.max(index,cursor-1)}if(inDoubleQuote)results.push({category:"redirect",operator:">",path:null});return results}function detectCmdWrites(command){let results=[],trimmed=command.trim();if(!trimmed)return results;let innerCommand=trimmed,cmdWrapperMatch=trimmed.match(new RegExp(`${CMD_STRIP_PREFIX.source}(.*)$`,"i"));if(cmdWrapperMatch){if(innerCommand=cmdWrapperMatch[1].trim(),innerCommand.startsWith('"')&&innerCommand.endsWith('"')||innerCommand.startsWith("'")&&innerCommand.endsWith("'"))innerCommand=innerCommand.slice(1,-1)}if(/^(?:powershell|pwsh)(?:\.exe)?\s+/i.test(innerCommand))results.push(...detectPowerShellWrites(innerCommand));results.push(...detectCmdRedirects(innerCommand));function detectCmdCopy(cmd){let commandMatch=cmd.match(new RegExp(`^${CMD_BUILTIN_PREFIX.source}copy(?=\\s|$)`,"i"));if(commandMatch){let start=(commandMatch.index??0)+commandMatch[0].length,positional=tokenizeCmdArguments(cmd.slice(start)).filter((token)=>!_CMD_COPY_MOVE_SWITCHES.has(token.toLowerCase()));if(positional.length<2)return null;return{category:"builtin_write",operator:"copy",path:positional[positional.length-1]}}return null}function detectCmdMove(cmd){let commandMatch=cmd.match(new RegExp(`^${CMD_BUILTIN_PREFIX.source}move(?=\\s|$)`,"i"));if(commandMatch){let start=(commandMatch.index??0)+commandMatch[0].length,positional=tokenizeCmdArguments(cmd.slice(start)).filter((token)=>!_CMD_COPY_MOVE_SWITCHES.has(token.toLowerCase()));if(positional.length<2)return null;return{category:"builtin_write",operator:"move",path:positional[positional.length-1]}}return null}let copyResult=detectCmdCopy(innerCommand);if(copyResult)results.push(copyResult);let moveResult=detectCmdMove(innerCommand);if(moveResult)results.push(moveResult);let renMatch=innerCommand.match(/^ren\s+(\S+|"[^"]+"|'[^']+')\s+(\S+|"[^"]+"|'[^']+')/i);if(renMatch){let dest=(renMatch[2]||"").replace(/^["']|["']$/g,"");if(dest)results.push({category:"builtin_write",operator:"ren",path:dest})}function detectCmdDel(cmd){let delMatch=cmd.match(/^del\s+/i);if(!delMatch)return null;let tokens=(cmd.slice(delMatch[0].length).trim().match(/(\/?[^\s]+|"[^"]*"|'[^']*')/g)??[]).filter((t)=>!t.startsWith("/"));if(tokens.length>0)return{category:"builtin_write",operator:"del",path:tokens[0].replace(/^["']|["']$/g,"")};return null}let delResult=detectCmdDel(innerCommand);if(delResult)results.push(delResult);let rdMatch=innerCommand.match(/^rd\s+(?:\/s\s+|\/q\s+)*(\S+)/i);if(rdMatch){let path96=rdMatch[1].replace(/^["']|["']$/g,"");if(!path96.startsWith("/"))results.push({category:"builtin_write",operator:"rd",path:path96})}let mdMatch=trimmed.match(/^md\s+(\S+)/i);if(mdMatch){let path96=mdMatch[1].replace(/^["']|["']$/g,"");if(!path96.startsWith("/"))results.push({category:"builtin_write",operator:"md",path:path96})}return results}function detectInteractiveSession(command,shell){if(!command||typeof command!=="string")return!1;let trimmed=command.trim();if(shell==="posix"){let lower=trimmed.toLowerCase();if(/^watch(\s|$)/.test(lower))return!0;if(/^screen(\s|$)/.test(lower))return!0;if(/^tmux(\s+new-session(\s+.*)?)?$/.test(lower))return!0}else if(shell==="powershell"){if(/^Start-Process\s/i.test(trimmed))return!0}return!1}function detectPosixWrites(command){if(!command||typeof command!=="string")return{writes:[],hasWrites:!1};if(unsafeShellCommandTextReason(command))return{writes:[{category:"interpreter_eval",operator:"unsafe command text",path:null}],hasWrites:!0,parseError:!0};let ast,parseFailed=!1;try{ast=import_bash_parser.default(command,{mode:"posix",insertLOC:!0}),annotateRawWordText(ast,command)}catch{parseFailed=!0}let allWrites=[];if(!parseFailed&&ast&&typeof ast==="object"){let leafCommands=[];collectLeafCommands(ast,leafCommands);for(let cmd of leafCommands)allWrites.push(...detectRedirects(cmd)),allWrites.push(...detectBuiltinWrites(cmd)),allWrites.push(...detectInplaceEdit(cmd)),allWrites.push(...detectInterpreterEval(cmd)),allWrites.push(...detectNetworkDownloaders(cmd)),allWrites.push(...detectArchiveExtract(cmd)),allWrites.push(...detectGitDestructive(cmd))}if(parseFailed){let procSubWrites=detectProcessSubstitutionWrites(command);allWrites.push(...procSubWrites)}let seen=new Set,writes=allWrites.filter((wt)=>{let key2=buildDedupeKey(wt.category,wt.operator,wt.path);if(seen.has(key2))return!1;return seen.add(key2),!0});return{writes,hasWrites:writes.length>0,parseError:parseFailed&&writes.length===0?!0:void 0}}function detectWindowsWrites(command,shell){if(!command||typeof command!=="string")return{writes:[],hasWrites:!1};if(unsafeShellCommandTextReason(command))return{writes:[{category:"interpreter_eval",operator:"unsafe command text",path:null}],hasWrites:!0,parseError:!0};try{let subCommands=splitWindowsCommands(command,shell),allWrites=[];for(let subCmd of subCommands){let psWrites=detectPowerShellWrites(subCmd),psFiltered=shell==="powershell"?psWrites:psWrites.filter((w)=>w.operator!=="working-directory mutation");allWrites.push(...psFiltered);let cmdWrites=detectCmdWrites(subCmd),cmdFiltered=shell==="powershell"?cmdWrites.filter((w)=>w.category!=="redirect"):cmdWrites;allWrites.push(...cmdFiltered)}let stripQuotes2=(p)=>p===null||p===void 0?p:p.replace(/^['"]+/,"").replace(/['"]+$/,""),seen=new Set,seenStripped=[],writes=allWrites.filter((wt)=>{let key2=buildDedupeKey(wt.category,wt.operator,wt.path);if(seen.has(key2))return!1;let stripped=stripQuotes2(wt.path);if(stripped!==wt.path){if(seenStripped.some((other)=>other.category===wt.category&&other.operator===wt.operator&&stripQuotes2(other.path)===stripped))return!1}return seen.add(key2),seenStripped.push({category:wt.category,operator:wt.operator,path:wt.path}),!0});return{writes,hasWrites:writes.length>0}}catch{return{writes:[],hasWrites:!1,parseError:!0}}}function isDynamicPath(pathText){if(pathText===null||pathText===void 0)return!1;if(/\$[A-Za-z_][A-Za-z0-9_]*/.test(pathText))return!0;if(/\$\{[^}]+\}/.test(pathText))return!0;if(/%[A-Za-z_][A-Za-z0-9_]*%/.test(pathText))return!0;if(/\$\([^)]+\)/.test(pathText))return!0;if(/`[^`]+`/.test(pathText))return!0;if(/^~(?:[^/\\\s]*)?(?:[/\\]|$)/.test(pathText))return!0;if(/%~[A-Za-z]*(?:\d+|\*)/.test(pathText))return!0;if(/%(?:\d+|\*)/.test(pathText))return!0;return!1}function resolvePath(pathText,cwd){if(pathText===null)return null;if(isDynamicPath(pathText))return null;if(/^[a-zA-Z]:[\\\\/]/.test(cwd)||cwd.includes("\\"))return path95.win32.resolve(cwd,pathText);let normalizedRelativeWindowsPath=!path95.posix.isAbsolute(pathText)&&!/^[a-zA-Z]:[\\/]/.test(pathText)?pathText.replace(/\\/g,"/"):pathText;return path95.posix.resolve(cwd,normalizedRelativeWindowsPath)}function getCdTarget(cmd){if(!cmd||typeof cmd!=="object")return null;let c=cmd;if(c.type!=="SimpleCommand"&&c.type!=="Command")return null;let name=c.name;if(!name||typeof name!=="object")return null;let n=name;if(n.type!=="Word")return null;if(n.text!=="cd")return null;let suffix=c.suffix;if(!Array.isArray(suffix)||suffix.length===0)return null;let first=suffix[0];if(!first||typeof first!=="object")return null;let firstWord=first;if(firstWord.type!=="Word")return null;let target=firstWord.text;if(target==="-"||target==="~"||target==="~/")return null;return target}function collectWritesWithNodes(node,out,cwdStack){if(!node||typeof node!=="object")return;switch(node.type){case"Script":{let _globalCwd=cwdStack[0]??"/";if(Array.isArray(node.commands))for(let cmd of node.commands)collectWritesWithNodes(cmd,out,cwdStack);break}case"Subshell":{let effectiveCwd=cwdStack[0]??"/",subshellRedirs=node.redirections;if(Array.isArray(subshellRedirs))for(let redirect of subshellRedirs){let writesFromRedirect=getWritesFromRedirectNode(redirect,effectiveCwd);for(let w of writesFromRedirect)out.push({write:w,context:effectiveCwd})}if(node.list){let subStack=[...cwdStack];collectWritesWithNodes(node.list,out,subStack)}break}case"CompoundList":{if(Array.isArray(node.commands)){let currentStack=cwdStack;for(let cmd of node.commands){let cdTarget=getCdTarget(cmd);if(cdTarget)currentStack[0]=path95.posix.resolve(currentStack[0]??"/",cdTarget);else collectWritesWithNodes(cmd,out,currentStack)}}break}case"Pipeline":case"Sequence":{if(Array.isArray(node.commands))for(let cmd of node.commands)collectWritesWithNodes(cmd,out,cwdStack);break}case"LogicalExpression":{if(node.left){collectWritesWithNodes(node.left,out,cwdStack);let leftContext=cwdStack[0]??"/";if(node.right){let rightStack=[leftContext];collectWritesWithNodes(node.right,out,rightStack)}}break}case"And":case"Or":{if(node.left){collectWritesWithNodes(node.left,out,cwdStack);let leftContext=cwdStack[0]??"/";if(node.right){let rightStack=[leftContext];collectWritesWithNodes(node.right,out,rightStack)}}break}case"If":{let effectiveCwd=cwdStack[0]??"/";if(Array.isArray(node.redirections))for(let redirect of node.redirections)for(let w of getWritesFromRedirectNode(redirect,effectiveCwd))out.push({write:w,context:effectiveCwd});for(let body of[node.clause,node.then,node.else])if(body)collectWritesWithNodes(body,out,[...cwdStack]);break}case"While":case"Until":{let effectiveCwd=cwdStack[0]??"/";if(Array.isArray(node.redirections))for(let redirect of node.redirections)for(let w of getWritesFromRedirectNode(redirect,effectiveCwd))out.push({write:w,context:effectiveCwd});if(node.clause)collectWritesWithNodes(node.clause,out,[...cwdStack]);if(node.do)collectWritesWithNodes(node.do,out,[...cwdStack]);break}case"For":{let effectiveCwd=cwdStack[0]??"/";if(Array.isArray(node.redirections))for(let redirect of node.redirections)for(let w of getWritesFromRedirectNode(redirect,effectiveCwd))out.push({write:w,context:effectiveCwd});if(node.do)collectWritesWithNodes(node.do,out,[...cwdStack]);break}case"Case":{let effectiveCwd=cwdStack[0]??"/";if(Array.isArray(node.redirections))for(let redirect of node.redirections)for(let w of getWritesFromRedirectNode(redirect,effectiveCwd))out.push({write:w,context:effectiveCwd});if(Array.isArray(node.cases)){for(let entry of node.cases)if(entry?.body)collectWritesWithNodes(entry.body,out,[...cwdStack])}break}case"Function":{let effectiveCwd=cwdStack[0]??"/";if(Array.isArray(node.redirections))for(let redirect of node.redirections)for(let w of getWritesFromRedirectNode(redirect,effectiveCwd))out.push({write:w,context:effectiveCwd});if(node.body)collectWritesWithNodes(node.body,out,[...cwdStack]);break}case"Command":case"SimpleCommand":{let effectiveCwd=cwdStack[0]??"/",cdTarget=getCdTarget(node);if(cdTarget){cwdStack[0]=path95.posix.resolve(cwdStack[0]??"/",cdTarget);return}let writesFromRedirs=getWritesFromCommandRedirs(node,effectiveCwd);for(let w of writesFromRedirs)out.push({write:w,context:effectiveCwd});let builtinWrites=detectBuiltinWrites(node);for(let w of builtinWrites)out.push({write:w,context:effectiveCwd});let inplaceWrites=detectInplaceEdit(node);for(let w of inplaceWrites)out.push({write:w,context:effectiveCwd});let interpreterWrites=detectInterpreterEval(node);for(let w of interpreterWrites)out.push({write:w,context:effectiveCwd});let networkWrites=detectNetworkDownloaders(node);for(let w of networkWrites)out.push({write:w,context:effectiveCwd});let archiveWrites=detectArchiveExtract(node);for(let w of archiveWrites)out.push({write:w,context:effectiveCwd});let gitWrites=detectGitDestructive(node);for(let w of gitWrites)out.push({write:w,context:effectiveCwd});break}}}function getWritesFromRedirectNode(redirect,_context){if(!redirect||typeof redirect!=="object")return[];let r=redirect,opNode=r.op;if(!opNode||typeof opNode!=="object")return[];let opType=opNode.type?.toUpperCase();if(!opType||!REDIRECT_ALL_WRITE_TOKENS.has(opType))return[];let fileNode=r.file,path96=extractRedirectPath(fileNode),opLabel=operatorLabel(opNode);if(REDIRECT_WRITE_TOKENS.has(opType)||REDIRECT_GREATAND_TOKENS.has(opType)&&!isNonFileGreatAndTarget(path96)){if(path96!==null&&isNullDevice(path96))return[];return[{category:"redirect",operator:opLabel,path:path96}]}else if(REDIRECT_HERE_TOKENS.has(opType))return[{category:"here_doc",operator:opLabel,path:path96}];return[]}function getWritesFromCommandRedirs(cmd,context){if(!cmd||typeof cmd!=="object")return[];let c=cmd,results=[];results.push(...detectHereDocMarkers(cmd));let{suffix,prefix}=c;if(Array.isArray(suffix)){for(let item of suffix)if(isRedirectNode(item)){let writes=getWritesFromRedirectNode(item,context);results.push(...writes)}}if(Array.isArray(prefix)){for(let item of prefix)if(isRedirectNode(item)){let writes=getWritesFromRedirectNode(item,context);results.push(...writes)}}return results}function resolveWriteTargets(command,writes,cwd){if(!writes||writes.length===0)return[];if(!command||typeof command!=="string")return writes.map((original)=>({original,resolvedPath:resolvePath(original.path,cwd),resolved:original.path!==null&&!isDynamicPath(original.path)}));let ast;try{ast=import_bash_parser.default(command,{mode:"posix",insertLOC:!0}),annotateRawWordText(ast,command)}catch{ast=null}if(!ast||typeof ast!=="object")return writes.map((original)=>({original,resolvedPath:resolvePath(original.path,cwd),resolved:original.path!==null&&!isDynamicPath(original.path)}));let cwdStack=[cwd],writesWithNodes=[];collectWritesWithNodes(ast,writesWithNodes,cwdStack);let seen=new Set,deduplicated=writesWithNodes.filter((wwn)=>{let key2=buildDedupeKey(wwn.write.category,wwn.write.operator,wwn.write.path);if(seen.has(key2))return!1;return seen.add(key2),!0}),resolvedMap=new Map;for(let{write,context}of deduplicated){let resolvedPath=resolvePath(write.path,context),resolved=write.path!==null&&!isDynamicPath(write.path),key2=buildDedupeKey(write.category,write.operator,write.path);resolvedMap.set(key2,{resolvedPath,resolved})}return writes.map((original)=>{let key2=buildDedupeKey(original.category,original.operator,original.path),resolved=resolvedMap.get(key2);if(resolved)return{original,resolvedPath:resolved.resolvedPath,resolved:resolved.resolved};return{original,resolvedPath:resolvePath(original.path,cwd),resolved:original.path!==null&&!isDynamicPath(original.path)}})}var import_bash_parser,REDIRECT_WRITE_TOKENS,REDIRECT_HERE_TOKENS,REDIRECT_GREATAND_TOKENS,REDIRECT_ALL_WRITE_TOKENS,BUILTIN_WRITE_COMMANDS,INPLACE_EDIT_COMMANDS,SED_LONG_SWITCHES,AWK_LONG_SWITCHES,INTERPRETER_EVAL_COMMANDS,NETWORK_DOWNLOAD_COMMANDS,ARCHIVE_EXTRACT_COMMANDS,GIT_COMMAND="git",POWERSHELL_WRITE_CMDLETS,AMBIGUOUS_WRITE_ALIASES,POWERSHELL_READ_ONLY_COMMANDS,POSIX_WRITE_TOKENS,READ_ONLY_SCRIPT_BLOCK_OPERATORS,RAW_WORD_TEXT,BRACE_EXPANSION,PARSER_CHAR_ESCAPES,_CMD_COPY_MOVE_SWITCHES;var init_shell_write_detect=__esm(()=>{init_path_identity();init_shell_executor_context();import_bash_parser=__toESM(require_src(),1);REDIRECT_WRITE_TOKENS=new Set(["GREAT","DGREAT","CLOBBER","LESSGREAT"]),REDIRECT_HERE_TOKENS=new Set(["DLESS","DLESSDASH"]),REDIRECT_GREATAND_TOKENS=new Set(["GREATAND"]),REDIRECT_ALL_WRITE_TOKENS=new Set([...REDIRECT_WRITE_TOKENS,...REDIRECT_HERE_TOKENS,...REDIRECT_GREATAND_TOKENS]),BUILTIN_WRITE_COMMANDS=new Set(["cp","mv","install","ln","truncate","unlink","rmdir"]),INPLACE_EDIT_COMMANDS=new Set(["sed","perl","awk"]),SED_LONG_SWITCHES=new Set(["--quiet","--silent","--debug","--follow-symlinks","--binary","--posix","--regexp-extended","--separate","--sandbox","--unbuffered","--null-data","--zero-terminated","--help","--version"]),AWK_LONG_SWITCHES=new Set(["--posix","--traditional","--lint","--re-interval","--sandbox","--version","--help"]),INTERPRETER_EVAL_COMMANDS=new Set(["python","python3","python2","node","bun","ruby","perl","php","bash","sh","dash","zsh","ksh","eval"]),NETWORK_DOWNLOAD_COMMANDS=new Set(["curl","wget","scp"]),ARCHIVE_EXTRACT_COMMANDS=new Set(["tar","unzip","gunzip","gzip","bzip2","xz","7z","rar"]),POWERSHELL_WRITE_CMDLETS=new Set(["set-content","add-content","out-file","clear-content","copy-item","move-item","remove-item","new-item","ni","ac","sc","epcsv"]),AMBIGUOUS_WRITE_ALIASES=new Set(["cp","cpi","mv","rm","del","ren","rd","md","type"]),POWERSHELL_READ_ONLY_COMMANDS=new Set(["get-content","gc","get-item","gi","get-childitem","gci","get-location","pwd","get-command","get-member","get-date","get-help","get-itemproperty","select-string","select-object","where-object","foreach-object","sort-object","group-object","measure-object","compare-object","resolve-path","test-path","format-table","out-string","write-output","write-host","write-verbose","write-warning"]),POSIX_WRITE_TOKENS=new Set(["cp","mv","rm","rmdir","tee","dd","ln","touch","truncate","unlink","install"]);READ_ONLY_SCRIPT_BLOCK_OPERATORS=new Set(["-gt","-ge","-lt","-le","-eq","-ne","-match","-notmatch","-like","-notlike","-replace","-contains","-notcontains","-in","-notin","-is","-isnot","-join","-split","-f","-band","-bor","-bnot","-shl","-shr","-and","-or","-not","-xor"].map((op)=>op.toLowerCase()));RAW_WORD_TEXT=new WeakMap;BRACE_EXPANSION=/\{[^{}]*(?:,|\.\.)[^{}]*\}/;PARSER_CHAR_ESCAPES={t:"\t",n:`
|
|
1174
1174
|
`,r:"\r",b:"\b",f:"\f",v:"\v"};_CMD_COPY_MOVE_SWITCHES=new Set(["/a","/b","/d","/f","/n","/v","/y","/-y","/z"])});import*as fs60 from"node:fs";import*as path96 from"node:path";function extractFilename(code,language,index){let lines=code.trim().split(`
|
|
1175
1175
|
`),ext=EXT_MAP[language.toLowerCase()]??".txt",firstLine=lines[0]?.trim()??"",filenameMatch=firstLine.match(/^[#/]+\s*filename[:\s]+(\S+\.\w+)/i);if(filenameMatch?.[1])return filenameMatch[1];let bareMatch=firstLine.match(/^[#/]+\s*(\w+\.\w+)\s*$/);if(bareMatch?.[1])return bareMatch[1];for(let line of lines.slice(0,5)){let defMatch=line.match(/^(?:def\s+|class\s+)(\w+)/);if(defMatch?.[1]&&!defMatch[1].startsWith("_"))return`${defMatch[1]}${ext}`;let psMatch=line.match(/^function\s+([\w-]+)/i);if(psMatch?.[1])return`${psMatch[1]}${ext}`}return`output_${index+1}${ext}`}function lstatIfPresent(filePath){try{return fs60.lstatSync(filePath)}catch(error93){if(error93.code==="ENOENT")return null;throw error93}}function reservationKey(filename){return path96.normalize(filename).toLowerCase()}function planExtractCodeBlocks(args2,directory){let{content,output_dir:outputDir,prefix}=args2;if(!content)return{status:"noop",reason:"content-required"};let matches=[...content.matchAll(/```(\w*)\n([\s\S]*?)```/g)];if(matches.length===0)return{status:"noop",reason:"no-code-blocks"};if(matches.length>MAX_EXTRACTED_FILES)return{status:"invalid",reason:`Too many code blocks (${matches.length}; maximum ${MAX_EXTRACTED_FILES})`};let targetDir=directory;if(outputDir!==void 0&&outputDir.trim()!==""){let reason=validateTargetWithinRoot(outputDir,directory);if(reason)return{status:"invalid",reason:`output_dir rejected — ${reason}`};targetDir=path96.resolve(directory,outputDir)}let reserved=new Set,files=[];for(let index=0;index<matches.length;index++){let language=matches[index]?.[1]??"",code=matches[index]?.[2]??"",filename=extractFilename(code,language,index);if(prefix)filename=`${prefix}_${filename}`;if(filename.includes("/")||filename.includes("\\"))return{status:"invalid",reason:`Rejected unsafe filename (must be a bare name): ${filename}`};let requestedPath=path96.join(targetDir,filename);if(lstatIfPresent(requestedPath)?.isSymbolicLink())return{status:"invalid",reason:`Rejected write through symlink: ${requestedPath}`};let base=path96.basename(filename,path96.extname(filename)),ext=path96.extname(filename),candidate=filename,counter=1;while(reserved.has(reservationKey(candidate))||lstatIfPresent(path96.join(targetDir,candidate))!==null){if(counter>MAX_COLLISION_ATTEMPTS)return{status:"invalid",reason:`Too many filename collisions for ${filename}`};candidate=`${base}_${counter}${ext}`,counter++}let absolutePath=path96.join(targetDir,candidate),relativePath=path96.relative(directory,absolutePath)||candidate,reason=validateTargetWithinRoot(relativePath,directory);if(reason)return{status:"invalid",reason:`Rejected write outside workspace: ${absolutePath} — ${reason}`};reserved.add(reservationKey(candidate)),files.push({filename:candidate,absolutePath,relativePath,code:code.trim()})}return{status:"ready",targetDir,files}}function getOrPlanExtractCodeBlocks(args2,directory){if(typeof args2==="object"&&args2!==null){let cached3=cachedPlans.get(args2);if(cached3?.directory===directory)return cached3.plan;let plan=planExtractCodeBlocks(args2,directory);return cachedPlans.set(args2,{directory,plan}),plan}return planExtractCodeBlocks(args2,directory)}function consumeExtractCodeBlocksPlan(args2,directory){let plan=getOrPlanExtractCodeBlocks(args2,directory);if(typeof args2==="object"&&args2!==null)cachedPlans.delete(args2);return plan}var EXT_MAP,MAX_EXTRACTED_FILES=256,MAX_COLLISION_ATTEMPTS=1e4,cachedPlans;var init_file_extractor_planner=__esm(()=>{init_path_security();EXT_MAP={python:".py",py:".py",powershell:".ps1",ps1:".ps1",pwsh:".ps1",javascript:".js",js:".js",typescript:".ts",ts:".ts",bash:".sh",sh:".sh",json:".json",yaml:".yaml",yml:".yaml",xml:".xml",html:".html",css:".css",sql:".sql",pester:".Tests.ps1",test:".Tests.ps1","":".txt"},cachedPlans=new WeakMap});import{Buffer as Buffer3}from"node:buffer";function unverifiable(reason){return{status:"unverifiable",reason}}function dedupe(paths){return[...new Set(paths)]}function genericResolver(args2){let paths=[],observedTargetField=!1;for(let key2 of SCALAR_PATH_KEYS){if(!(key2 in args2))continue;observedTargetField=!0;let value=args2[key2];if(typeof value!=="string"||value.trim()===""||containsControlCharacter(value))return unverifiable(`Malformed ${key2} target`);paths.push(value)}for(let key2 of ARRAY_PATH_KEYS){if(!(key2 in args2))continue;observedTargetField=!0;let value=args2[key2];if(!Array.isArray(value)||value.some((item)=>typeof item!=="string"||item.trim()===""||containsControlCharacter(item)))return unverifiable(`Malformed ${key2} targets`);paths.push(...value)}if(!observedTargetField||paths.length===0)return unverifiable("No write target was provided");return{status:"resolved",paths:dedupe(paths)}}function normalizeComparisonPath(filePath){return filePath.replace(/\\/g,"/").replace(/^\.\//,"")}function containsControlCharacter(value){for(let index=0;index<value.length;index++){let code=value.charCodeAt(index);if(code<=31||code===127)return!0}return!1}function parseTarget(raw,stripGitPrefix){let value=raw.replace(/\r$/,"").split("\t",1)[0]?.trim()??"";if(!value)return{error:"Empty patch target"};if(value==="/dev/null")return{};if(value.startsWith('"')||value.startsWith("'")||value.endsWith('"')||value.endsWith("'"))return{error:`Quoted patch path is unsupported: ${value}`};if(stripGitPrefix&&/\s/.test(value))return{error:`Ambiguous whitespace in diff path: ${value}`};if(stripGitPrefix&&(value.startsWith("a/")||value.startsWith("b/")))value=value.slice(2);if(!value||containsControlCharacter(value))return{error:"Malformed patch target"};return{path:value}}function parsePatchPayload(payload){let paths=[],operations=new Map,add=(raw,operation,stripGitPrefix=!1)=>{let parsed=parseTarget(raw,stripGitPrefix);if(parsed.error)return parsed.error;if(!parsed.path)return null;paths.push(parsed.path);let key2=normalizeComparisonPath(parsed.path),existing=operations.get(key2)??new Set;return existing.add(operation),operations.set(key2,existing),null},lines=normalizePatchIndentation(payload).split(/\r?\n/),beginIndices=[],endIndices=[],nativeOperationIndices=[];for(let index=0;index<lines.length;index++){let trimmed=(lines[index]??"").trim();if(trimmed==="*** Begin Patch")beginIndices.push(index);if(trimmed==="*** End Patch")endIndices.push(index);if(/^\*\*\* (?:Update|Add|Delete) File:/i.test(trimmed)||/^\*\*\* Move (?:to|from):/i.test(trimmed))nativeOperationIndices.push(index)}let hasUnifiedHeaders=lines.some((l)=>/^(---|\+\+\+)\s+/.test(l));if(beginIndices.length>0||nativeOperationIndices.length>0||!hasUnifiedHeaders&&endIndices.length>0){if(beginIndices.length===0)return"Native patch is missing *** Begin Patch";if(endIndices.length===0)return"Native patch is missing *** End Patch";if(beginIndices.length!==1||endIndices.length!==1)return"Native patch framing must contain exactly one begin and end marker";let beginIndex=beginIndices[0]??-1,endIndex=endIndices[0]??-1;if(beginIndex>=endIndex)return"Native patch has invalid begin/end marker ordering";if(nativeOperationIndices.some((index)=>index<=beginIndex||index>=endIndex))return"Native patch contains an operation outside begin/end markers";for(let index=beginIndex+1;index<endIndex;index++){let line=(lines[index]??"").trim(),match=line.match(/^\*\*\* (Update|Add|Delete) File:\s*(.*)$/);if(match){let error93=add(match[2]??"",(match[1]??"").toLowerCase());if(error93)return error93;continue}let move=line.match(/^\*\*\* Move (?:to|from):\s*(.*)$/i);if(move){let error93=add(move[1]??"","move");if(error93)return error93}}}else for(let line of lines){let git=line.match(/^diff --git\s+(.+)$/);if(git){let remainder=git[1]?.trim()??"";if(remainder.startsWith('"')||remainder.startsWith("'"))return"Quoted diff --git paths are unsupported";let parts=remainder.split(/\s+/);if(parts.length!==2)return"Malformed diff --git header";for(let part of parts){let error93=add(part,"diff",!0);if(error93)return error93}continue}let unified=line.match(/^(---|\+\+\+)\s+(.+)$/);if(unified){let error93=add(unified[2]??"","diff",!0);if(error93)return error93;continue}let rename7=line.match(/^rename (from|to)\s+(.+)$/);if(rename7){let error93=add(rename7[2]??"","rename");if(error93)return error93}}if(paths.length===0)return"Patch contains no recognizable write targets";for(let[filePath,fileOperations]of operations)if(fileOperations.has("add")&&fileOperations.has("delete"))return`Contradictory add/delete operations for ${filePath}`;return{paths:dedupe(paths),operations}}function patchResolver(args2,_context,toolName){let payloadGroups=[],aggregateBytes=0;for(let field of PATCH_PAYLOAD_KEYS){if(!(field in args2))continue;let value=args2[field];if(typeof value!=="string")return unverifiable(`Malformed ${field} payload`);payloadGroups.push({field,payloads:[value]})}if("cmd"in args2){let cmd=args2.cmd;if(typeof cmd==="string")payloadGroups.push({field:"cmd",payloads:[cmd]});else if(Array.isArray(cmd)&&cmd.every((item)=>typeof item==="string")){let payloads=cmd.filter((item,index)=>{if(index===0&&/(?:^|[/\\])(?:apply_patch|patch)(?:\.exe)?$/i.test(item))return!1;return!(item.startsWith("-")&&!item.includes(`
|
|
1176
1176
|
`)&&!item.includes("*** Begin Patch"))});payloadGroups.push({field:"cmd",payloads})}else return unverifiable("Malformed cmd payload")}if(payloadGroups.length===0)return unverifiable("No patch payload was provided");let resolvedGroups=[];for(let group of payloadGroups){if(group.payloads.length===0)return unverifiable(`Empty ${group.field} payload`);let groupPaths=[];for(let payload of group.payloads){let bytes=Buffer3.byteLength(payload,"utf8");if(bytes>MAX_PATCH_FIELD_BYTES)return unverifiable(`Patch payload exceeds 1 MB (${group.field} field)`);if(aggregateBytes+=bytes,aggregateBytes>MAX_PATCH_AGGREGATE_BYTES)return unverifiable("Aggregate patch payload exceeds size limit");let parsed=parsePatchPayload(payload);if(typeof parsed==="string")return unverifiable(`${group.field}: ${parsed}`);groupPaths.push(...parsed.paths)}resolvedGroups.push({field:group.field,paths:dedupe(groupPaths)})}let canonical=(paths2)=>paths2.map(normalizeComparisonPath).sort().join(`
|
|
@@ -1193,7 +1193,7 @@ ${line}`)}else{let prefix=fileEndsWithNewline2(filePath)?"":`
|
|
|
1193
1193
|
`;break;case"destructive_block":case"sandbox_wrap":case"sandbox_skip":{let command=truncateUtf8Safe(redactShellCommand(entry.command),maxCommand);line=`${JSON.stringify({...entry,command,commandHash:hashRedactedCommand(command)})}
|
|
1194
1194
|
`;break}case"file_write":line=`${JSON.stringify({...entry,path:redactPath(entry.path),reason:truncateUtf8Safe(redactEmbeddedPaths(entry.reason),maxReason),resolvedScope:redactPath(entry.resolvedScope)})}
|
|
1195
1195
|
`;break;case"scope_violation":line=`${JSON.stringify({...entry,path:redactPath(entry.path),declaredScope:redactPath(entry.declaredScope),resolvedScope:redactPath(entry.resolvedScope)})}
|
|
1196
|
-
`;break}try{appendShellAuditLineSync(ctx.directory,line)}catch(error93){log("guardrail audit: append failed",{directory:ctx.directory,error:error93})}}var SHELL_AUDIT_FIELD_CLASSES,REQUIRED_STRING_FIELDS;var init_audit_log=__esm(()=>{init_logger();init_helpers();init_shell_audit_store();SHELL_AUDIT_FIELD_CLASSES=Object.freeze({ts:"timestamp",sessionID:"identifier",agent:"identifier",tool:"identifier",type:"decision-type",command:"redacted-command",commandHash:"content-hash",path:"redacted-path",reason:"free-text-redacted",resolvedScope:"redacted-path",declaredScope:"redacted-path",action:"enum",destructiveCategory:"enum",executorMechanism:"enum",skipReason:"enum"}),REQUIRED_STRING_FIELDS=["ts","sessionID","agent","tool","type"]});import*as fsSync10 from"node:fs";import*as os14 from"node:os";import*as path99 from"node:path";import{fileURLToPath as fileURLToPath3}from"node:url";function readPackageName(dir){try{let manifestPath=path99.join(dir,"package.json");if(!_internals90.existsSync(manifestPath))return null;let name=JSON.parse(_internals90.readFileSync(manifestPath,"utf-8"))?.name;return typeof name==="string"?name:null}catch{return null}}function resolvePackageRoot(){if(cachedPackageRoot!==void 0)return cachedPackageRoot.root;let root=null;try{let dir=path99.dirname(fileURLToPath3(_internals90.moduleUrl()));for(let depth=0;depth<MAX_PACKAGE_ROOT_WALK_DEPTH;depth++){if(readPackageName(dir)==="opencode-swarm"){root=dir;break}let parent=path99.dirname(dir);if(parent===dir)break;dir=parent}}catch{root=null}return cachedPackageRoot={root},root}function isSelfDevelopmentWorkspace(directory){if(!directory)return!1;let resolved;try{resolved=canonicalRootKeyFresh(directory)}catch{return!1}let cached3=selfDevelopmentWorkspaces.get(resolved);if(cached3!==void 0)return cached3;let isSelfDev=readPackageName(resolved)==="opencode-swarm";if(selfDevelopmentWorkspaces.size>=MAX_CACHED_WORKSPACE_ROOTS){let oldest=selfDevelopmentWorkspaces.keys().next().value;if(oldest!==void 0)selfDevelopmentWorkspaces.delete(oldest)}return selfDevelopmentWorkspaces.set(resolved,isSelfDev),isSelfDev}function comparablePath(value){return process.platform==="win32"?value.toLowerCase():value}function isInsidePackageRoot(root,target){try{let rel=path99.relative(comparablePath(root),comparablePath(target));if(rel==="")return!0;if(rel.startsWith(".."))return!1;return!path99.isAbsolute(rel)}catch{return!1}}function expandHome(candidate){if(!candidate.startsWith("~"))return candidate;let home=_internals90.homedir();if(!home)return null;let rest=candidate.slice(1).replace(/^[\\/]/,"");return rest?path99.join(home,rest):home}function extractGuardedPathCandidates(normalizedTool,args2){let argsObj=args2??{},raw=[];if(normalizedTool==="bash"||normalizedTool==="shell"){let command=typeof argsObj.command==="string"?argsObj.command.slice(0,MAX_SCANNED_COMMAND_LENGTH):void 0;if(command){let matcher=new RegExp(SHELL_PATH_CANDIDATE_PATTERN.source,SHELL_PATH_CANDIDATE_PATTERN.flags);for(let match of command.matchAll(matcher)){let token=match[1];if(token&&token.length>1)raw.push(token);if(raw.length>=MAX_SHELL_PATH_CANDIDATES)break}}}else for(let key2 of SCALAR_PATH_KEYS2){let value=argsObj[key2];if(typeof value==="string"&&value.length>0)raw.push(value)}let resolved=[];for(let candidate of raw){let expanded=expandHome(candidate);if(!expanded)continue;if(!path99.isAbsolute(expanded))continue;try{resolved.push(path99.resolve(expanded))}catch{}}return resolved}function enforceInternalsGuard(params){let{sessionID,tool:tool3,args:args2,directory,options}=params;if(options?.enabled===!1)return;let normalizedTool=normalizeToolNameLowerCase(tool3??"");if(!GUARDED_TOOLS.has(normalizedTool))return;let match=null,relativeTarget="";try{let packageRoot=_internals90.resolvePackageRoot();if(!packageRoot)return;if(_internals90.isSelfDevelopmentWorkspace(directory))return;if(directory&&isInsidePackageRoot(packageRoot,path99.resolve(directory)))return;for(let candidate of extractGuardedPathCandidates(normalizedTool,args2))if(isInsidePackageRoot(packageRoot,candidate)){match=candidate,relativeTarget=path99.relative(packageRoot,candidate).replace(/\\/g,"/")||"<package root>";break}}catch{return}if(!match)return;try{telemetry.swarmInternalsReadDenied(sessionID,normalizedTool,relativeTarget)}catch{}throw Error(SWARM_INTERNALS_DENIAL_MESSAGE)}var SWARM_INTERNALS_DENIAL_MESSAGE="SWARM_INTERNALS_OFF_LIMITS: the swarm plugin's installed files are never the fix for a gate error. Fix the dispatch/state the error names, or report the blocker to the user.",GUARDED_TOOLS,SCALAR_PATH_KEYS2,MAX_PACKAGE_ROOT_WALK_DEPTH=12,MAX_CACHED_WORKSPACE_ROOTS=32,SHELL_PATH_CANDIDATE_PATTERN,MAX_SHELL_PATH_CANDIDATES=64,MAX_SCANNED_COMMAND_LENGTH=8192,cachedPackageRoot,selfDevelopmentWorkspaces,_internals90;var init_internals_guard=__esm(()=>{init_telemetry();init_canonical_root();init_normalize_tool_name();GUARDED_TOOLS=new Set(["read","glob","grep","bash","shell"]),SCALAR_PATH_KEYS2=["filePath","file_path","path","file","target"],SHELL_PATH_CANDIDATE_PATTERN=/(?:^|[\s'"`;|&<>()=,])((?:~|[A-Za-z]:)?[\\/][^\s'"`;|&<>()]*)/g,selfDevelopmentWorkspaces=new Map;_internals90={moduleUrl:()=>import.meta.url,existsSync:(p)=>fsSync10.existsSync(p),readFileSync:(p,enc)=>fsSync10.readFileSync(p,enc),homedir:()=>os14.homedir(),resolvePackageRoot,isSelfDevelopmentWorkspace,resetCaches:()=>{cachedPackageRoot=void 0,selfDevelopmentWorkspaces.clear()}}});import*as fs62 from"node:fs";import*as path100 from"node:path";function normalizeSandboxMechanism2(mechanism){return mechanism.toLowerCase().replace(/[^a-z0-9]+/g,"")}function pluginOwnsExecutorEnv(mechanism){if(mechanism.startsWith("native-runner/"))return!0;switch(mechanism){case"sandbox-exec":case"powershell-wrapper":case"Bubblewrap":return!0;default:return!1}}function throwDestructiveBlock(destructiveCategory,message){throw new DestructiveCommandBlockedError(message,destructiveCategory)}function resolveWindowsWriteAuthority(tool3,command,detectedShellType,shaped){let cmdWrapper=CMD_WRAPPER_DECLARATION.test(command),psWrapper=declaresWindowsWrapperLoose(command),inheritedWindows=detectedShellType==="powershell"||detectedShellType==="cmd";if(cmdWrapper)return"cmd";if(psWrapper||shaped)return"powershell";if(inheritedWindows&&tool3!=="bash")return detectedShellType;return null}function createToolBeforeHandler(ctx){let{effectiveDirectory,cfg,precomputedAuthorityRules,universalDenyPrefixes,shellAuditEnabled,interpreterAllowedAgents,authorityConfig,consecutiveNoToolTurns,worktreeBaseDirOverrides,getSandboxExecutor,assessSandboxEnforcement:assessSandboxEnforcement2,rememberReviewerScopeWrite,rememberScopeLeaseCandidate}=ctx,enforcePolicy=ctx.enforcePolicy!==!1;setMacOSSandboxPolicy(cfg.sandbox_macos_enabled??!1);let executionStallOptions={enabled:cfg.enabled,warnCalls:cfg.execution_stall_warn_calls,stopCalls:cfg.execution_stall_stop_calls,episodeMinutes:cfg.execution_stall_episode_minutes},internalsGuardOptions={enabled:cfg.enabled},sessionWorkspaceDirectory=(sessionID)=>resolveSessionWorkspaceDirectory(sessionID,effectiveDirectory);function resolveActiveScopeBinding(sessionID){let session=swarmState.agentSessions.get(sessionID),taskId=session?.currentTaskId??null,bindingDirectory=sessionWorkspaceDirectory(sessionID),resolution=taskId?resolveAuthorizedScopeBindingDetailed({directory:bindingDirectory,taskId,activeSessionId:sessionID}):resolveAuthorizedScopeBindingForSessionDetailed({directory:bindingDirectory,activeSessionId:sessionID}),binding=resolution.status==="found"?resolution.binding:null;if(!binding){let diagnostic=formatScopeResolutionDiagnostic({resolution,taskId,sessionId:sessionID});if(diagnostic)throw Error(diagnostic)}if(!taskId&&binding&&session)session.currentTaskId=binding.taskId,session.declaredCoderScope=[...binding.files];return binding}function resolveActiveScopeBindingObserving(sessionID){try{return resolveActiveScopeBinding(sessionID)}catch{return null}}function resolveDeclaredScope(sessionID,observing=!1){let session=swarmState.agentSessions.get(sessionID);if(!session?.currentTaskId)return session?.declaredCoderScope?.length?[...session.declaredCoderScope]:null;return(observing?resolveActiveScopeBindingObserving(sessionID):resolveActiveScopeBinding(sessionID))?.files??null}function isArchitect(sessionId){let activeAgent=swarmState.activeAgent.get(sessionId);if(activeAgent){if(stripKnownSwarmPrefix(activeAgent)===ORCHESTRATOR_NAME)return!0}let session=swarmState.agentSessions.get(sessionId);if(session){if(stripKnownSwarmPrefix(session.agentName)===ORCHESTRATOR_NAME)return!0}return!1}function handleInterpreterGating(sessionID,tool3){let normalizedTool=normalizeToolName(tool3).toLowerCase();if(normalizedTool!=="bash"&&normalizedTool!=="shell")return;if(!interpreterAllowedAgents)return;let rawAgent=swarmState.activeAgent.get(sessionID),agentRole=rawAgent?stripKnownSwarmPrefix(rawAgent).toLowerCase():"unknown";if(!interpreterAllowedAgents.some((a)=>a.toLowerCase()===agentRole))throw Error(`BLOCKED: Agent "${agentRole}" is not permitted to use the bash/shell interpreter. Allowed agents: [${interpreterAllowedAgents.map((a)=>`"${a}"`).join(", ")}]`)}function checkDestructiveCommand(sessionID,tool3,args2){if(tool3!=="bash"&&tool3!=="shell")return;if(cfg.block_destructive_commands===!1)return;let rawAgent=swarmState.activeAgent.get(sessionID),isCoder=(rawAgent?stripKnownSwarmPrefix(rawAgent).toLowerCase():"unknown")==="coder",session=swarmState.agentSessions.get(sessionID),activeBinding=isCoder&&session?.currentTaskId?resolveActiveScopeBinding(sessionID):null,bindingIdentity=activeBinding,verifiedScope=bindingIdentity&&typeof bindingIdentity.bindingId==="string"&&typeof bindingIdentity.generationId==="string"?{bindingId:bindingIdentity.bindingId,generationId:bindingIdentity.generationId,files:bindingIdentity.files}:void 0,declaredScope=activeBinding?.files??(session?.declaredCoderScope?.length?[...session.declaredCoderScope]:null),toolArgs=args2,rawCommand=typeof toolArgs?.command==="string"?toolArgs.command.trim():"";if(!rawCommand)return;let sharedClassification=classifyCommand(rawCommand),sharedGuardrailBlock=getSharedClassifierGuardrailBlock(sharedClassification);if(sharedGuardrailBlock)throwDestructiveBlock(sharedGuardrailBlock.destructiveCategory,sharedGuardrailBlock.message);let cwd=sessionWorkspaceDirectory(sessionID),command=dcNormalizeCommand(rawCommand),unwrapped=dcUnwrapWrappers(command),outerSegments=dcSplitSegments(command),innerSegments=dcSplitSegments(unwrapped),perSegmentUnwrapped=outerSegments.map((s)=>dcUnwrapWrappers(s)),allSegments=[...new Set([...outerSegments,...innerSegments,...perSegmentUnwrapped])],swarmShellVars=new Map;for(let segment of allSegments){let seg=segment.trim();if(!seg)continue;for(let m of seg.matchAll(/(?:^|[\s;&|(])([A-Za-z_][A-Za-z0-9_]*)=(?:"([^"]*)"|'([^']*)'|([^\s;&|()]+))/g)){let value=m[2]??m[3]??m[4]??"";if(m[1])swarmShellVars.set(m[1],value)}let junctionBlock=dcCheckJunctionCreation(seg,cwd);if(junctionBlock)throwDestructiveBlock("junction/symlink creation",junctionBlock);let rmTargets=dcExtractRecursiveRmTargets(seg);if(rmTargets){let decision=dcEvaluateRecursiveDeleteTargets({targets:rmTargets,cwd,verifiedScope});if(!decision.allowed)throwDestructiveBlock("recursive delete",decision.reason)}if(/^(?:rmdir|rd)(?:\.exe)?\s+.*\/[sS]/i.test(seg)){let targets=dcExtractWindowsCmdTargets(seg);if(targets.length===0)throwDestructiveBlock("recursive directory delete","BLOCKED: Windows recursive directory delete (rmdir /s or rd /s) detected. Verify the target is not a junction/symlink.");let decision=dcEvaluateRecursiveDeleteTargets({targets,cwd,verifiedScope});if(!decision.allowed)throwDestructiveBlock("recursive directory delete",decision.reason)}if(/^del(?:\.exe)?\s+.*\/[sS]/i.test(seg)){let targets=dcExtractWindowsCmdTargets(seg);if(targets.length>0){let decision=dcEvaluateRecursiveDeleteTargets({targets,cwd,verifiedScope});if(!decision.allowed)throwDestructiveBlock("recursive file delete",decision.reason)}}if(/^(?:Remove-Item|ri|rm|rmdir|del|erase|rd)\b.*-[Rr]ecurse\b/i.test(seg)||/^(?:Remove-Item|ri|rm|rmdir|del|erase|rd)\b.*-[Rr]\b/i.test(seg)){let targets=dcExtractPowerShellTargets(seg);if(targets.length>0){let decision=dcEvaluateRecursiveDeleteTargets({targets,cwd,verifiedScope});if(!decision.allowed)throwDestructiveBlock("recursive remove",decision.reason)}else throwDestructiveBlock("recursive remove","BLOCKED: PowerShell Remove-Item with -Recurse detected — cannot verify target safety")}if(/Get-ChildItem\b.*\|\s*Remove-Item\b.*-[Rr]ecurse/i.test(seg)||/gci\b.*\|\s*ri\b.*-[Rr]ecurse/i.test(seg))throwDestructiveBlock("recursive remove",'BLOCKED: PowerShell pipeline "Get-ChildItem | Remove-Item -Recurse" detected — verify target safety and avoid recursive deletion through symlinks/junctions');let worktreeRemoveMatch=/^git\s+worktree\s+remove\s+(.+)$/i.exec(seg);if(worktreeRemoveMatch){let normalizedArgs=worktreeRemoveMatch[1].trim().split(/\s+/).filter(Boolean).map((a)=>a.replace(/^["']|["']$/g,"")),isForceToken=(a)=>{let lower=a.toLowerCase();return/^-f+$/.test(lower)||lower.length>2&&"--force".startsWith(lower)};if(normalizedArgs.some(isForceToken)){let pathArgs=normalizedArgs.filter((a)=>!a.startsWith("-")),target=pathArgs.length===1?pathArgs[0].trim():null;if(!(target!=null&&target.length>0&&(declaredScope!=null&&declaredScope.length>0&&isInDeclaredScope(target,declaredScope,cwd)||isPathUnderSwarmWorktreeBase(target,cwd,worktreeBaseDirOverrides??[]))))throwDestructiveBlock("git worktree remove",'BLOCKED: "git worktree remove --force" detected — can delete working tree contents')}}if(/^rsync\b.*--delete(?:-after|-before|-during|-delay)?\b/.test(seg)){let rsyncTarget=seg.split(/\s+/).slice(1).filter((a)=>!a.startsWith("-")&&!a.includes("@")).pop();if(!(rsyncTarget!=null&&declaredScope!=null&&declaredScope.length>0&&isInDeclaredScope(rsyncTarget,declaredScope,cwd)))throwDestructiveBlock("rsync delete",'BLOCKED: "rsync --delete" detected — can delete files in the destination. Verify source is not empty.')}if(/^\\?mv\s/i.test(seg)){let mvMatch=seg.match(/^\\?mv\s+(.+)$/i);if(mvMatch){let argsStr=mvMatch[1].replace(/["']/g,"");if(/\.swarm(?:[\x5c/\s]|$)/.test(argsStr))throwDestructiveBlock("swarm path move",'BLOCKED: "mv" targeting .swarm/ detected — move operations under .swarm/ are not allowed from shell commands')}}if(/^\\?(?:move|ren)(?:\.exe)?\s/i.test(seg)){let moveMatch=seg.match(/^\\?(?:move|ren)(?:\.exe)?\s+(.+)$/i);if(moveMatch){let argsStr=moveMatch[1].replace(/["']/g,"");if(/\.swarm(?:[\x5c/\s]|$)/i.test(argsStr))throwDestructiveBlock("move/rename",'BLOCKED: "move" or "ren" targeting .swarm/ detected — move/rename operations under .swarm/ are not allowed from shell commands')}}if(/^\\?(?:Move-Item|Rename-Item|move|mi|mv|ren|rni)\b.*\.swarm(?:[\x5c/\s]|$)/i.test(seg))throwDestructiveBlock("move/rename","BLOCKED: PowerShell Move-Item or Rename-Item targeting .swarm/ detected — move/rename operations under .swarm/ are not allowed from shell commands");if(/^\\?rm\b/i.test(seg)&&!/^\\?rm\s+(?:-[a-zA-Z]*[rR][a-zA-Z]*|--recursive)\b/i.test(seg)&&/\.swarm(?:[\x5c/\s]|$)/i.test(seg))throwDestructiveBlock("swarm path delete",'BLOCKED: "rm" targeting .swarm/ detected — deleting files under .swarm/ is not allowed from shell commands');if(/\bcp\b.*\.swarm(?:[\x5c/\s]|$)/i.test(seg)&&/\brm\b.*\.swarm(?:[\x5c/\s]|$)/i.test(seg))throwDestructiveBlock("copy-and-delete bypass",'BLOCKED: "cp" of .swarm/ file followed by "rm" of .swarm/ source detected — copy-and-delete bypass is not allowed');if(/^rsync\b.*--remove-source-files\b/i.test(seg)&&/\.swarm(?:[\x5c/\s]|$)/i.test(seg))throwDestructiveBlock("archive delete source",'BLOCKED: "rsync" with delete-source flag targeting .swarm/ detected — archive with source deletion under .swarm/ is not allowed');if(/^tar\b.*--remove-files\b/i.test(seg)&&/\.swarm(?:[\x5c/\s]|$)/i.test(seg))throwDestructiveBlock("archive delete source",'BLOCKED: "tar" with delete-source flag targeting .swarm/ detected — archive with source deletion under .swarm/ is not allowed');if(/^zip\b.*\s-m\b/i.test(seg)&&/\.swarm(?:[\x5c/\s]|$)/i.test(seg))throwDestructiveBlock("archive delete source",'BLOCKED: "zip" with delete-source flag targeting .swarm/ detected — archive with source deletion under .swarm/ is not allowed');if(/^7z\b.*\s-sdel\b/i.test(seg)&&/\.swarm(?:[\x5c/\s]|$)/i.test(seg))throwDestructiveBlock("archive delete source",'BLOCKED: "7z" with delete-source flag targeting .swarm/ detected — archive with source deletion under .swarm/ is not allowed');{let HUMAN_ONLY_SWARM_SUBCOMMANDS=HUMAN_ONLY_SWARM_COMMANDS,probe2=seg.replace(/^(?:[A-Za-z_][A-Za-z0-9_]*(?:="[^"]*"|='[^']*'|=\S+)\s+)+/,"").replace(/^eval(?:\s+--)?\s+["']?/,"").replace(/["']\s*$/,"").replace(/^\$\(\s*/,"").replace(/^\(\s*/,"").replace(/\s*\)$/,"").replace(/^`/,"").replace(/`$/,"").trim();for(let i=0;i<4;i++){let before=probe2;if(probe2=probe2.replace(/^env\s+(?:-i\b|--ignore-environment\b|-u\s+\S+|-[a-zA-Z]+\s+)*\s*/,"").replace(/^command\s+(?:-[pvV]\s+)*/,"").replace(/^(?:[A-Za-z_][A-Za-z0-9_]*(?:="[^"]*"|='[^']*'|=\S+)\s+)+/,"").trim(),probe2===before)break}let dequote=(input)=>input.replace(/["']/g,""),resolveVars=(input)=>input.replace(/\$\{?([A-Za-z_][A-Za-z0-9_]*)\}?/g,(full,name)=>swarmShellVars.has(name)?swarmShellVars.get(name):full),RUNNER_SHAPE=/^(?:\\|\/?(?:[\w.:%@=+-]+[/\\])*)?(?:bunx|npx|pnpx|npm|pnpm|yarn|bun|node|deno|tsx|ts-node|opencode-swarm)\b[^|;&]*?\brun\s+\$/i;for(let variant of[resolveVars(probe2),dequote(resolveVars(probe2))])if(RUNNER_SHAPE.test(variant))throwDestructiveBlock("human-only swarm command",'BLOCKED: "opencode-swarm run" invoked with an unresolvable shell variable or command substitution in the subcommand position. Re-run with the literal subcommand name so the human-only policy can be evaluated.');let probeVariants=[probe2,dequote(probe2),resolveVars(probe2),dequote(resolveVars(probe2))],matchCaptures=(re)=>{let captures=[];for(let variant of probeVariants){let m=variant.match(re);if(m?.[1])captures.push(m[1])}return captures},blockIfHumanOnly=(captures)=>{for(let captured of captures){let normalized=captured.trim().split(/\s+/).join(" "),firstToken=normalized.includes(" ")?normalized.split(" ")[0]:normalized,cmdName=HUMAN_ONLY_SWARM_SUBCOMMANDS.has(normalized)?normalized:firstToken;if(HUMAN_ONLY_SWARM_SUBCOMMANDS.has(normalized)||HUMAN_ONLY_SWARM_SUBCOMMANDS.has(firstToken))throwDestructiveBlock("human-only swarm command",`BLOCKED: "${cmdName}" is a human-only swarm command and may not be invoked from shell by an agent. Present the situation to the user and ask them to run \`/swarm ${cmdName}\` themselves.`)}};blockIfHumanOnly(matchCaptures(/^(?:\\|\/?(?:[\w.:%@=+-]+[/\\])*)?(?:bunx|npx|pnpx|npm(?:\s+(?:exec|x)(?:\s+--)?)?|pnpm(?:\s+(?:dlx|exec))?|yarn(?:\s+(?:dlx|exec))?|bun(?:\s+x)?|node|deno\s+run|tsx|ts-node)\b[^|;&]*?\bopencode-swarm\b[^|;&]*?\brun\s+([A-Za-z0-9_-]+(?:\s+(?!-)[A-Za-z0-9_-]+)?)/i)),blockIfHumanOnly(matchCaptures(/^(?:\\|\/?(?:[\w.:%@=+-]+[/\\])*)?opencode-swarm\b[^|;&]*?\brun\s+([A-Za-z0-9_-]+(?:\s+(?!-)[A-Za-z0-9_-]+)?)/i)),blockIfHumanOnly(matchCaptures(/\bcli[/\\]+index\.[mc]?(?:js|ts)\b[^|;&]*?\brun\s+([A-Za-z0-9_-]+(?:\s+(?!-)[A-Za-z0-9_-]+)?)/i))}{let normForPathCheck=seg.replace(/\\/g,"/").replace(/\/(?:\.\/+)+/g,"/").replace(/\/{2,}/g,"/");if(/\.swarm\/spec-staleness\.json\b/i.test(normForPathCheck)){let trimmed=seg.trim(),looksReadOnly=/^(?:cat|less|more|head|tail|file|stat|ls|dir|Get-Content|gc|Get-Item|gi|type)\b/i.test(trimmed),hasWriteRedirect=/>{1,2}\s*[^\s>]/.test(trimmed);if(!looksReadOnly||hasWriteRedirect)throwDestructiveBlock("system file tampering","BLOCKED: shell command targeting .swarm/spec-staleness.json detected. This file is system-managed and gates plan-mutating tools while spec drift is unresolved. Present the drift to the user and ask them to run /swarm acknowledge-spec-drift.")}}}}function detectShellType(command){if(/^(powershell|ps1|\.\s*\\|Remove-Item|Copy-Item|Move-Item|Start-Process|New-Object|Get-ChildItem|Set-Content|Add-Content|Out-File|Invoke-WebRequest|Invoke-RestMethod|IEX|iex)\b/i.test(command)||command.includes("$PSVersionTable")||command.includes("$env:")||/-EncodedCommand|-ExecutionPolicy|Enable-PSRemoting/i.test(command))return"powershell";if(/^(cmd|c:\/|set \w+=|\.\d+|del \/|rd \/|mkdir|chdir|echo |copy |move |ren |fc |diskpart)/i.test(command)||/%[^%\s]+%/.test(command)||/\b(set|echo|if|exist)\s+/i.test(command))return"cmd";if(/^(bash|sh|zsh|ksh|ash|dash|fish|ruby|python|perl|npm|yarn|node|cargo|go|rustc|mv|cp|rm|chmod|chown|mkdir|ln|tar|gzip|gunzip|ssh|scp|rsync|sudo|su -|export |source |\.\s+)/i.test(command)||command.includes("|")||command.includes("&&")||command.includes(">>")||/\$\{?\w+\}?/.test(command))return"bash";return"unix"}function checkShellWriteScope(sessionID,callID,tool3,args2,commandOverride,options){let enforce=options?.enforce!==!1;if(tool3!=="bash"&&tool3!=="shell")return;let session=swarmState.agentSessions.get(sessionID),toolArgs=args2,command=typeof commandOverride==="string"?commandOverride.trim():typeof toolArgs?.command==="string"?toolArgs.command.trim():"";if(!command)return;let normalizedTool=tool3,detectedShellType=detectShellType(command),shaped=isPowerShellShaped(command),shellType=detectedShellType;if(enforce&&(shellType==="powershell"||shellType==="cmd"?[shellType,"posix"]:["posix"]).some((candidate)=>detectInteractiveSession(command,candidate)))throw Error("BLOCKED: interactive/session tool detected — rejecting for safety");let windowsShell=resolveWindowsWriteAuthority(normalizedTool,command,detectedShellType,shaped),wrapperDeclaredHere=declaresWindowsWrapperLoose(command),windowsAuthoritative=wrapperDeclaredHere||normalizedTool!=="bash",detect=(c)=>{let posix14=detectPosixWrites(c);if(windowsShell===null)return posix14;return mergeWriteAnalyses(posix14,detectWindowsWrites(c,windowsShell),windowsAuthoritative,wrapperDeclaredHere)},suppressParseError=(c)=>enforce&&isPowerShellReadOnlyPipeline(c),primaryAnalysis=detect(command);if(enforce&&primaryAnalysis.parseError&&!suppressParseError(command))throw Error("BLOCKED: bash write detection failed to parse command — rejecting for safety");let commandSegments=dcSplitSegments(command),unwrappedSegments=commandSegments.map((s)=>dcUnwrapWrappers(s)),didUnwrap=commandSegments.some((s,i)=>unwrappedSegments[i]!==s),detectionCommand=didUnwrap?unwrappedSegments.join(`
|
|
1196
|
+
`;break}try{appendShellAuditLineSync(ctx.directory,line)}catch(error93){log("guardrail audit: append failed",{directory:ctx.directory,error:error93})}}var SHELL_AUDIT_FIELD_CLASSES,REQUIRED_STRING_FIELDS;var init_audit_log=__esm(()=>{init_logger();init_helpers();init_shell_audit_store();SHELL_AUDIT_FIELD_CLASSES=Object.freeze({ts:"timestamp",sessionID:"identifier",agent:"identifier",tool:"identifier",type:"decision-type",command:"redacted-command",commandHash:"content-hash",path:"redacted-path",reason:"free-text-redacted",resolvedScope:"redacted-path",declaredScope:"redacted-path",action:"enum",destructiveCategory:"enum",executorMechanism:"enum",skipReason:"enum"}),REQUIRED_STRING_FIELDS=["ts","sessionID","agent","tool","type"]});import*as fsSync10 from"node:fs";import*as os14 from"node:os";import*as path99 from"node:path";import{fileURLToPath as fileURLToPath3}from"node:url";function readPackageName(dir){try{let manifestPath=path99.join(dir,"package.json");if(!_internals90.existsSync(manifestPath))return null;let name=JSON.parse(_internals90.readFileSync(manifestPath,"utf-8"))?.name;return typeof name==="string"?name:null}catch{return null}}function resolvePackageRoot(){if(cachedPackageRoot!==void 0)return cachedPackageRoot.root;let root=null;try{let dir=path99.dirname(fileURLToPath3(_internals90.moduleUrl()));for(let depth=0;depth<MAX_PACKAGE_ROOT_WALK_DEPTH;depth++){if(readPackageName(dir)==="opencode-swarm"){root=dir;break}let parent=path99.dirname(dir);if(parent===dir)break;dir=parent}}catch{root=null}return cachedPackageRoot={root},root}function isSelfDevelopmentWorkspace(directory){if(!directory)return!1;let resolved;try{resolved=canonicalRootKeyFresh(directory)}catch{return!1}let cached3=selfDevelopmentWorkspaces.get(resolved);if(cached3!==void 0)return cached3;let isSelfDev=readPackageName(resolved)==="opencode-swarm";if(selfDevelopmentWorkspaces.size>=MAX_CACHED_WORKSPACE_ROOTS){let oldest=selfDevelopmentWorkspaces.keys().next().value;if(oldest!==void 0)selfDevelopmentWorkspaces.delete(oldest)}return selfDevelopmentWorkspaces.set(resolved,isSelfDev),isSelfDev}function comparablePath(value){return process.platform==="win32"?value.toLowerCase():value}function isInsidePackageRoot(root,target){try{let rel=path99.relative(comparablePath(root),comparablePath(target));if(rel==="")return!0;if(rel.startsWith(".."))return!1;return!path99.isAbsolute(rel)}catch{return!1}}function expandHome(candidate){if(!candidate.startsWith("~"))return candidate;let home=_internals90.homedir();if(!home)return null;let rest=candidate.slice(1).replace(/^[\\/]/,"");return rest?path99.join(home,rest):home}function extractGuardedPathCandidates(normalizedTool,args2){let argsObj=args2??{},raw=[];if(normalizedTool==="bash"||normalizedTool==="shell"){let command=typeof argsObj.command==="string"?argsObj.command.slice(0,MAX_SCANNED_COMMAND_LENGTH):void 0;if(command){let matcher=new RegExp(SHELL_PATH_CANDIDATE_PATTERN.source,SHELL_PATH_CANDIDATE_PATTERN.flags);for(let match of command.matchAll(matcher)){let token=match[1];if(token&&token.length>1)raw.push(token);if(raw.length>=MAX_SHELL_PATH_CANDIDATES)break}}}else for(let key2 of SCALAR_PATH_KEYS2){let value=argsObj[key2];if(typeof value==="string"&&value.length>0)raw.push(value)}let resolved=[];for(let candidate of raw){let expanded=expandHome(candidate);if(!expanded)continue;if(!path99.isAbsolute(expanded))continue;try{resolved.push(path99.resolve(expanded))}catch{}}return resolved}function enforceInternalsGuard(params){let{sessionID,tool:tool3,args:args2,directory,options}=params;if(options?.enabled===!1)return;let normalizedTool=normalizeToolNameLowerCase(tool3??"");if(!GUARDED_TOOLS.has(normalizedTool))return;let match=null,relativeTarget="";try{let packageRoot=_internals90.resolvePackageRoot();if(!packageRoot)return;if(_internals90.isSelfDevelopmentWorkspace(directory))return;if(directory&&isInsidePackageRoot(packageRoot,path99.resolve(directory)))return;for(let candidate of extractGuardedPathCandidates(normalizedTool,args2))if(isInsidePackageRoot(packageRoot,candidate)){match=candidate,relativeTarget=path99.relative(packageRoot,candidate).replace(/\\/g,"/")||"<package root>";break}}catch{return}if(!match)return;try{telemetry.swarmInternalsReadDenied(sessionID,normalizedTool,relativeTarget)}catch{}throw Error(SWARM_INTERNALS_DENIAL_MESSAGE)}var SWARM_INTERNALS_DENIAL_MESSAGE="SWARM_INTERNALS_OFF_LIMITS: the swarm plugin's installed files are never the fix for a gate error. Fix the dispatch/state the error names, or report the blocker to the user.",GUARDED_TOOLS,SCALAR_PATH_KEYS2,MAX_PACKAGE_ROOT_WALK_DEPTH=12,MAX_CACHED_WORKSPACE_ROOTS=32,SHELL_PATH_CANDIDATE_PATTERN,MAX_SHELL_PATH_CANDIDATES=64,MAX_SCANNED_COMMAND_LENGTH=8192,cachedPackageRoot,selfDevelopmentWorkspaces,_internals90;var init_internals_guard=__esm(()=>{init_telemetry();init_canonical_root();init_normalize_tool_name();GUARDED_TOOLS=new Set(["read","glob","grep","bash","shell"]),SCALAR_PATH_KEYS2=["filePath","file_path","path","file","target"],SHELL_PATH_CANDIDATE_PATTERN=/(?:^|[\s'"`;|&<>()=,])((?:~|[A-Za-z]:)?[\\/][^\s'"`;|&<>()]*)/g,selfDevelopmentWorkspaces=new Map;_internals90={moduleUrl:()=>import.meta.url,existsSync:(p)=>fsSync10.existsSync(p),readFileSync:(p,enc)=>fsSync10.readFileSync(p,enc),homedir:()=>os14.homedir(),resolvePackageRoot,isSelfDevelopmentWorkspace,resetCaches:()=>{cachedPackageRoot=void 0,selfDevelopmentWorkspaces.clear()}}});import*as fs62 from"node:fs";import*as path100 from"node:path";function normalizeSandboxMechanism2(mechanism){return mechanism.toLowerCase().replace(/[^a-z0-9]+/g,"")}function pluginOwnsExecutorEnv(mechanism){if(mechanism.startsWith("native-runner/"))return!0;switch(mechanism){case"sandbox-exec":case"powershell-wrapper":case"Bubblewrap":return!0;default:return!1}}function throwDestructiveBlock(destructiveCategory,message){throw new DestructiveCommandBlockedError(message,destructiveCategory)}function resolveWindowsWriteAuthority(tool3,command,detectedShellType,shaped,platform=process.platform){let cmdWrapper=CMD_WRAPPER_DECLARATION.test(command),psWrapper=declaresWindowsWrapperLoose(command),inheritedWindows=detectedShellType==="powershell"||detectedShellType==="cmd";if(cmdWrapper)return"cmd";if(psWrapper||shaped)return"powershell";if(inheritedWindows&&!(tool3==="bash"||tool3==="shell"&&platform!=="win32"))return detectedShellType;return null}function createToolBeforeHandler(ctx){let{effectiveDirectory,cfg,precomputedAuthorityRules,universalDenyPrefixes,shellAuditEnabled,interpreterAllowedAgents,authorityConfig,consecutiveNoToolTurns,worktreeBaseDirOverrides,getSandboxExecutor,assessSandboxEnforcement:assessSandboxEnforcement2,rememberReviewerScopeWrite,rememberScopeLeaseCandidate}=ctx,enforcePolicy=ctx.enforcePolicy!==!1;setMacOSSandboxPolicy(cfg.sandbox_macos_enabled??!1);let executionStallOptions={enabled:cfg.enabled,warnCalls:cfg.execution_stall_warn_calls,stopCalls:cfg.execution_stall_stop_calls,episodeMinutes:cfg.execution_stall_episode_minutes},internalsGuardOptions={enabled:cfg.enabled},sessionWorkspaceDirectory=(sessionID)=>resolveSessionWorkspaceDirectory(sessionID,effectiveDirectory);function resolveActiveScopeBinding(sessionID){let session=swarmState.agentSessions.get(sessionID),taskId=session?.currentTaskId??null,bindingDirectory=sessionWorkspaceDirectory(sessionID),resolution=taskId?resolveAuthorizedScopeBindingDetailed({directory:bindingDirectory,taskId,activeSessionId:sessionID}):resolveAuthorizedScopeBindingForSessionDetailed({directory:bindingDirectory,activeSessionId:sessionID}),binding=resolution.status==="found"?resolution.binding:null;if(!binding){let diagnostic=formatScopeResolutionDiagnostic({resolution,taskId,sessionId:sessionID});if(diagnostic)throw Error(diagnostic)}if(!taskId&&binding&&session)session.currentTaskId=binding.taskId,session.declaredCoderScope=[...binding.files];return binding}function resolveActiveScopeBindingObserving(sessionID){try{return resolveActiveScopeBinding(sessionID)}catch{return null}}function resolveDeclaredScope(sessionID,observing=!1){let session=swarmState.agentSessions.get(sessionID);if(!session?.currentTaskId)return session?.declaredCoderScope?.length?[...session.declaredCoderScope]:null;return(observing?resolveActiveScopeBindingObserving(sessionID):resolveActiveScopeBinding(sessionID))?.files??null}function isArchitect(sessionId){let activeAgent=swarmState.activeAgent.get(sessionId);if(activeAgent){if(stripKnownSwarmPrefix(activeAgent)===ORCHESTRATOR_NAME)return!0}let session=swarmState.agentSessions.get(sessionId);if(session){if(stripKnownSwarmPrefix(session.agentName)===ORCHESTRATOR_NAME)return!0}return!1}function handleInterpreterGating(sessionID,tool3){let normalizedTool=normalizeToolName(tool3).toLowerCase();if(normalizedTool!=="bash"&&normalizedTool!=="shell")return;if(!interpreterAllowedAgents)return;let rawAgent=swarmState.activeAgent.get(sessionID),agentRole=rawAgent?stripKnownSwarmPrefix(rawAgent).toLowerCase():"unknown";if(!interpreterAllowedAgents.some((a)=>a.toLowerCase()===agentRole))throw Error(`BLOCKED: Agent "${agentRole}" is not permitted to use the bash/shell interpreter. Allowed agents: [${interpreterAllowedAgents.map((a)=>`"${a}"`).join(", ")}]`)}function checkDestructiveCommand(sessionID,tool3,args2){if(tool3!=="bash"&&tool3!=="shell")return;if(cfg.block_destructive_commands===!1)return;let rawAgent=swarmState.activeAgent.get(sessionID),isCoder=(rawAgent?stripKnownSwarmPrefix(rawAgent).toLowerCase():"unknown")==="coder",session=swarmState.agentSessions.get(sessionID),activeBinding=isCoder&&session?.currentTaskId?resolveActiveScopeBinding(sessionID):null,bindingIdentity=activeBinding,verifiedScope=bindingIdentity&&typeof bindingIdentity.bindingId==="string"&&typeof bindingIdentity.generationId==="string"?{bindingId:bindingIdentity.bindingId,generationId:bindingIdentity.generationId,files:bindingIdentity.files}:void 0,declaredScope=activeBinding?.files??(session?.declaredCoderScope?.length?[...session.declaredCoderScope]:null),toolArgs=args2,rawCommand=typeof toolArgs?.command==="string"?toolArgs.command.trim():"";if(!rawCommand)return;let sharedClassification=classifyCommand(rawCommand),sharedGuardrailBlock=getSharedClassifierGuardrailBlock(sharedClassification);if(sharedGuardrailBlock)throwDestructiveBlock(sharedGuardrailBlock.destructiveCategory,sharedGuardrailBlock.message);let cwd=sessionWorkspaceDirectory(sessionID),command=dcNormalizeCommand(rawCommand),unwrapped=dcUnwrapWrappers(command),outerSegments=dcSplitSegments(command),innerSegments=dcSplitSegments(unwrapped),perSegmentUnwrapped=outerSegments.map((s)=>dcUnwrapWrappers(s)),allSegments=[...new Set([...outerSegments,...innerSegments,...perSegmentUnwrapped])],swarmShellVars=new Map;for(let segment of allSegments){let seg=segment.trim();if(!seg)continue;for(let m of seg.matchAll(/(?:^|[\s;&|(])([A-Za-z_][A-Za-z0-9_]*)=(?:"([^"]*)"|'([^']*)'|([^\s;&|()]+))/g)){let value=m[2]??m[3]??m[4]??"";if(m[1])swarmShellVars.set(m[1],value)}let junctionBlock=dcCheckJunctionCreation(seg,cwd);if(junctionBlock)throwDestructiveBlock("junction/symlink creation",junctionBlock);let rmTargets=dcExtractRecursiveRmTargets(seg);if(rmTargets){let decision=dcEvaluateRecursiveDeleteTargets({targets:rmTargets,cwd,verifiedScope});if(!decision.allowed)throwDestructiveBlock("recursive delete",decision.reason)}if(/^(?:rmdir|rd)(?:\.exe)?\s+.*\/[sS]/i.test(seg)){let targets=dcExtractWindowsCmdTargets(seg);if(targets.length===0)throwDestructiveBlock("recursive directory delete","BLOCKED: Windows recursive directory delete (rmdir /s or rd /s) detected. Verify the target is not a junction/symlink.");let decision=dcEvaluateRecursiveDeleteTargets({targets,cwd,verifiedScope});if(!decision.allowed)throwDestructiveBlock("recursive directory delete",decision.reason)}if(/^del(?:\.exe)?\s+.*\/[sS]/i.test(seg)){let targets=dcExtractWindowsCmdTargets(seg);if(targets.length>0){let decision=dcEvaluateRecursiveDeleteTargets({targets,cwd,verifiedScope});if(!decision.allowed)throwDestructiveBlock("recursive file delete",decision.reason)}}if(/^(?:Remove-Item|ri|rm|rmdir|del|erase|rd)\b.*-[Rr]ecurse\b/i.test(seg)||/^(?:Remove-Item|ri|rm|rmdir|del|erase|rd)\b.*-[Rr]\b/i.test(seg)){let targets=dcExtractPowerShellTargets(seg);if(targets.length>0){let decision=dcEvaluateRecursiveDeleteTargets({targets,cwd,verifiedScope});if(!decision.allowed)throwDestructiveBlock("recursive remove",decision.reason)}else throwDestructiveBlock("recursive remove","BLOCKED: PowerShell Remove-Item with -Recurse detected — cannot verify target safety")}if(/Get-ChildItem\b.*\|\s*Remove-Item\b.*-[Rr]ecurse/i.test(seg)||/gci\b.*\|\s*ri\b.*-[Rr]ecurse/i.test(seg))throwDestructiveBlock("recursive remove",'BLOCKED: PowerShell pipeline "Get-ChildItem | Remove-Item -Recurse" detected — verify target safety and avoid recursive deletion through symlinks/junctions');let worktreeRemoveMatch=/^git\s+worktree\s+remove\s+(.+)$/i.exec(seg);if(worktreeRemoveMatch){let normalizedArgs=worktreeRemoveMatch[1].trim().split(/\s+/).filter(Boolean).map((a)=>a.replace(/^["']|["']$/g,"")),isForceToken=(a)=>{let lower=a.toLowerCase();return/^-f+$/.test(lower)||lower.length>2&&"--force".startsWith(lower)};if(normalizedArgs.some(isForceToken)){let pathArgs=normalizedArgs.filter((a)=>!a.startsWith("-")),target=pathArgs.length===1?pathArgs[0].trim():null;if(!(target!=null&&target.length>0&&(declaredScope!=null&&declaredScope.length>0&&isInDeclaredScope(target,declaredScope,cwd)||isPathUnderSwarmWorktreeBase(target,cwd,worktreeBaseDirOverrides??[]))))throwDestructiveBlock("git worktree remove",'BLOCKED: "git worktree remove --force" detected — can delete working tree contents')}}if(/^rsync\b.*--delete(?:-after|-before|-during|-delay)?\b/.test(seg)){let rsyncTarget=seg.split(/\s+/).slice(1).filter((a)=>!a.startsWith("-")&&!a.includes("@")).pop();if(!(rsyncTarget!=null&&declaredScope!=null&&declaredScope.length>0&&isInDeclaredScope(rsyncTarget,declaredScope,cwd)))throwDestructiveBlock("rsync delete",'BLOCKED: "rsync --delete" detected — can delete files in the destination. Verify source is not empty.')}if(/^\\?mv\s/i.test(seg)){let mvMatch=seg.match(/^\\?mv\s+(.+)$/i);if(mvMatch){let argsStr=mvMatch[1].replace(/["']/g,"");if(/\.swarm(?:[\x5c/\s]|$)/.test(argsStr))throwDestructiveBlock("swarm path move",'BLOCKED: "mv" targeting .swarm/ detected — move operations under .swarm/ are not allowed from shell commands')}}if(/^\\?(?:move|ren)(?:\.exe)?\s/i.test(seg)){let moveMatch=seg.match(/^\\?(?:move|ren)(?:\.exe)?\s+(.+)$/i);if(moveMatch){let argsStr=moveMatch[1].replace(/["']/g,"");if(/\.swarm(?:[\x5c/\s]|$)/i.test(argsStr))throwDestructiveBlock("move/rename",'BLOCKED: "move" or "ren" targeting .swarm/ detected — move/rename operations under .swarm/ are not allowed from shell commands')}}if(/^\\?(?:Move-Item|Rename-Item|move|mi|mv|ren|rni)\b.*\.swarm(?:[\x5c/\s]|$)/i.test(seg))throwDestructiveBlock("move/rename","BLOCKED: PowerShell Move-Item or Rename-Item targeting .swarm/ detected — move/rename operations under .swarm/ are not allowed from shell commands");if(/^\\?rm\b/i.test(seg)&&!/^\\?rm\s+(?:-[a-zA-Z]*[rR][a-zA-Z]*|--recursive)\b/i.test(seg)&&/\.swarm(?:[\x5c/\s]|$)/i.test(seg))throwDestructiveBlock("swarm path delete",'BLOCKED: "rm" targeting .swarm/ detected — deleting files under .swarm/ is not allowed from shell commands');if(/\bcp\b.*\.swarm(?:[\x5c/\s]|$)/i.test(seg)&&/\brm\b.*\.swarm(?:[\x5c/\s]|$)/i.test(seg))throwDestructiveBlock("copy-and-delete bypass",'BLOCKED: "cp" of .swarm/ file followed by "rm" of .swarm/ source detected — copy-and-delete bypass is not allowed');if(/^rsync\b.*--remove-source-files\b/i.test(seg)&&/\.swarm(?:[\x5c/\s]|$)/i.test(seg))throwDestructiveBlock("archive delete source",'BLOCKED: "rsync" with delete-source flag targeting .swarm/ detected — archive with source deletion under .swarm/ is not allowed');if(/^tar\b.*--remove-files\b/i.test(seg)&&/\.swarm(?:[\x5c/\s]|$)/i.test(seg))throwDestructiveBlock("archive delete source",'BLOCKED: "tar" with delete-source flag targeting .swarm/ detected — archive with source deletion under .swarm/ is not allowed');if(/^zip\b.*\s-m\b/i.test(seg)&&/\.swarm(?:[\x5c/\s]|$)/i.test(seg))throwDestructiveBlock("archive delete source",'BLOCKED: "zip" with delete-source flag targeting .swarm/ detected — archive with source deletion under .swarm/ is not allowed');if(/^7z\b.*\s-sdel\b/i.test(seg)&&/\.swarm(?:[\x5c/\s]|$)/i.test(seg))throwDestructiveBlock("archive delete source",'BLOCKED: "7z" with delete-source flag targeting .swarm/ detected — archive with source deletion under .swarm/ is not allowed');{let HUMAN_ONLY_SWARM_SUBCOMMANDS=HUMAN_ONLY_SWARM_COMMANDS,probe2=seg.replace(/^(?:[A-Za-z_][A-Za-z0-9_]*(?:="[^"]*"|='[^']*'|=\S+)\s+)+/,"").replace(/^eval(?:\s+--)?\s+["']?/,"").replace(/["']\s*$/,"").replace(/^\$\(\s*/,"").replace(/^\(\s*/,"").replace(/\s*\)$/,"").replace(/^`/,"").replace(/`$/,"").trim();for(let i=0;i<4;i++){let before=probe2;if(probe2=probe2.replace(/^env\s+(?:-i\b|--ignore-environment\b|-u\s+\S+|-[a-zA-Z]+\s+)*\s*/,"").replace(/^command\s+(?:-[pvV]\s+)*/,"").replace(/^(?:[A-Za-z_][A-Za-z0-9_]*(?:="[^"]*"|='[^']*'|=\S+)\s+)+/,"").trim(),probe2===before)break}let dequote=(input)=>input.replace(/["']/g,""),resolveVars=(input)=>input.replace(/\$\{?([A-Za-z_][A-Za-z0-9_]*)\}?/g,(full,name)=>swarmShellVars.has(name)?swarmShellVars.get(name):full),RUNNER_SHAPE=/^(?:\\|\/?(?:[\w.:%@=+-]+[/\\])*)?(?:bunx|npx|pnpx|npm|pnpm|yarn|bun|node|deno|tsx|ts-node|opencode-swarm)\b[^|;&]*?\brun\s+\$/i;for(let variant of[resolveVars(probe2),dequote(resolveVars(probe2))])if(RUNNER_SHAPE.test(variant))throwDestructiveBlock("human-only swarm command",'BLOCKED: "opencode-swarm run" invoked with an unresolvable shell variable or command substitution in the subcommand position. Re-run with the literal subcommand name so the human-only policy can be evaluated.');let probeVariants=[probe2,dequote(probe2),resolveVars(probe2),dequote(resolveVars(probe2))],matchCaptures=(re)=>{let captures=[];for(let variant of probeVariants){let m=variant.match(re);if(m?.[1])captures.push(m[1])}return captures},blockIfHumanOnly=(captures)=>{for(let captured of captures){let normalized=captured.trim().split(/\s+/).join(" "),firstToken=normalized.includes(" ")?normalized.split(" ")[0]:normalized,cmdName=HUMAN_ONLY_SWARM_SUBCOMMANDS.has(normalized)?normalized:firstToken;if(HUMAN_ONLY_SWARM_SUBCOMMANDS.has(normalized)||HUMAN_ONLY_SWARM_SUBCOMMANDS.has(firstToken))throwDestructiveBlock("human-only swarm command",`BLOCKED: "${cmdName}" is a human-only swarm command and may not be invoked from shell by an agent. Present the situation to the user and ask them to run \`/swarm ${cmdName}\` themselves.`)}};blockIfHumanOnly(matchCaptures(/^(?:\\|\/?(?:[\w.:%@=+-]+[/\\])*)?(?:bunx|npx|pnpx|npm(?:\s+(?:exec|x)(?:\s+--)?)?|pnpm(?:\s+(?:dlx|exec))?|yarn(?:\s+(?:dlx|exec))?|bun(?:\s+x)?|node|deno\s+run|tsx|ts-node)\b[^|;&]*?\bopencode-swarm\b[^|;&]*?\brun\s+([A-Za-z0-9_-]+(?:\s+(?!-)[A-Za-z0-9_-]+)?)/i)),blockIfHumanOnly(matchCaptures(/^(?:\\|\/?(?:[\w.:%@=+-]+[/\\])*)?opencode-swarm\b[^|;&]*?\brun\s+([A-Za-z0-9_-]+(?:\s+(?!-)[A-Za-z0-9_-]+)?)/i)),blockIfHumanOnly(matchCaptures(/\bcli[/\\]+index\.[mc]?(?:js|ts)\b[^|;&]*?\brun\s+([A-Za-z0-9_-]+(?:\s+(?!-)[A-Za-z0-9_-]+)?)/i))}{let normForPathCheck=seg.replace(/\\/g,"/").replace(/\/(?:\.\/+)+/g,"/").replace(/\/{2,}/g,"/");if(/\.swarm\/spec-staleness\.json\b/i.test(normForPathCheck)){let trimmed=seg.trim(),looksReadOnly=/^(?:cat|less|more|head|tail|file|stat|ls|dir|Get-Content|gc|Get-Item|gi|type)\b/i.test(trimmed),hasWriteRedirect=/>{1,2}\s*[^\s>]/.test(trimmed);if(!looksReadOnly||hasWriteRedirect)throwDestructiveBlock("system file tampering","BLOCKED: shell command targeting .swarm/spec-staleness.json detected. This file is system-managed and gates plan-mutating tools while spec drift is unresolved. Present the drift to the user and ask them to run /swarm acknowledge-spec-drift.")}}}}function detectShellType(command){if(/^(powershell|ps1|\.\s*\\|Remove-Item|Copy-Item|Move-Item|Start-Process|New-Object|Get-ChildItem|Set-Content|Add-Content|Out-File|Invoke-WebRequest|Invoke-RestMethod|IEX|iex)\b/i.test(command)||command.includes("$PSVersionTable")||command.includes("$env:")||/-EncodedCommand|-ExecutionPolicy|Enable-PSRemoting/i.test(command))return"powershell";if(/^(cmd|c:\/|set \w+=|\.\d+|del \/|rd \/|mkdir|chdir|echo |copy |move |ren |fc |diskpart)/i.test(command)||/%[^%\s]+%/.test(command)||/\b(set|echo|if|exist)\s+/i.test(command))return"cmd";if(/^(bash|sh|zsh|ksh|ash|dash|fish|ruby|python|perl|npm|yarn|node|cargo|go|rustc|mv|cp|rm|chmod|chown|mkdir|ln|tar|gzip|gunzip|ssh|scp|rsync|sudo|su -|export |source |\.\s+)/i.test(command)||command.includes("|")||command.includes("&&")||command.includes(">>")||/\$\{?\w+\}?/.test(command))return"bash";return"unix"}function checkShellWriteScope(sessionID,callID,tool3,args2,commandOverride,options){let enforce=options?.enforce!==!1;if(tool3!=="bash"&&tool3!=="shell")return;let session=swarmState.agentSessions.get(sessionID),toolArgs=args2,command=typeof commandOverride==="string"?commandOverride.trim():typeof toolArgs?.command==="string"?toolArgs.command.trim():"";if(!command)return;let normalizedTool=tool3,detectedShellType=detectShellType(command),shaped=isPowerShellShaped(command),shellType=detectedShellType;if(enforce&&(shellType==="powershell"||shellType==="cmd"?[shellType,"posix"]:["posix"]).some((candidate)=>detectInteractiveSession(command,candidate)))throw Error("BLOCKED: interactive/session tool detected — rejecting for safety");let windowsShell=resolveWindowsWriteAuthority(normalizedTool,command,detectedShellType,shaped),wrapperDeclaredHere=declaresWindowsWrapperLoose(command),windowsAuthoritative=wrapperDeclaredHere||normalizedTool!=="bash",detect=(c)=>{let posix14=detectPosixWrites(c);if(windowsShell===null)return posix14;return mergeWriteAnalyses(posix14,detectWindowsWrites(c,windowsShell),windowsAuthoritative,wrapperDeclaredHere)},suppressParseError=(c)=>enforce&&isPowerShellReadOnlyPipeline(c),primaryAnalysis=detect(command);if(enforce&&primaryAnalysis.parseError&&!suppressParseError(command))throw Error("BLOCKED: bash write detection failed to parse command — rejecting for safety");let commandSegments=dcSplitSegments(command),unwrappedSegments=commandSegments.map((s)=>dcUnwrapWrappers(s)),didUnwrap=commandSegments.some((s,i)=>unwrappedSegments[i]!==s),detectionCommand=didUnwrap?unwrappedSegments.join(`
|
|
1197
1197
|
`):command,analysis=didUnwrap?detect(detectionCommand):primaryAnalysis;if(enforce&&analysis.parseError&&!suppressParseError(detectionCommand))throw Error("BLOCKED: bash write detection failed to parse command — rejecting for safety");if(!analysis.hasWrites||analysis.writes.length===0)return;let declaredScope=resolveDeclaredScope(sessionID,!enforce),shellWriteAgent=swarmState.activeAgent.get(sessionID);if(!shellWriteAgent){if(enforce)throw Error(`WRITE BLOCKED: No active agent registered for session "${sessionID}". Agent identity must be established (e.g. via a chat message or Task delegation) before shell writes can be authorized.`);return}let shellWriteRole=stripKnownSwarmPrefix(shellWriteAgent).toLowerCase(),isArch=shellWriteRole==="architect",isCoder=shellWriteRole==="coder",shellRoleCapability=AUTHORITY_ROLE_CAPABILITIES[shellWriteRole],isImmutableNonWriter=shellRoleCapability==="read-only"||shellRoleCapability==="dedicated-tool-only";if(enforce&&isCoder&&(!declaredScope||declaredScope.length===0))throw Error(`SCOPE_NOT_DECLARED: ${shellWriteAgent} cannot perform shell writes without an active Task-correlated scope binding. ACTION[architect]: call declare_scope with the exact workspace-relative paths and replace_existing=true, then dispatch a new Task call.`);let noScopeLenient=!isArch&&!isCoder&&!isImmutableNonWriter&&(!declaredScope||declaredScope.length===0),shellDirectory=sessionWorkspaceDirectory(sessionID),resolvedWrites=resolveWriteTargets(detectionCommand,analysis.writes,shellDirectory);for(let write of resolvedWrites){if(write.resolvedPath===null){if(write.original.category==="here_doc"&&write.original.path===null)continue;if(enforce&&write.original.category==="interpreter_eval")throw Error(`BLOCKED: ${write.original.operator} evaluates inline code whose write targets cannot be verified against the declared scope — rejecting for safety. Write files with the write/edit tools or a checked-in script, and invoke installed tools directly (e.g. \`pytest\`, \`ruff\`) instead of an inline \`python -c\` / \`node -e\` eval.`);if(enforce)throw Error(`BLOCKED: bash/shell write to a dynamic path target${write.original.path?` "${write.original.path}"`:""} that cannot be statically resolved (shell variable or command substitution) — rejecting for safety.`);continue}if(enforce&&noScopeLenient&&universalDenyPrefixes.length>0){for(let prefix of universalDenyPrefixes)if(matchesAuthorityDenyPrefix(write.resolvedPath,prefix,shellDirectory))throw Error(`WRITE BLOCKED: Agent "${shellWriteAgent}" is not authorised to write "${write.resolvedPath}" (via shell). Reason: Path is under universal deny prefix "${prefix}"`)}if(noScopeLenient)continue;let authorityCheck=checkFileAuthorityWithRules(shellWriteAgent,write.resolvedPath,shellDirectory,precomputedAuthorityRules,{declaredScope,authorityEnabled:authorityConfig?.enabled,universalDenyPrefixes,verifierConfigPaths:authorityConfig?.verifier_config_paths});if(enforce&&!authorityCheck.allowed){let evidenceEventID=authorityCheck.layer==="protected-path"?recordFullAutoSevereEvidenceEvent({sessionID,childSessionID:sessionID,category:"protected_state_mutation",paths:[write.resolvedPath]}):void 0;throw Error(`WRITE BLOCKED: Agent "${shellWriteAgent}" is not authorised to write "${write.resolvedPath}" (via shell). Reason: ${authorityCheck.reason}${evidenceEventID?` Evidence event: ${evidenceEventID}.`:""}`)}if(enforce&&declaredScope&&declaredScope.length>0&&!isInDeclaredScope(write.resolvedPath,declaredScope,shellDirectory)){let safeTarget=sanitizeDiagnosticText(write.resolvedPath,320),scopeSummary=declaredScope.slice(0,10).map((entry)=>sanitizeDiagnosticText(entry,160)).join(", "),omitted=Math.max(0,declaredScope.length-10);throw Error(`WRITE BLOCKED: SCOPE_VIOLATION: shell write target "${safeTarget}" is outside the active scope [${scopeSummary}${omitted>0?`, ... (+${omitted} more)`:""}]. ACTION[architect]: if the target is intended, call declare_scope for the exact workspace-relative path and redispatch; otherwise correct the command.`)}if(isCoder&&session?.currentTaskId){let writeBinding=enforce?resolveActiveScopeBinding(sessionID):resolveActiveScopeBindingObserving(sessionID);if(writeBinding?.activation==="active"&&writeBinding.parentOwnerSessionId&&writeBinding.parentCallId){let relativeTarget=path100.relative(path100.resolve(shellDirectory),path100.resolve(shellDirectory,write.resolvedPath)).replace(/\\/g,"/");if(recordReviewerScopeGenerationFile({parentSessionID:writeBinding.parentOwnerSessionId,taskId:writeBinding.taskId,coderCallID:writeBinding.parentCallId,file:relativeTarget}))rememberReviewerScopeWrite?.({callID,parentSessionID:writeBinding.parentOwnerSessionId,taskId:writeBinding.taskId,coderCallID:writeBinding.parentCallId,file:relativeTarget})}}}if(isCoder&&session?.currentTaskId){let binding=enforce?resolveActiveScopeBinding(sessionID):resolveActiveScopeBindingObserving(sessionID);if(binding)rememberScopeLeaseCandidate?.({callID,sessionID,tool:tool3,directory:shellDirectory,binding,targets:resolvedWrites.flatMap((write)=>write.resolvedPath===null?[]:[path100.resolve(shellDirectory,write.resolvedPath)]),args:args2})}}function isSandboxWrapperInvocation(raw){let head=raw.replace(/^\s*(?:(?:exec|(?:\/(?:usr\/)?bin\/)?env)(?:\s+(?:-\S+|[A-Za-z_]\w*=\S*))*\s+)*/,"");return/^(?:\/(?:usr\/(?:local\/)?)?bin\/)?bwrap(?:\s|$)/.test(head)}async function applySandboxExecution(sessionID,callID,tool3,args2,agent,command,auditEnabled){if(tool3!=="bash"&&tool3!=="shell")return;let toolArgs=args2,rawCommand=typeof toolArgs?.command==="string"?toolArgs.command.trim():"";if(!rawCommand||!toolArgs)return;let executor=await getSandboxExecutor(),sandboxConfig=cfg.sandbox,originalCommandHash=hashArgs({command:rawCommand}),commandIdentity=`cmd=${originalCommandHash}`,assessment=await assessSandboxEnforcement2(sandboxConfig?{mode:sandboxConfig.mode,require_filesystem:sandboxConfig.require_filesystem,require_network:sandboxConfig.require_network,require_process:sandboxConfig.require_process,network_mode:sandboxConfig.network_mode,network_allowlist:sandboxConfig.network_allowlist,writable_roots:sandboxConfig.writable_roots}:void 0),capabilityIdentity=`cap=${assessment.capability.identity}`,recordOutcome2=(outcome)=>recordSandboxWrapOutcome({...outcome,sessionID,callID,originalCommandHash,originalCommand:rawCommand,assessmentCacheKey:assessment.cacheKey,executorMechanism:executor?.mechanism??"none",capabilityMechanism:assessment.capability.mechanism}),clearRecordedOutcome=()=>{clearSandboxWrapOutcome(sessionID,callID)};if(sandboxConfig?.mode==="required"){let assessmentSupported=assessment.supported!==!1,assessmentUnsupported=assessment.unsupported??[],missing=!executor||!executor.isAvailable()?["executor"]:assessment.missing;if(!executor||!executor.isAvailable()||!assessmentSupported||!assessment.satisfied){let missingOrUnsupported=assessmentSupported?missing.join(", "):assessmentUnsupported.join(", "),skipReason=missing[0]==="executor"?`required sandbox executor unavailable [${commandIdentity} ${capabilityIdentity}]`:!assessmentSupported?`required sandbox policy unsupported (${missingOrUnsupported}) [${commandIdentity} ${capabilityIdentity}]`:`required sandbox capability unsatisfied (${missingOrUnsupported}) [${commandIdentity} ${capabilityIdentity}]`;throw recordOutcome2({finalCommandHash:originalCommandHash,wrapped:!1,capabilityIdentity:assessment.capability.identity,reason:skipReason}),clearRecordedOutcome(),appendGuardrailDecision({type:"sandbox_skip",ts:new Date().toISOString(),sessionID,agent,tool:tool3,command,executorMechanism:executor?.mechanism??"none",skipReason},{directory:effectiveDirectory,enabled:auditEnabled}),Error(`[sandbox] BLOCKED: Required sandbox policy unsatisfied (${missingOrUnsupported}). [${commandIdentity} ${capabilityIdentity}] Command will not be executed unsandboxed.`)}}if(!executor||!executor.isAvailable()){if(recordOutcome2({finalCommandHash:originalCommandHash,wrapped:!1,capabilityIdentity:assessment.capability.identity,reason:"executor not available"}),!hasWarnedSandboxUnavailable)hasWarnedSandboxUnavailable=!0,criticalWarn("[guardrails] sandbox executor unavailable; shell commands will run unsandboxed. Run /swarm diagnose for details.");appendGuardrailDecision({type:"sandbox_skip",ts:new Date().toISOString(),sessionID,agent,tool:tool3,command,executorMechanism:executor?.mechanism??"none",skipReason:"executor not available"},{directory:effectiveDirectory,enabled:auditEnabled});return}let declaredPaths=resolveDeclaredScope(sessionID,!enforcePolicy);if(!declaredPaths||declaredPaths.length===0){if(recordOutcome2({finalCommandHash:originalCommandHash,wrapped:!1,capabilityIdentity:assessment.capability.identity,reason:"no declared scope"}),sandboxConfig?.mode==="required")throw clearRecordedOutcome(),Error("[sandbox] BLOCKED: Required sandbox policy needs a declared writable scope; command will not execute unsandboxed.");return}let resolved=resolveScopePaths(declaredPaths,sessionWorkspaceDirectory(sessionID)),configuredWritableRoots=resolveScopePaths(sandboxConfig?.writable_roots??[],sessionWorkspaceDirectory(sessionID));if(configuredWritableRoots.rejected.length>0){if(recordOutcome2({finalCommandHash:originalCommandHash,wrapped:!1,capabilityIdentity:assessment.capability.identity,reason:`configured writable_roots rejected (${configuredWritableRoots.rejected.map((item)=>item.path).join(", ")})`}),sandboxConfig?.mode==="required")throw clearRecordedOutcome(),Error("[sandbox] BLOCKED: Required sandbox policy contains writable_roots outside the session workspace; command will not execute unsandboxed.");return}if(resolved.paths.length===0){if(recordOutcome2({finalCommandHash:originalCommandHash,wrapped:!1,capabilityIdentity:assessment.capability.identity,reason:"resolved scope empty"}),sandboxConfig?.mode==="required")throw clearRecordedOutcome(),Error("[sandbox] BLOCKED: Required sandbox policy resolved no writable scope; command will not execute unsandboxed.");return}let writablePaths=[...new Set([...resolved.paths,...configuredWritableRoots.paths])];if(normalizeSandboxMechanism2(executor.mechanism)==="bubblewrap"&&isSandboxWrapperInvocation(rawCommand))throw recordOutcome2({finalCommandHash:originalCommandHash,wrapped:!1,capabilityIdentity:assessment.capability.identity,reason:"command already invokes the sandbox wrapper"}),clearRecordedOutcome(),Error(`[sandbox] BLOCKED: the command already invokes bwrap. Every bash call is sandboxed by the harness (${executor.mechanism}); a nested wrapper fails with "No permissions to create new namespace". Re-issue the plain command without the bwrap prefix.`);let workspaceRoot=sessionWorkspaceDirectory(sessionID),readonlyWorkspaceRoot=workspaceRoot;try{readonlyWorkspaceRoot=fs62.realpathSync(workspaceRoot)}catch{}try{let envOverrides=pluginOwnsExecutorEnv(executor.mechanism)?executor.getEnvOverrides():void 0,wrappedCommand=executor.wrapCommand(rawCommand,writablePaths,void 0,envOverrides,{network_mode:sandboxConfig?.network_mode??"off",network_allowlist:sandboxConfig?.network_allowlist??[],writable_roots:configuredWritableRoots.paths,readonly_roots:[readonlyWorkspaceRoot]});if(wrappedCommand.trim()===rawCommand)throw recordOutcome2({finalCommandHash:originalCommandHash,wrapped:!1,capabilityIdentity:assessment.capability.identity,reason:"sandbox wrapper returned the original command unchanged"}),clearRecordedOutcome(),Error(`[sandbox] BLOCKED: ${executor.mechanism} returned the original command unchanged. [${commandIdentity} ${capabilityIdentity}] Command will not be executed unsandboxed.`);if(normalizeSandboxMechanism2(executor.mechanism)!==normalizeSandboxMechanism2(assessment.capability.mechanism))throw recordOutcome2({finalCommandHash:originalCommandHash,wrapped:!1,capabilityIdentity:assessment.capability.identity,reason:"sandbox executor mechanism no longer matches the assessed capability"}),clearRecordedOutcome(),Error(`[sandbox] BLOCKED: sandbox executor mechanism drifted from the assessed capability (${executor.mechanism} != ${assessment.capability.mechanism}). [${commandIdentity} ${capabilityIdentity}]`);toolArgs.command=wrappedCommand,recordOutcome2({finalCommandHash:hashArgs({command:wrappedCommand}),wrapped:!0,capabilityIdentity:assessment.capability.identity,reason:"wrapped"}),markToolExecutionSandboxWrapped(sessionID,callID),appendGuardrailDecision({type:"sandbox_wrap",ts:new Date().toISOString(),sessionID,agent,tool:tool3,command:rawCommand,executorMechanism:executor.mechanism},{directory:effectiveDirectory,enabled:auditEnabled})}catch(err){recordOutcome2({finalCommandHash:originalCommandHash,wrapped:!1,capabilityIdentity:assessment.capability.identity,reason:err instanceof Error?err.message:String(err)}),clearRecordedOutcome(),forgetToolExecution(sessionID,callID);let message=`[sandbox] BLOCKED: Failed to wrap command with ${executor.mechanism}: ${err}. Command will not be executed unsandboxed.`,circuit=recordNonTransientFailure(sessionID,"sandbox_wrapper_failure",message,{tool:tool3,args:{command:rawCommand},armAttempt:!0});if(circuit?.hardStop)throw Error(nonTransientHardStopMessage(circuit));throw Error(message)}}async function checkGateLimits(params){let{sessionID,window:window2,agentConfig,elapsedMinutes,repetitionCount}=params;if(agentConfig.max_tool_calls>0&&window2.toolCalls>=agentConfig.max_tool_calls)throw window2.hardLimitHit=!0,telemetry.hardLimitHit(sessionID,window2.agentName,"tool_calls",window2.toolCalls),warn("Circuit breaker: tool call limit hit",{sessionID,agentName:window2.agentName,invocationId:window2.id,windowKey:`${window2.agentName}:${window2.id}`,resolvedMaxCalls:agentConfig.max_tool_calls,currentCalls:window2.toolCalls}),Error(`\uD83D\uDED1 LIMIT REACHED: Tool calls exhausted (${window2.toolCalls}/${agentConfig.max_tool_calls}). Finish the current operation and return your progress summary.`);if(agentConfig.max_duration_minutes>0&&elapsedMinutes>=agentConfig.max_duration_minutes)throw window2.hardLimitHit=!0,telemetry.hardLimitHit(sessionID,window2.agentName,"duration",elapsedMinutes),warn("Circuit breaker: duration limit hit",{sessionID,agentName:window2.agentName,invocationId:window2.id,windowKey:`${window2.agentName}:${window2.id}`,resolvedMaxMinutes:agentConfig.max_duration_minutes,elapsedMinutes:Math.floor(elapsedMinutes)}),Error(`\uD83D\uDED1 LIMIT REACHED: Duration exhausted (${Math.floor(elapsedMinutes)}/${agentConfig.max_duration_minutes} min). Finish the current operation and return your progress summary.`);if(repetitionCount>=agentConfig.max_repetitions)throw window2.hardLimitHit=!0,telemetry.hardLimitHit(sessionID,window2.agentName,"repetition",repetitionCount),Error(`\uD83D\uDED1 LIMIT REACHED: Repeated the same tool call ${repetitionCount} times. This suggests a loop. Return your progress summary.`);if(window2.consecutiveErrors>=agentConfig.max_consecutive_errors)throw window2.hardLimitHit=!0,telemetry.hardLimitHit(sessionID,window2.agentName,"consecutive_errors",window2.consecutiveErrors),Error(`\uD83D\uDED1 LIMIT REACHED: ${window2.consecutiveErrors} consecutive tool errors detected. Return your progress summary with details of what went wrong. Run /swarm reset-session to clear the circuit breaker without restarting your session.`);let idleMinutes=(Date.now()-window2.lastSuccessTimeMs)/60000;if(idleMinutes>=agentConfig.idle_timeout_minutes)throw window2.hardLimitHit=!0,telemetry.hardLimitHit(sessionID,window2.agentName,"idle_timeout",idleMinutes),warn("Circuit breaker: idle timeout hit",{sessionID,agentName:window2.agentName,invocationId:window2.id,windowKey:`${window2.agentName}:${window2.id}`,idleTimeoutMinutes:agentConfig.idle_timeout_minutes,idleMinutes:Math.floor(idleMinutes)}),Error(`\uD83D\uDED1 LIMIT REACHED: No successful tool call for ${Math.floor(idleMinutes)} minutes (idle timeout: ${agentConfig.idle_timeout_minutes} min). This suggests the agent may be stuck. Return your progress summary.`);if(!window2.warningIssued){let toolPct=agentConfig.max_tool_calls>0?window2.toolCalls/agentConfig.max_tool_calls:0,durationPct=agentConfig.max_duration_minutes>0?elapsedMinutes/agentConfig.max_duration_minutes:0,repPct=repetitionCount/agentConfig.max_repetitions,errorPct=window2.consecutiveErrors/agentConfig.max_consecutive_errors,reasons=[];if(agentConfig.max_tool_calls>0&&toolPct>=agentConfig.warning_threshold)reasons.push(`tool calls ${window2.toolCalls}/${agentConfig.max_tool_calls}`);if(durationPct>=agentConfig.warning_threshold)reasons.push(`duration ${Math.floor(elapsedMinutes)}/${agentConfig.max_duration_minutes} min`);if(repPct>=agentConfig.warning_threshold)reasons.push(`repetitions ${repetitionCount}/${agentConfig.max_repetitions}`);if(errorPct>=agentConfig.warning_threshold)reasons.push(`errors ${window2.consecutiveErrors}/${agentConfig.max_consecutive_errors}`);if(reasons.length>0)window2.warningIssued=!0,window2.warningReason=reasons.join(", ")}}function handleDelegatedWriteTracking(sessionID,tool3,args2){if(!swarmState.agentSessions.get(sessionID)?.delegationActive&&isArchitect(sessionID)){let coderDeleg=isAgentDelegation(tool3,args2);if(coderDeleg.isDelegation&&coderDeleg.targetAgent==="coder"){let coderSession=swarmState.agentSessions.get(sessionID);if(coderSession){let taskId=coderSession.currentTaskId??coderSession.lastCoderDelegationTaskId??`${sessionID}:unknown`;if(coderSession.currentTaskId=taskId,resetModifiedFilesForTask(coderSession,taskId),!coderSession.revisionLimitHit)coderSession.coderRevisions=0}}}}function isAgentDelegation(toolName,args2){if(!isTaskToolId(toolName))return{isDelegation:!1,targetAgent:null};let argsObj=args2;if(!argsObj)return{isDelegation:!1,targetAgent:null};let subagentType=argsObj.subagent_type;if(typeof subagentType==="string")return{isDelegation:!0,targetAgent:stripKnownSwarmPrefix(subagentType)};return{isDelegation:!1,targetAgent:null}}function handleLoopDetection(sessionID,tool3,args2){if(!isTaskToolId(tool3))return;let loopArgs=args2,loopResult=detectLoop(sessionID,tool3,loopArgs);if(loopResult.count>=5)throw Error(`CIRCUIT BREAKER: Delegation loop detected (${loopResult.count} identical patterns). Further identical delegations are blocked. Diagnose or rescope the task before retrying.`);else if(loopResult.count>=3&&loopResult.count<5){let agentName=typeof loopArgs?.subagent_type==="string"?loopArgs.subagent_type:"agent",loopSession=swarmState.agentSessions.get(sessionID);if(loopSession){let loopPattern=loopResult.pattern,modifiedFiles=loopSession.currentTaskId?getModifiedFilesForTask(loopSession,loopSession.currentTaskId):[],accomplishmentSummary=modifiedFiles.length>0?`Modified ${modifiedFiles.length} file(s): ${modifiedFiles.slice(0,3).join(", ")}${modifiedFiles.length>3?"...":""}`:"No files modified yet",alternativeSuggestions={coder:"Try a different task spec, simplify the constraint, or escalate to user",reviewer:"Try a different review dimension or escalate to user",test_engineer:"Run a specific test file with targeted scope",explorer:"Narrow the search scope or check a specific file directly"},cleanAgent=stripKnownSwarmPrefix(agentName).toLowerCase(),suggestion=alternativeSuggestions[cleanAgent]??"Try a different agent, different instructions, or escalate to the user";loopSession.loopWarningPending={agent:agentName,message:[`LOOP DETECTED: Pattern "${loopPattern}" repeated 3 times.`,`Agent: ${agentName}`,`Accomplished: ${accomplishmentSummary}`,`Suggested action: ${suggestion}`,"If still stuck after trying alternatives, escalate to the user."].join(`
|
|
1198
1198
|
`),timestamp:Date.now()}}}}function handleTestSuiteBlocking(tool3,args2){if(tool3!=="bash"&&tool3!=="shell")return;let bashArgs=args2,cmd=(typeof bashArgs?.command==="string"?bashArgs.command:"").trim();if(/^(bun\s+test|npm\s+test|npx\s+vitest|bunx\s+vitest)\b/.test(cmd)){let tokens=cmd.split(/\s+/),runnerTokenCount=tokens[0]==="npx"||tokens[0]==="bunx"?3:2;if(!tokens.slice(runnerTokenCount).some((token)=>token.length>0&&!token.startsWith("-")&&(token.includes("/")||token.includes("\\")||token.endsWith(".ts")||token.endsWith(".js")||token.endsWith(".tsx")||token.endsWith(".jsx")||token.endsWith(".mts")||token.endsWith(".mjs"))))throw Error("BLOCKED: Full test suite execution is not allowed in-session. Run a specific test file instead: bun test path/to/file.test.ts")}}function extractAllPatchPayloads(args2){let toolArgs=args2;if(!toolArgs)return[];let out=[];for(let key2 of PATCH_PAYLOAD_KEYS){let v=toolArgs[key2];if(typeof v==="string"&&v.length>0)out.push(v)}let cmd=toolArgs.cmd;if(Array.isArray(cmd)){for(let entry of cmd)if(typeof entry==="string"&&entry.length>0)out.push(entry)}return out}function getHumanOnlyAlternation(){return[...HUMAN_ONLY_SWARM_COMMANDS].map((c)=>c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).sort((a,b)=>b.length-a.length).join("|")}function patchPayloadHasHumanOnlyInvocation(args2){let payloads=extractAllPatchPayloads(args2);if(payloads.length===0)return!1;let alternation=getHumanOnlyAlternation(),re=new RegExp(`\\bopencode-swarm\\b[\\s\\S]*?\\brun\\s+(${alternation})\\b`,"i");return payloads.some((p)=>re.test(p))}function extractPatchTargetPaths(tool3,args2){if(tool3!=="apply_patch"&&tool3!=="swarm_apply_patch"&&tool3!=="patch")return[];let toolArgs=args2,paths=new Set;if(Array.isArray(toolArgs?.files)){for(let f of toolArgs.files)if(typeof f==="string"&&f.length>0&&f!=="/dev/null")paths.add(f)}let patchText;for(let key2 of["input","patch","diff"]){let v=toolArgs?.[key2];if(typeof v==="string"){patchText=v;break}}if(patchText===void 0)for(let key2 of PATCH_PAYLOAD_KEYS){if(key2==="patch"||key2==="input"||key2==="diff")continue;let v=toolArgs?.[key2];if(typeof v==="string"){patchText=v;break}}if(patchText===void 0&&Array.isArray(toolArgs?.cmd))patchText=toolArgs.cmd[1];if(typeof patchText!=="string")return Array.from(paths);if(patchText.length>1e6)throw Error("WRITE BLOCKED: Patch payload exceeds 1 MB — authority cannot be verified for all modified paths. Split into smaller patches.");let normalizedPatchText=normalizePatchIndentation(patchText),patchPathPattern=/\*\*\*\s+(?:Update|Add|Delete)\s+File:\s*(.+)/gi,diffPathPattern=/\+\+\+\s+b\/(.+)/gm,gitDiffPathPattern=/^diff --git a\/(.+?) b\/(.+?)$/gm,minusPathPattern=/^---\s+a\/(.+)$/gm,traditionalMinusPattern=/^---\s+([^\s].+?)(?:\t.*)?$/gm,traditionalPlusPattern=/^\+\+\+\s+([^\s].+?)(?:\t.*)?$/gm;for(let match of normalizedPatchText.matchAll(patchPathPattern))paths.add(match[1].trim());for(let match of normalizedPatchText.matchAll(diffPathPattern)){let p=match[1].trim();if(p!=="/dev/null")paths.add(p)}for(let match of normalizedPatchText.matchAll(gitDiffPathPattern)){let aPath=match[1].trim(),bPath=match[2].trim();if(aPath!=="/dev/null")paths.add(aPath);if(bPath!=="/dev/null")paths.add(bPath)}for(let match of normalizedPatchText.matchAll(minusPathPattern)){let p=match[1].trim();if(p!=="/dev/null")paths.add(p)}for(let match of normalizedPatchText.matchAll(traditionalMinusPattern)){let p=match[1].trim();if(p!=="/dev/null"&&!p.startsWith("a/")&&!p.startsWith("b/"))paths.add(p)}for(let match of normalizedPatchText.matchAll(traditionalPlusPattern)){let p=match[1].trim();if(p!=="/dev/null"&&!p.startsWith("a/")&&!p.startsWith("b/"))paths.add(p)}return Array.from(paths)}function handlePlanAndScopeProtection(sessionID,tool3,args2){let toolArgs=args2,targetPath=toolArgs?.filePath??toolArgs?.path??toolArgs?.file??toolArgs?.target;if(tool3==="apply_patch"||tool3==="swarm_apply_patch"||tool3==="patch"){if(patchPayloadHasHumanOnlyInvocation(args2))throw Error("BLOCKED: apply_patch/swarm_apply_patch would introduce a script invoking a human-only swarm CLI subcommand. Present the situation to the user and ask them to run the command themselves.")}if(typeof targetPath==="string"&&targetPath.length>0){let resolvedTarget=path100.resolve(effectiveDirectory,targetPath).toLowerCase(),planMdPath=path100.resolve(effectiveDirectory,".swarm","plan.md").toLowerCase(),planJsonPath=path100.resolve(effectiveDirectory,".swarm","plan.json").toLowerCase();if(resolvedTarget===planMdPath||resolvedTarget===planJsonPath)throw Error("PLAN STATE VIOLATION: Direct writes to .swarm/plan.md and .swarm/plan.json are blocked. plan.md is auto-regenerated from plan.json by PlanSyncWorker. Use save_plan for ALL structural plan changes (adding/removing tasks, updating descriptions, dependencies, or phase names). Use update_task_status() for task status only. Use phase_complete() for phase transitions only.");let specStalenessPath=path100.resolve(effectiveDirectory,".swarm","spec-staleness.json").toLowerCase();if(resolvedTarget===specStalenessPath)throw Error("SPEC_DRIFT_VIOLATION: Direct writes to .swarm/spec-staleness.json are blocked. This file is system-managed and gates plan-mutating tools while spec drift is unresolved. Present the drift to the user and ask them to run /swarm acknowledge-spec-drift.");let content=toolArgs?.content??toolArgs?.text??toolArgs?.new_string??toolArgs?.newText;if(typeof content==="string"&&new RegExp(`\\bopencode-swarm\\b[\\s\\S]*?\\brun\\s+(${getHumanOnlyAlternation()})\\b`,"i").test(content))throw Error("BLOCKED: write/edit tool would create a script invoking a human-only swarm CLI subcommand. Present the situation to the user and ask them to run the command themselves.")}if(!targetPath&&(tool3==="apply_patch"||tool3==="swarm_apply_patch"||tool3==="patch"))for(let p of extractPatchTargetPaths(tool3,args2)){let resolvedP=path100.resolve(effectiveDirectory,p),planMdPath=path100.resolve(effectiveDirectory,".swarm","plan.md").toLowerCase(),planJsonPath=path100.resolve(effectiveDirectory,".swarm","plan.json").toLowerCase(),specStalenessPath=path100.resolve(effectiveDirectory,".swarm","spec-staleness.json").toLowerCase();if(resolvedP.toLowerCase()===planMdPath||resolvedP.toLowerCase()===planJsonPath)throw Error("PLAN STATE VIOLATION: Direct writes to .swarm/plan.md and .swarm/plan.json are blocked. plan.md is auto-regenerated from plan.json by PlanSyncWorker. Use save_plan for ALL structural plan changes (adding/removing tasks, updating descriptions, dependencies, or phase names). Use update_task_status() for task status only. Use phase_complete() for phase transitions only.");if(resolvedP.toLowerCase()===specStalenessPath)throw Error("SPEC_DRIFT_VIOLATION: Direct writes to .swarm/spec-staleness.json are blocked. This file is system-managed and gates plan-mutating tools while spec drift is unresolved. Present the drift to the user and ask them to run /swarm acknowledge-spec-drift.");if(isOutsideSwarmDir(p,effectiveDirectory)&&(isSourceCodePath(p)||hasTraversalSegments(p))){let session=swarmState.agentSessions.get(sessionID);if(session)session.architectWriteCount++,warn("Architect direct code edit detected via patch tool",{tool:tool3,sessionID,targetPath:p,writeCount:session.architectWriteCount});break}}if(typeof targetPath==="string"&&targetPath.length>0&&isOutsideSwarmDir(targetPath,effectiveDirectory)&&isSourceCodePath(path100.relative(effectiveDirectory,path100.resolve(effectiveDirectory,targetPath)))){let session=swarmState.agentSessions.get(sessionID);if(session){if(session.architectWriteCount++,warn("Architect direct code edit detected",{tool:tool3,sessionID,targetPath,writeCount:session.architectWriteCount}),session.lastGateFailure&&Date.now()-session.lastGateFailure.timestamp<120000){let failedGate=session.lastGateFailure.tool,failedTaskId=session.lastGateFailure.taskId;warn("Self-fix after gate failure detected",{failedGate,failedTaskId,currentTool:tool3,sessionID}),session.selfFixAttempted=!0}}}}function resolveSessionAndWindow(sessionID){let rawActiveAgent=swarmState.activeAgent.get(sessionID),strippedAgent=rawActiveAgent?stripKnownSwarmPrefix(rawActiveAgent):void 0;if(strippedAgent===ORCHESTRATOR_NAME)return null;if(strippedAgent&&isNativeOpencodeAgent(strippedAgent))return null;let existingSession=swarmState.agentSessions.get(sessionID);if(existingSession){let sessionAgent=stripKnownSwarmPrefix(existingSession.agentName);if(sessionAgent===ORCHESTRATOR_NAME)return null;if(isNativeOpencodeAgent(sessionAgent))return null}let agentName=swarmState.activeAgent.get(sessionID)??ORCHESTRATOR_NAME,session=ensureAgentSession(sessionID,agentName),resolvedName=stripKnownSwarmPrefix(session.agentName);if(resolvedName===ORCHESTRATOR_NAME)return null;if(isNativeOpencodeAgent(resolvedName))return null;let agentConfig=resolveGuardrailsConfig(cfg,session.agentName);if(agentConfig.max_duration_minutes===0&&agentConfig.max_tool_calls===0)return null;if(!getActiveWindow(sessionID)){let fallbackAgent=swarmState.activeAgent.get(sessionID)??session.agentName;if(stripKnownSwarmPrefix(fallbackAgent)!==ORCHESTRATOR_NAME)beginInvocation(sessionID,fallbackAgent)}let window2=getActiveWindow(sessionID);if(!window2)return null;return{agentConfig,window:window2}}function isNativeOpencodeAgent(agentName){return OPENCODE_NATIVE_AGENTS.has(agentName.toLowerCase())}function trackToolCall(window2,tool3,args2){if(window2.hardLimitHit)throw Error("\uD83D\uDED1 CIRCUIT BREAKER: Agent blocked. Hard limit was previously triggered. Stop making tool calls and return your progress summary.");window2.toolCalls++;let hash4=hashArgs(args2);if(window2.recentToolCalls.push({tool:tool3,argsHash:hash4,timestamp:Date.now()}),window2.recentToolCalls.length>20)window2.recentToolCalls.shift();let repetitionCount=0;if(window2.recentToolCalls.length>0){let lastEntry=window2.recentToolCalls[window2.recentToolCalls.length-1];for(let i=window2.recentToolCalls.length-1;i>=0;i--){let entry=window2.recentToolCalls[i];if(entry.tool===lastEntry.tool&&entry.argsHash===lastEntry.argsHash)repetitionCount++;else break}}let elapsedMinutes=(Date.now()-window2.startedAtMs)/60000;return{repetitionCount,elapsedMinutes}}return async(input,output)=>{if(enforcePolicy)assertNonTransientCircuitAllowsTool(input.sessionID,{tool:input.tool,args:output.args});let resolvedSessionWindow=swarmState.agentSessions.has(input.sessionID)||swarmState.activeAgent.has(input.sessionID)?resolveSessionAndWindow(input.sessionID):null,session=swarmState.agentSessions.get(input.sessionID),rawAgentForScope=swarmState.activeAgent.get(input.sessionID),isCoder=rawAgentForScope!==void 0&&stripKnownSwarmPrefix(rawAgentForScope).toLowerCase()==="coder";if(consecutiveNoToolTurns.set(input.sessionID,0),observeExecutionStallToolCall({sessionID:input.sessionID,tool:input.tool,args:output.args,callID:input.callID,options:executionStallOptions}),handleDelegatedWriteTracking(input.sessionID,input.tool,output.args),enforcePolicy)handleLoopDetection(input.sessionID,input.tool,output.args);if(enforcePolicy)handleTestSuiteBlocking(input.tool,output.args);let rawShellCommand=(()=>{let bashArgs=output.args;return typeof bashArgs?.command==="string"?bashArgs.command:""})(),normalizedAuditTool=normalizeToolName(input.tool).toLowerCase();if(normalizedAuditTool==="bash"||normalizedAuditTool==="shell")appendGuardrailDecision({type:"shell",ts:new Date().toISOString(),sessionID:input.sessionID,agent:(()=>{let rawAgent=swarmState.activeAgent.get(input.sessionID);return rawAgent?stripKnownSwarmPrefix(rawAgent):"unknown"})(),tool:input.tool,command:(()=>{let bashArgs=output.args,rawCmd=typeof bashArgs?.command==="string"?bashArgs.command:"";return redactShellCommand(rawCmd)})()},{directory:effectiveDirectory,enabled:shellAuditEnabled});if(enforcePolicy)handleInterpreterGating(input.sessionID,input.tool);try{if(enforcePolicy)checkDestructiveCommand(input.sessionID,input.tool,output.args)}catch(err){let destructiveCategory=err instanceof DestructiveCommandBlockedError?err.destructiveCategory:"destructive shell command";throw appendGuardrailDecision({type:"destructive_block",ts:new Date().toISOString(),sessionID:input.sessionID,agent:(()=>{let rawAgent=swarmState.activeAgent.get(input.sessionID);return rawAgent?stripKnownSwarmPrefix(rawAgent):"unknown"})(),tool:input.tool,command:(()=>{let bashArgs=output.args;return typeof bashArgs?.command==="string"?bashArgs.command:""})(),destructiveCategory},{directory:effectiveDirectory,enabled:shellAuditEnabled}),err}try{checkShellWriteScope(input.sessionID,input.callID,input.tool,output.args,rawShellCommand,{enforce:enforcePolicy})}catch(err){let toolArgs=output.args,declaredScope=resolveDeclaredScope(input.sessionID,!0),declaredScopeText=declaredScope!=null&&declaredScope.length>0?declaredScope.join(", "):"",resolvedScopeText=declaredScope!=null&&declaredScope.length>0?resolveScopePaths(declaredScope,sessionWorkspaceDirectory(input.sessionID)).paths.join(", "):"",pathMatch=/[^\s]+/.exec(err instanceof Error?err.message:String(err)),targetPath=(()=>{let p=toolArgs?.filePath??toolArgs?.path??toolArgs?.file??toolArgs?.target;if(typeof p==="string"&&p.length>0)return p;let rawMessage=err instanceof Error?err.message:String(err),extracted=/(?:write|target|file|path|scope|prefix)[^:]*:\s*(?:"([^"]+)"|'([^']+)'|(\S+))/i.exec(rawMessage)??/(?:write|target|file|path)\s+(?:"([^"]+)"|'([^']+)'|(\S+))/i.exec(rawMessage),candidate=extracted!=null?extracted[1]??extracted[2]??extracted[3]??extracted[4]??extracted[5]??extracted[6]:null;if(candidate&&candidate.length>0&&candidate.length<200)return candidate;if(pathMatch)return pathMatch[0];return"<shell write>"})(),agentName=(()=>{let rawAgent=swarmState.activeAgent.get(input.sessionID);return rawAgent?stripKnownSwarmPrefix(rawAgent):"unknown"})();throw appendGuardrailDecision({type:"scope_violation",ts:new Date().toISOString(),sessionID:input.sessionID,agent:agentName,tool:input.tool,path:targetPath,declaredScope:declaredScopeText,resolvedScope:resolvedScopeText,action:"bash"},{directory:effectiveDirectory,enabled:shellAuditEnabled}),err}let agentNameForSandbox=(()=>{let rawAgent=swarmState.activeAgent.get(input.sessionID);return rawAgent?stripKnownSwarmPrefix(rawAgent):"unknown"})();if(rememberToolExecution(input.sessionID,input.callID,input.tool,rawShellCommand),enforcePolicy)await applySandboxExecution(input.sessionID,input.callID,input.tool,output.args,agentNameForSandbox,rawShellCommand,shellAuditEnabled);if(enforcePolicy)enforceSpecDriftGate(effectiveDirectory,input.tool);if(enforcePolicy&&isArchitect(input.sessionID)&&isWriteTool(input.tool))handlePlanAndScopeProtection(input.sessionID,input.tool,output.args);if(input.tool==="apply_patch"||input.tool==="swarm_apply_patch"||input.tool==="patch"){let patchArgs=output.args,structuralPatch=typeof patchArgs?.input==="string"?patchArgs.input:typeof patchArgs?.patch==="string"?patchArgs.patch:typeof patchArgs?.diff==="string"?patchArgs.diff:void 0;if(structuralPatch===void 0)for(let key2 of PATCH_PAYLOAD_KEYS){let value=patchArgs?.[key2];if(typeof value==="string"){structuralPatch=value;break}}if(structuralPatch===void 0&&Array.isArray(patchArgs?.cmd)&&typeof patchArgs.cmd[1]==="string")structuralPatch=patchArgs.cmd[1];if(structuralPatch===void 0&&typeof patchArgs?.cmd==="string")structuralPatch=patchArgs.cmd;if((structuralPatch??"").length>1e6)throw Error("WRITE BLOCKED: Patch payload exceeds 1 MB — authority cannot be verified for all modified paths. Split into smaller patches.")}let writeDirectory=sessionWorkspaceDirectory(input.sessionID),resolvedFileTargets=null;if(isWriteTool(input.tool)){let resolution=resolveWriteTargets2(normalizeToolName(input.tool),output.args,{directory:writeDirectory});if(resolution.status==="unverifiable"){if(enforcePolicy)throw Error(`WRITE TARGET UNVERIFIABLE: ${resolution.reason}`)}else resolvedFileTargets=resolution.paths;let writeBinding=session?.currentTaskId&&isCoder?enforcePolicy?resolveActiveScopeBinding(input.sessionID):resolveActiveScopeBindingObserving(input.sessionID):null;if(writeBinding)rememberScopeLeaseCandidate?.({callID:input.callID,sessionID:input.sessionID,tool:input.tool,directory:writeDirectory,binding:writeBinding,targets:(resolvedFileTargets??[]).map((target)=>path100.resolve(writeDirectory,target)),args:output.args})}if(isWriteTool(input.tool))for(let targetPath of resolvedFileTargets??[]){let agentName=swarmState.activeAgent.get(input.sessionID);if(!agentName){if(!enforcePolicy)continue;throw Error(`WRITE BLOCKED: No active agent registered for session "${input.sessionID}". Call startAgentSession before issuing write tool calls.`)}let lstatBlock=checkWriteTargetForSymlink(targetPath,writeDirectory);if(lstatBlock){if(appendGuardrailDecision({type:"file_write",ts:new Date().toISOString(),sessionID:input.sessionID,agent:agentName,tool:input.tool,path:targetPath,reason:lstatBlock,resolvedScope:(()=>{let scope=resolveDeclaredScope(input.sessionID,!enforcePolicy);return scope!=null&&scope.length>0?scope.join(", "):""})()},{directory:effectiveDirectory,enabled:shellAuditEnabled}),enforcePolicy)throw Error(lstatBlock)}let writeBinding=session?.currentTaskId&&isCoder?enforcePolicy?resolveActiveScopeBinding(input.sessionID):resolveActiveScopeBindingObserving(input.sessionID):null,writeDeclaredScope=writeBinding?.files??null,authorityCheck=checkFileAuthorityWithRules(agentName,targetPath,writeDirectory,precomputedAuthorityRules,{declaredScope:writeDeclaredScope,authorityEnabled:authorityConfig?.enabled,universalDenyPrefixes,verifierConfigPaths:authorityConfig?.verifier_config_paths});if(!authorityCheck.allowed){let evidenceEventID=authorityCheck.layer==="protected-path"?recordFullAutoSevereEvidenceEvent({sessionID:input.sessionID,childSessionID:input.sessionID,category:"protected_state_mutation",paths:[targetPath]}):void 0;if(appendGuardrailDecision({type:"file_write",ts:new Date().toISOString(),sessionID:input.sessionID,agent:agentName,tool:input.tool,path:targetPath,reason:authorityCheck.reason,resolvedScope:(()=>{let scope=writeDeclaredScope;return scope!=null&&scope.length>0?scope.join(", "):""})()},{directory:effectiveDirectory,enabled:shellAuditEnabled}),!enforcePolicy)continue;throw Error(`WRITE BLOCKED: Agent "${agentName}" is not authorised to write "${targetPath}". Reason: ${authorityCheck.reason}${evidenceEventID?` Evidence event: ${evidenceEventID}.`:""}`)}let trackingSession=swarmState.agentSessions.get(input.sessionID),auditContext=trackingSession?.delegationActive?"delegated":"direct",auditOperation=["apply_patch","swarm_apply_patch","patch"].includes(normalizeToolName(input.tool))?"patch":"write";if(isConfigFilePath(targetPath,writeDirectory,authorityConfig?.verifier_config_paths)){let normalizedPath=path100.relative(path100.resolve(writeDirectory),path100.resolve(writeDirectory,targetPath)).replace(/\\/g,"/"),logEntry={agent:agentName,path:normalizedPath,allowed:authorityCheck.allowed,type:`${auditContext}_${auditOperation}`};if(!authorityCheck.allowed&&"reason"in authorityCheck)logEntry.reason=authorityCheck.reason;warn("Config file write attempt",logEntry)}if(trackingSession?.delegationActive){let taskId=trackingSession.currentTaskId??trackingSession.lastCoderDelegationTaskId??`${input.sessionID}:unknown`;trackingSession.currentTaskId=taskId,recordModifiedFileForTask(trackingSession,taskId,targetPath,writeDirectory)}if(writeBinding?.activation==="active"&&writeBinding.parentOwnerSessionId&&writeBinding.parentCallId){let relativeTarget=path100.relative(path100.resolve(writeDirectory),path100.resolve(writeDirectory,targetPath)).replace(/\\/g,"/");if(recordReviewerScopeGenerationFile({parentSessionID:writeBinding.parentOwnerSessionId,taskId:writeBinding.taskId,coderCallID:writeBinding.parentCallId,file:relativeTarget}))rememberReviewerScopeWrite?.({callID:input.callID,parentSessionID:writeBinding.parentOwnerSessionId,taskId:writeBinding.taskId,coderCallID:writeBinding.parentCallId,file:relativeTarget})}}let resolved=resolvedSessionWindow;if(resolved){let{agentConfig,window:window2}=resolved,{repetitionCount,elapsedMinutes}=trackToolCall(window2,input.tool,output.args);if(enforcePolicy)await checkGateLimits({sessionID:input.sessionID,window:window2,agentConfig,elapsedMinutes,repetitionCount})}if(enforcePolicy){let prmSession=swarmState.agentSessions.get(input.sessionID);if(prmSession?.prmHardStopPending){prmSession.prmHardStopPending=!1;let patternType=prmSession.prmLastPatternDetected?.pattern??"unknown";throw telemetry.prmHardStopDelivered(input.sessionID,patternType,prmSession.prmEscalationLevel,prmSession.prmPatternCounts?.get(patternType)??0),Error("\uD83D\uDED1 PRM HARD STOP: Pattern escalation maximum reached. Stop tool calls and return progress summary.")}}if(enforceInternalsGuard({sessionID:input.sessionID,tool:input.tool,args:output.args,directory:effectiveDirectory,options:internalsGuardOptions}),enforceExecutionStallDenial({sessionID:input.sessionID,tool:input.tool,options:executionStallOptions}),!resolved)return;setStoredInputArgs(input.callID,output.args)}}var hasWarnedSandboxUnavailable=!1,DestructiveCommandBlockedError;var init_tool_before=__esm(()=>{init_tool_policy();init_constants();init_schema();init_severe_result();init_executor();init_scope_resolver();init_skip_state();init_path_identity();init_scope_persistence();init_scope_resolution_diagnostic();init_command_classifier();init_state();init_telemetry();init_utils();init_core3();init_loop_detector();init_normalize_tool_name();init_shell_executor_context();init_shell_write_detect();init_write_target_resolver();init_audit_log();init_destructive_command();init_execution_stall();init_file_authority();init_guardrails();init_internals_guard();init_nontransient_circuit();init_stored_input_args();init_helpers();DestructiveCommandBlockedError=class DestructiveCommandBlockedError extends Error{destructiveCategory;constructor(message,destructiveCategory){super(message);this.destructiveCategory=destructiveCategory;this.name="DestructiveCommandBlockedError"}}});import*as fsSync11 from"node:fs";import*as path101 from"node:path";function emitDurableAttributionAdvisory(sessionID,key2,message){let now=Date.now(),prior=durableAttributionAdvisoryBySession.get(sessionID);if(prior&&prior.key===key2&&now-prior.at<DURABLE_ATTRIBUTION_ADVISORY_COOLDOWN_MS)return;if(!prior&&durableAttributionAdvisoryBySession.size>=MAX_DURABLE_ATTRIBUTION_ADVISORY_SESSIONS){let oldest=durableAttributionAdvisoryBySession.keys().next().value;if(oldest!==void 0)durableAttributionAdvisoryBySession.delete(oldest)}durableAttributionAdvisoryBySession.set(sessionID,{key:key2,at:now});let session=swarmState.agentSessions.get(sessionID);if(session)pushAdvisory(session,message);else criticalWarn(`[guardrails] ${message}`)}function stageAWriteErrorCode(error93){let message=error93 instanceof Error?error93.message:String(error93),match=/^[A-Z][A-Z0-9_]+/.exec(message);return match?match[0]:null}function extractGateCallFiles(args2){if(!args2||typeof args2!=="object")return null;let raw=args2.files;if(Array.isArray(raw)){let files=raw.filter((entry)=>typeof entry==="string"&&entry!=="");return files.length>0?files:null}let changed2=args2.changed_files;if(Array.isArray(changed2)){let files=changed2.map((entry)=>typeof entry==="string"?entry:entry&&typeof entry==="object"&&typeof entry.path==="string"?entry.path:null).filter((entry)=>entry!==null&&entry!=="");return files.length>0?files:null}return null}async function resolveDurableGateTaskId(directory,callerFiles){try{let{states,truncated}=await listCoderSettlementWalStates(directory),eligible=[],inFlightAtCoderDelegated=new Set;for(let state2 of states){if(!isStrictTaskId(state2.taskId))continue;if(state2.state==="DISPATCHED"||state2.state==="PREPARED"){if(getTaskWorkflowSnapshot(await readTaskEvidence(directory,state2.taskId)).state==="coder_delegated")inFlightAtCoderDelegated.add(state2.taskId);continue}if(state2.state!=="COMMITTED")continue;if(state2.accepted!==!0)continue;if(getTaskWorkflowSnapshot(await readTaskEvidence(directory,state2.taskId)).state==="coder_delegated")eligible.push(state2)}let ambiguousIds=new Set([...eligible.map((s)=>s.taskId),...inFlightAtCoderDelegated]);if(ambiguousIds.size>1)return{ambiguous:[...ambiguousIds].sort()};if(eligible.length===1){let candidate=eligible[0];if(truncated)return{unbound:candidate.taskId,reason:"truncated"};let declared=candidate.declaredFiles,normalizedCallerFiles=callerFiles!==null?normalizeScopeFiles(callerFiles):null;if(normalizedCallerFiles!==null&&normalizedCallerFiles.length>0&&declared!==null&&declared!==void 0&&declared.length>0&&declared.some((f)=>f!==""&&normalizedCallerFiles.includes(f)))return{taskId:candidate.taskId};return{unbound:candidate.taskId,reason:"files_mismatch"}}return null}catch(error93){return warn("Durable gate attribution fallback failed",{error:String(error93)}),null}}function enforceSpecDriftGate(directory,toolName){if(!directory)return;if(!SPEC_DRIFT_BLOCKED_TOOLS.has(toolName))return;let stalePath=path101.join(directory,".swarm","spec-staleness.json");if(fsSync11.existsSync(stalePath)){let diffInfo=null;try{diffInfo=computeSpecDiff(directory)}catch{}let message=`SPEC_DRIFT_BLOCK: tool "${toolName}" is blocked because .swarm/spec-staleness.json exists. Run /swarm clarify to enter spec repair mode. Clarify alone does not clear drift: rewrite the spec so recovery can reconcile it, or run /swarm acknowledge-spec-drift to dismiss, then retry.`;if(diffInfo){let sectionSummary=diffInfo.changedSections.length>0?`
|
|
1199
1199
|
Changed sections: ${diffInfo.changedSections.map((s)=>`## ${s}`).join(", ")}`:"";message+=`
|
|
@@ -7431,7 +7431,7 @@ Review before proceeding.`;injectSystemMessage(input.sessionID,message)}}}init_c
|
|
|
7431
7431
|
`):void 0}function entryModelIds(entry){if(!entry||typeof entry!=="object")return{};let record3=entry,providerID=typeof record3.model?.providerID==="string"?record3.model.providerID:typeof record3.providerID==="string"?record3.providerID:void 0,modelID=typeof record3.model?.id==="string"?record3.model.id:typeof record3.modelID==="string"?record3.modelID:void 0;return{providerID,modelID}}function idleOutcome(entries2){for(let i=entries2.length-1;i>=0;i-=1){let entry=entries2[i];if(!entry||typeof entry!=="object")continue;let record3=entry;if(record3.type!=="idle")continue;return typeof record3.outcome==="string"?record3.outcome:void 0}return}function recordedErrorToInfoError(error93){if(error93&&typeof error93==="object"){let record3=error93,message=typeof record3.data?.message==="string"&&record3.data.message.length>0?record3.data.message:typeof record3.message==="string"&&record3.message.length>0?record3.message:"no message",statusCodeValue=typeof record3.data?.statusCode==="number"&&Number.isFinite(record3.data.statusCode)?record3.data.statusCode:typeof record3.statusCode==="number"&&Number.isFinite(record3.statusCode)?record3.statusCode:typeof record3.status==="number"&&Number.isFinite(record3.status)?record3.status:void 0;return{name:typeof record3.name==="string"&&record3.name.length>0?record3.name.slice(0,64):"ProviderError",data:{message,...statusCodeValue===void 0?{}:{statusCode:statusCodeValue}}}}return{name:"ProviderError",data:{message:"v2 session failed without recorded error detail"}}}function classifyContextEntries(entries2){let lastUserIndex=entries2.reduce((last,entry,index)=>isUserEntry(entry)?index:last,-1),assistantEntries=entries2.slice(lastUserIndex+1).filter(isAssistantEntry),texts=assistantEntries.map(entryText2).filter((text)=>typeof text==="string"),outcome=idleOutcome(entries2);return{outcome,texts,model:assistantEntries.reduce((acc,entry)=>{let ids=entryModelIds(entry);if(ids.providerID!==void 0&&ids.modelID!==void 0)return{providerID:ids.providerID,modelID:ids.modelID};return acc},{}),needsErrorLookup:outcome==="failed"||outcome===void 0&&texts.length===0}}function buildTranslatedPromptData(classification,recordedError){if(classification.needsErrorLookup||recordedError!==void 0)return{info:{error:recordedErrorToInfoError(recordedError)},parts:[]};return{info:classification.model,parts:classification.texts.map((text)=>({type:"text",text}))}}async function deferredV2SessionErrorRecheck(realId){for(let attempt=0;attempt<ERROR_RECHECK_ATTEMPTS;attempt+=1){if(sessionErrors.has(realId))return sessionErrors.get(realId);if(attempt<ERROR_RECHECK_ATTEMPTS-1)await new Promise((resolve121)=>setTimeout(resolve121,ERROR_RECHECK_DELAY_MS))}return}async function deferredV2SessionTranslate(entries2,sessionId){let classification=classifyContextEntries(entries2),recordedError=sessionErrors.get(sessionId);if(classification.needsErrorLookup&&recordedError===void 0)recordedError=await deferredV2SessionErrorRecheck(sessionId);return buildTranslatedPromptData(classification,recordedError)}async function deferredV2SessionGetParentDirectory(ctx,parentID){let info=await ctx.session.get({sessionID:parentID});if(!info||typeof info!=="object")return;let location=info.location;return typeof location?.directory==="string"?location.directory:void 0}async function deferredV2SessionWait(ctx,realId,signal2){if(signal2?.aborted)throw await ctx.session.interrupt({sessionID:realId}).catch(()=>{return}),Error("v2 session-client: prompt wait aborted");await new Promise((resolve121,reject3)=>{let settled=!1,timer=signal2===void 0?setTimeout(()=>{if(settled)return;settled=!0,ctx.session.interrupt({sessionID:realId}).catch(()=>{return}).finally(()=>{reject3(Error("v2 session-client: signal-less prompt wait exceeded cap"))})},SIGNAL_LESS_WAIT_CAP_MS):void 0,onAbort=()=>{if(settled)return;if(settled=!0,timer!==void 0)clearTimeout(timer);ctx.session.interrupt({sessionID:realId}).catch(()=>{return}).finally(()=>{reject3(Error("v2 session-client: prompt wait aborted"))})};signal2?.addEventListener("abort",onAbort,{once:!0}),Promise.resolve(ctx.session.wait({sessionID:realId})).then(()=>{if(settled)return;if(settled=!0,timer!==void 0)clearTimeout(timer);signal2?.removeEventListener("abort",onAbort),resolve121()}).catch((error93)=>{if(settled)return;if(settled=!0,timer!==void 0)clearTimeout(timer);signal2?.removeEventListener("abort",onAbort),reject3(error93 instanceof Error?error93:String(error93))})})}function makeV2SessionContextHandler(realId,system,tools){return(event)=>{let typed=event;if(!typed||typed.sessionID!==realId)return Promise.resolve();if(system!==void 0&&Array.isArray(typed.system)){let fenced=typed.system.filter((part)=>part&&typeof part.text==="string"&&part.text.includes(SYSTEM_DIRECTIVE_FENCE_OPEN));typed.system.length=0,typed.system.push(...fenced.map((part)=>({type:"text",text:part.text})),{type:"text",text:system})}if(tools&&typed.tools&&typeof typed.tools==="object"){let deleted=0;for(let name of Object.keys(tools))if(Object.hasOwn(typed.tools,name))delete typed.tools[name],deleted+=1;if(deleted>0)log("v2 session-client: denied tools via context hook",{count:deleted})}return Promise.resolve()}}function promptBodyText(parts){if(!Array.isArray(parts))return"";let texts=[];for(let part of parts)if(part&&typeof part==="object"&&part.type==="text"&&typeof part.text==="string")texts.push(part.text);return texts.join(`
|
|
7432
7432
|
`)}async function deferredV2SessionPromptPlaceholder(ctx,_placeholderId,stash,body,text,signal2){if(stash.promptStarted=!0,signal2?.aborted)throw Error("v2 session-client: prompt wait aborted");let previousRealId=stash.realId;if(previousRealId!==void 0)stash.realId=void 0,stash.abortPending=!1,stash.deletePending=!1,await ctx.session.remove({sessionID:previousRealId}).catch(()=>{return});let agent=typeof body.agent==="string"?body.agent:void 0,model=body.model&&typeof body.model.providerID==="string"&&typeof body.model.modelID==="string"?{id:body.model.modelID,providerID:body.model.providerID}:void 0,system=typeof body.system==="string"?body.system:void 0,createdRecord=await ctx.session.create({...stash.parentID!==void 0?{parentID:stash.parentID}:{},...stash.title!==void 0?{title:stash.title}:{},...agent!==void 0?{agent}:{},...model!==void 0?{model}:{},location:{directory:stash.directory},permissions:readOnlyToolsToV2Permissions(body.tools)}),realId=typeof createdRecord?.id==="string"?createdRecord.id:void 0;if(realId===void 0)throw Error("v2 session-client: session create returned no id");let echoedDirectory=typeof createdRecord.location?.directory==="string"?createdRecord.location.directory:void 0;if(echoedDirectory!==void 0&&!sameDirectoryLexical(echoedDirectory,stash.directory))throw await ctx.session.remove({sessionID:realId}).catch(()=>{return}),Error(`v2 session-client: created session landed in ${echoedDirectory}, not the requested ${stash.directory} (#3169 Phase 0 C1)`);sessionErrors.delete(realId);let registration;try{if(system!==void 0||body.tools!==void 0)registration=await ctx.session.hook("context",makeV2SessionContextHandler(realId,system,body.tools));await ctx.session.prompt({sessionID:realId,text}),await deferredV2SessionWait(ctx,realId,signal2);let entries2=await ctx.session.context({sessionID:realId});return{data:await deferredV2SessionTranslate(Array.isArray(entries2)?entries2:[],realId)}}finally{if(stash.realId=realId,registration?.dispose)await registration.dispose().catch(()=>{return});if(stash.abortPending)await ctx.session.interrupt({sessionID:realId}).catch(()=>{return});if(stash.deletePending)sessionErrors.delete(realId),await ctx.session.remove({sessionID:realId}).catch(()=>{return})}}async function deferredV2SessionPromptReal(ctx,sessionId,body,text,signal2){if(typeof body.agent==="string"){let switchAgent=ctx.session.switchAgent;if(typeof switchAgent==="function")await switchAgent({sessionID:sessionId,agent:body.agent})}sessionErrors.delete(sessionId),await ctx.session.prompt({sessionID:sessionId,text}),await deferredV2SessionWait(ctx,sessionId,signal2);let entries2=await ctx.session.context({sessionID:sessionId});return{data:await deferredV2SessionTranslate(Array.isArray(entries2)?entries2:[],sessionId)}}function resolveSessionId(id){let stash=placeholderSessions.get(id);if(stash===void 0)return id;return stash.realId}function createV2SessionClient(ctx){let session=ctx?.session;if(!session||typeof session!=="object")return;for(let member of["create","get","remove","prompt","wait","context","interrupt","hook"])if(typeof session[member]!=="function")return;return{session:{create:(args2)=>deferredV2SessionCreate(ctx,args2),prompt:(args2)=>deferredV2SessionPrompt(ctx,args2),abort:(args2)=>{let id=args2?.path?.id,resolved=resolveSessionId(id);if(resolved!==void 0)return ctx.session.interrupt({sessionID:resolved}).catch(()=>{return});let stash=placeholderSessions.get(id);if(stash?.promptStarted)stash.abortPending=!0;return Promise.resolve(void 0)},delete:(args2)=>{let id=args2?.path?.id,stash=placeholderSessions.get(id),resolved=resolveSessionId(id);if(resolved!==void 0)return sessionErrors.delete(resolved),deferredV2SessionRemoveEager(ctx,resolved).then((outcome)=>{if(stash?.eager===!0&&outcome.ok)placeholderSessions.delete(id);else if(stash?.eager===!0)log("v2 session-client: eager delete cleanup failed",{reason:outcome.reason})});if(stash?.promptStarted)stash.deletePending=!0;return Promise.resolve(void 0)},get:(args2)=>{let id=args2?.path?.id,stash=placeholderSessions.get(id),overlayParentID=stash?.eager===!0&&typeof stash.parentID==="string"?stash.parentID:void 0,resolved=resolveSessionId(id);if(resolved===void 0)return Promise.resolve({data:null});return ctx.session.get({sessionID:resolved}).then((info)=>({data:overlayParentID!==void 0&&info&&typeof info==="object"?{...info,parentID:overlayParentID}:info})).catch((error93)=>({data:null,error:error93}))}}}}var MAX_PATH_IN_MESSAGE_CHARS=200;function boundPathForMessage(path316){if(path316===void 0)return"an unverifiable location";if(path316.length<=MAX_PATH_IN_MESSAGE_CHARS)return path316;return`${path316.slice(0,MAX_PATH_IN_MESSAGE_CHARS)}… (truncated)`}var EAGER_CLEANUP_TIMEOUT_MS=1e4;async function deferredV2SessionRemoveEager(ctx,sessionID){try{return await withTimeout(ctx.session.remove({sessionID}),EAGER_CLEANUP_TIMEOUT_MS,Error(`v2 session-client: eager cleanup of session ${sessionID} exceeded ${EAGER_CLEANUP_TIMEOUT_MS}ms`)),{ok:!0}}catch(error93){return{ok:!1,reason:error93 instanceof Error?error93.message:String(error93)}}}async function deferredV2SessionCreateEager(ctx,parentID,title,directory,signal2){let created;try{created=await ctx.session.create({...title!==void 0?{title}:{},location:{directory}})}catch(error93){return{data:null,error:{message:`v2 session-client: eager lane create failed (${error93 instanceof Error?error93.message:String(error93)})`}}}let createdRecord=created,realId=typeof createdRecord?.id==="string"?createdRecord.id:void 0;if(realId===void 0)return{data:null,error:{message:"v2 session-client: eager lane create returned no id (#3169 Phase 3)"}};if(signal2?.aborted){let compensated=await deferredV2SessionRemoveEager(ctx,realId);if(!compensated.ok)log("v2 session-client: aborted eager create compensation failed",{reason:compensated.reason});return{data:null,error:{message:`v2 session-client: eager lane create aborted by the caller; ${compensated.ok?"the created session was removed":`removing session ${realId} also failed (${compensated.reason??"unknown error"}) — remove it manually`}`,...compensated.ok?{}:{sessionID:realId,cleanupFailed:!0}}}}let landed=typeof createdRecord.location?.directory==="string"?createdRecord.location.directory:void 0;if(landed===void 0){let reported=await ctx.session.get({sessionID:realId}).catch(()=>{return});landed=typeof reported?.location?.directory==="string"?reported.location.directory:void 0}if(landed===void 0||!sameDirectoryLexical(landed,directory)){let removed=await deferredV2SessionRemoveEager(ctx,realId);return{data:null,error:{message:`v2 session-client: eager lane create landed in ${boundPathForMessage(landed)}, not the requested ${boundPathForMessage(directory)} (#3169 Phase 3 placement guard; Phase 0 C1)${removed.ok?"":`; cleanup of session ${realId} also failed (${removed.reason??"unknown error"}) — remove it before retrying`}`,...removed.ok?{}:{sessionID:realId,cleanupFailed:!0}}}}return rememberPlaceholder(realId,{parentID,...title!==void 0?{title}:{},directory,realId,eager:!0}),{data:{id:realId}}}async function deferredV2SessionCreate(ctx,args2){let directory=args2?.query?.directory;if(typeof directory!=="string"||directory.length===0)return{data:null,error:{message:"v2 session-client: create requires query.directory (v1 contract)"}};let parentID=args2?.body?.parentID;if(parentID!==void 0){let parentDirectory=await deferredV2SessionGetParentDirectory(ctx,parentID).catch(()=>{return});if(parentDirectory===void 0)return{data:null,error:{message:"v2 session-client: parent session placement unverifiable (get returned no location.directory — live-verification item on #3169 Phase 2)"}};if(!sameDirectoryLexical(parentDirectory,directory))return deferredV2SessionCreateEager(ctx,parentID,args2?.body?.title,directory,args2?.signal)}placeholderCounter+=1;let placeholderId=`v2shim-${placeholderCounter}-${Math.random().toString(36).slice(2,10)}`;return rememberPlaceholder(placeholderId,{...parentID!==void 0?{parentID}:{},...args2?.body?.title!==void 0?{title:args2.body.title}:{},directory}),{data:{id:placeholderId}}}async function deferredV2SessionPromptEager(ctx,realId,body,text,signal2){if(signal2?.aborted)throw Error("v2 session-client: eager prompt aborted before dispatch");let agent=typeof body.agent==="string"?body.agent:void 0;if(agent!==void 0){let switchAgent=ctx.session.switchAgent;if(typeof switchAgent==="function")await switchAgent({sessionID:realId,agent});else log("v2 session-client: eager prompt skipped switchAgent (host lacks it)",{agent})}let model=body.model&&typeof body.model.providerID==="string"&&typeof body.model.modelID==="string"?{id:body.model.modelID,providerID:body.model.providerID}:void 0;if(model!==void 0){let switchModel=ctx.session.switchModel;if(typeof switchModel==="function")await switchModel({sessionID:realId,model});else log("v2 session-client: eager prompt skipped switchModel (host lacks it)",{model})}let system=typeof body.system==="string"?body.system:void 0;sessionErrors.delete(realId);let registration;try{if(system!==void 0||body.tools!==void 0)registration=await ctx.session.hook("context",makeV2SessionContextHandler(realId,system,body.tools));await ctx.session.prompt({sessionID:realId,text}),await deferredV2SessionWait(ctx,realId,signal2);let entries2=await ctx.session.context({sessionID:realId});return{data:await deferredV2SessionTranslate(Array.isArray(entries2)?entries2:[],realId)}}finally{if(registration?.dispose)await registration.dispose().catch(()=>{return})}}async function deferredV2SessionPrompt(ctx,args2){let id=args2?.path?.id;if(typeof id!=="string"||id.length===0)return{data:null,error:{message:"v2 session-client: prompt requires path.id"}};let body=args2?.body??{},text=promptBodyText(body.parts),stash=placeholderSessions.get(id);if(stash!==void 0&&stash.eager===!0&&stash.realId!==void 0)return deferredV2SessionPromptEager(ctx,stash.realId,body,text,args2?.signal);if(stash!==void 0)return deferredV2SessionPromptPlaceholder(ctx,id,stash,body,text,args2?.signal);return deferredV2SessionPromptReal(ctx,id,body,text,args2?.signal)}var V2_EVENT_BATCH_TIMEOUT_MS=60000,UNMAPPED_LOG_LIMIT=20;function mapV2EventToV1(envelope){let type=typeof envelope?.type==="string"?envelope.type:void 0;if(type===void 0)return;let data=envelope.data??envelope.properties??{},sessionID=typeof data.sessionID==="string"?data.sessionID:void 0;switch(type){case"session.idle":case"session.status.updated":return{type:"session.idle",properties:{...sessionID?{sessionID}:{},...data}};case"session.status":return{type:"session.status",properties:{...sessionID?{sessionID}:{},...data}};case"session.error":case"session.execution.failed":return{type:"session.error",properties:{...sessionID?{sessionID}:{},...data}};case"session.deleted":return{type:"session.deleted",properties:{...sessionID?{sessionID}:{},...data}};case"session.created":return{type:"session.created",properties:{...sessionID?{sessionID}:{},...data}};case"session.text.delta":case"session.tool.called":case"session.tool.input.delta":return{type:"message.part.updated",properties:{...sessionID?{sessionID}:{},...data}};case"session.text.ended":case"session.tool.success":case"session.tool.failed":return{type:"message.updated",properties:{...sessionID?{sessionID}:{},...data}};default:return}}async function deferredDispatch(hooks2,mapped){let handler=hooks2.event;if(typeof handler!=="function")return;await withTimeout(Promise.resolve(handler({event:{type:mapped.type,properties:mapped.properties}})),V2_EVENT_BATCH_TIMEOUT_MS,Error("[opencode-swarm] v2: event dispatch exceeded budget")).catch((err)=>{log("v2 event dispatch failed (non-fatal)",{type:mapped.type,error:err instanceof Error?err.message:String(err)})})}function seedSessionIdentityFromEnvelope(envelope){let type=typeof envelope?.type==="string"?envelope.type:void 0;if(type!=="session.created"&&type!=="session.agent.selected")return;let payload=envelope.data??envelope.properties??{},sessionID=typeof payload.sessionID==="string"?payload.sessionID:void 0,agent=typeof payload.agent==="string"?payload.agent:void 0;if(sessionID&&agent)recordSessionChatAgent(sessionID,agent)}function startDeferredEventPump(ctx,hooks2){let stopped=!1,unmappedSeen=new Set;return(async()=>{try{let subscribe2=ctx?.event?.subscribe;if(typeof subscribe2!=="function"){log("v2 event subscribe surface absent; event pump idle (non-fatal)",{});return}let iterable=await withTimeout(Promise.resolve(subscribe2()),V2_EVENT_BATCH_TIMEOUT_MS,Error("[opencode-swarm] v2: event subscribe exceeded budget"));if(!iterable||typeof iterable[Symbol.asyncIterator]!=="function"){log("v2 event subscribe returned a non-iterable; event pump idle (non-fatal)",{});return}for await(let envelope of iterable){if(stopped)break;seedSessionIdentityFromEnvelope(envelope),recordV2SessionErrorFromEnvelope(envelope);let mapped=mapV2EventToV1(envelope);if(mapped===void 0){let t=typeof envelope?.type==="string"?envelope.type:"(no type)";if(!unmappedSeen.has(t)&&unmappedSeen.size<UNMAPPED_LOG_LIMIT)unmappedSeen.add(t),log("v2 event type not mapped (ignored)",{type:t});continue}await deferredDispatch(hooks2,mapped)}}catch(err){if(!stopped)log("v2 event pump stopped on error (non-fatal)",{error:err instanceof Error?err.message:String(err)})}})(),()=>{stopped=!0}}init_system_guidance_carrier();init_utils();init_timeout();var V2_GUIDANCE_CHAIN_TIMEOUT_MS=30000;function toV1MessageView(message,sessionID){let textParts=[];for(let part of message.content??[])if(part&&typeof part==="object"&&part.type==="text"&&typeof part.text==="string")textParts.push({type:"text",text:part.text});return{info:{id:typeof message.id==="string"?message.id:void 0,role:message.role,sessionID},parts:textParts}}function writeBackTextParts(message,parts){let kept=(message.content??[]).filter((part)=>!(part&&typeof part==="object"&&part.type==="text")),texts=parts.filter((p)=>p.type==="text"&&typeof p.text==="string").map((p)=>({type:"text",text:p.text}));message.content=[...kept,...texts]}function toV1ModelInput(model){if(model&&typeof model==="object")return{providerID:typeof model.providerID==="string"?model.providerID:"unknown",modelID:typeof model.id==="string"?model.id:"unknown"};return{providerID:"unknown",modelID:"unknown"}}async function onV2ContextEvent(event,hooks2,directory){let sessionID=event.sessionID;seedV1SessionState(sessionID,event.agent,directory);let messagesTransform=hooks2["experimental.chat.messages.transform"];if(typeof messagesTransform==="function"){let views=(event.messages??[]).map((m)=>toV1MessageView(m,sessionID)),originalMessages=[...event.messages??[]];await withTimeout(messagesTransform({},{messages:views}),V2_GUIDANCE_CHAIN_TIMEOUT_MS,Error("[opencode-swarm] v2: messages transform exceeded budget")).catch((err)=>{log("v2 messages transform failed (non-fatal; original messages retained)",{error:err instanceof Error?err.message:String(err)});for(let i=0;i<originalMessages.length;i+=1)views[i]=toV1MessageView(originalMessages[i],sessionID)});let originalById=new Map,originalsWithoutId=[];for(let message of originalMessages){let id=typeof message.id==="string"?message.id:void 0;if(id!==void 0&&id.length>0)originalById.set(id,message);else originalsWithoutId.push(message)}let usedIds=new Set,nextIdless=0,keptParts=[];event.system=event.system??[];for(let view of views){let id=view.info.id;if(typeof id==="string"&&id.startsWith(GUIDANCE_CARRIER_ID_PREFIX)){for(let part of view.parts)if(part.type==="text"&&typeof part.text==="string"&&part.text.length>0)event.system.push({type:"text",text:part.text});continue}let message;if(typeof id==="string"&&id.length>0&&originalById.has(id)&&!usedIds.has(id))message=originalById.get(id),usedIds.add(id);else if((id===void 0||id.length===0)&&nextIdless<originalsWithoutId.length)message=originalsWithoutId[nextIdless],nextIdless+=1;if(message)keptParts.push({message,parts:view.parts})}for(let{message,parts}of keptParts)writeBackTextParts(message,parts);event.messages.length=0,event.messages.push(...keptParts.map((k)=>k.message))}let systemTransform=hooks2["experimental.chat.system.transform"];if(typeof systemTransform==="function"){let output={system:[]};await withTimeout(systemTransform({sessionID,model:toV1ModelInput(event.model)},output),V2_GUIDANCE_CHAIN_TIMEOUT_MS,Error("[opencode-swarm] v2: system transform exceeded budget")).catch((err)=>{log("v2 system transform failed (non-fatal)",{error:err instanceof Error?err.message:String(err)})});for(let text of output.system)if(typeof text==="string"&&text.length>0)event.system.push({type:"text",text})}}async function registerV2ContextHook(ctx,hooks2,directory,registrations){let registration=await withTimeout(ctx.session.hook("context",async(event)=>{return onV2ContextEvent(event,hooks2,directory)}),V2_GUIDANCE_CHAIN_TIMEOUT_MS,Error("[opencode-swarm] v2: context hook registration exceeded budget"));registrations.push(registration)}init_normalize_tool_name();init_utils();init_timeout();var V2_HOOK_TIMEOUT_MS=60000;function isV2SubagentToolId(toolName){if(!toolName)return!1;if(toolName.includes("."))return/^tool\.[^.:]+\.subagent$/i.test(toolName);return normalizeToolNameLowerCase(toolName)==="subagent"}function isPlainObject9(value){return typeof value==="object"&&value!==null&&!Array.isArray(value)}function mapV2SubagentArgsToV1(input){if(!isPlainObject9(input))return input;let mapped={};for(let[key2,value]of Object.entries(input))if(key2==="agent")mapped.subagent_type=value;else if(key2==="sessionID")mapped.task_id=value;else mapped[key2]=value;return mapped}function mapV1TaskArgsToV2(args2){if(!isPlainObject9(args2))return args2;let mapped={};for(let[key2,value]of Object.entries(args2))if(key2==="subagent_type")mapped.agent=value;else if(key2==="task_id")mapped.sessionID=value;else mapped[key2]=value;return mapped}var V2_SUBAGENT_WRAPPER_RE=/<subagent\s+sessionID="([^"]+)"\s+state="(running|completed|error|cancelled|canceled)"[^>]*>/,MAX_V2_WRAPPER_INNER_CHARS=20000;function parseV2SubagentWrapper(content){if(typeof content!=="string")return null;let match=content.match(V2_SUBAGENT_WRAPPER_RE);if(!match)return null;let sessionID=match[1];if(sessionID.includes("<")||sessionID.includes(">"))return null;let rawState=match[2],matchStart=match.index??0,inner=content.slice(matchStart+match[0].length).replace(/\s*<\/subagent>\s*$/,"");return{sessionID,state:rawState==="canceled"?"cancelled":rawState,inner}}var V2_WRAPPER_STRUCTURAL_TAG_RE=/<\/?(?:task_result|task_error|summary)>/g;function renderV1TaskEnvelopeFromV2(wrapper){let inner=wrapper.inner;if(inner.length>MAX_V2_WRAPPER_INNER_CHARS){let omitted=inner.length-MAX_V2_WRAPPER_INNER_CHARS;inner=`${inner.slice(0,MAX_V2_WRAPPER_INNER_CHARS)}
|
|
7433
7433
|
[... ${omitted} chars truncated by v2 task translation ...]`}return inner=inner.replace(V2_WRAPPER_STRUCTURAL_TAG_RE,(tag)=>tag.replace("<","<\\")),`<task id="${wrapper.sessionID}" state="${wrapper.state}"><task_result>${inner}</task_result></task>`}async function onV2ToolBefore(event,hooks2,directory){let handler=hooks2["tool.execute.before"];if(typeof handler!=="function")return;seedV1SessionState(event.sessionID,event.agent,directory);let isSubagent2=isV2SubagentToolId(event.tool),output={args:isSubagent2?mapV2SubagentArgsToV1(event.input):event.input};if(await withTimeout(Promise.resolve(handler({tool:isSubagent2?"task":event.tool,sessionID:event.sessionID,callID:event.id,agent:normalizeV2AgentRef(event.agent),messageID:event.messageID},output)),V2_HOOK_TIMEOUT_MS,Error("[opencode-swarm] v2: tool.execute.before exceeded budget")),isSubagent2){let mapped=mapV1TaskArgsToV2(output.args);if(isPlainObject9(event.input)&&isPlainObject9(mapped)){for(let key2 of Object.keys(event.input))delete event.input[key2];Object.assign(event.input,mapped)}}else event.input=output.args}async function onV2ToolAfter(event,hooks2,directory){let handler=hooks2["tool.execute.after"];if(typeof handler!=="function")return;seedV1SessionState(event.sessionID,event.agent,directory);let isSubagent2=isV2SubagentToolId(event.tool),output=translateV2ResultToV1Output(event,isSubagent2);await withTimeout(Promise.resolve(handler({tool:isSubagent2?"task":event.tool,sessionID:event.sessionID,callID:event.id,agent:normalizeV2AgentRef(event.agent),messageID:event.messageID,...isSubagent2?{args:mapV2SubagentArgsToV1(event.input)}:{}},output)),V2_HOOK_TIMEOUT_MS,Error("[opencode-swarm] v2: tool.execute.after exceeded budget")).catch((err)=>{log("v2 tool.execute.after failed (non-fatal)",{tool:event.tool,error:err instanceof Error?err.message:String(err)})})}function translateV2ResultToV1Output(event,isSubagent2){if(event.status==="error")return{title:"error",state:"error",output:event.error&&typeof event.error.message==="string"?event.error.message:"tool error",metadata:{}};let result=event.result,content=typeof result?.content==="string"?result.content:Array.isArray(result?.content)?(result?.content).filter((p)=>p.type==="text"&&typeof p.text==="string").map((p)=>p.text).join(`
|
|
7434
|
-
`):"";if(isSubagent2){let wrapper=parseV2SubagentWrapper(content);if(wrapper)return{title:"",state:wrapper.state==="running"?"running":wrapper.state==="completed"?"completed":wrapper.state==="error"?"error":"cancelled",output:renderV1TaskEnvelopeFromV2(wrapper),metadata:result?.metadata??{}};if(content.includes("<subagent"))log("v2 subagent wrapper not recognized; passing result text through",{chars:content.length})}return{title:"",state:"completed",output:content,metadata:result?.metadata??{}}}async function onV2Compaction(event,hooks2,directory){let handler=hooks2["experimental.session.compacting"];if(typeof handler!=="function")return;seedV1SessionState(event.sessionID,event.agent,directory);let model=event.model,output={};await withTimeout(Promise.resolve(handler({sessionID:event.sessionID,providerID:typeof model?.providerID==="string"?model.providerID:"unknown",modelID:typeof model?.id==="string"?model.id:"unknown"},output)),V2_HOOK_TIMEOUT_MS,Error("[opencode-swarm] v2: compaction hook exceeded budget")).catch((err)=>{log("v2 compaction hook failed (non-fatal)",{error:err instanceof Error?err.message:String(err)})})}async function onV2Prompt(event,hooks2){let handler=hooks2["chat.message"];if(typeof handler!=="function")return;let text=event.prompt?.text??"",message={id:event.messageID,role:"user",sessionID:event.sessionID},parts=[{type:"text",text}],input={sessionID:event.sessionID,message:{...message},parts:[...parts]},output={message:{...message},parts:[...parts]};if(await withTimeout(Promise.resolve(handler(input,output)),V2_HOOK_TIMEOUT_MS,Error("[opencode-swarm] v2: prompt hook exceeded budget")).catch((err)=>{log("v2 prompt (chat.message) hook failed (non-fatal)",{error:err instanceof Error?err.message:String(err)})}),typeof event.prompt==="object"&&event.prompt!==null){let rewritten=output.parts.find((p)=>p.type==="text"&&typeof p.text==="string");if(rewritten&&typeof rewritten.text==="string"&&rewritten.text!==text)event.prompt.text=rewritten.text}}async function registerV2ToolHooks(ctx,hooks2,directory,registrations){let before=await withTimeout(ctx.tool.hook("execute.before",async(event)=>{return onV2ToolBefore(event,hooks2,directory)}),V2_HOOK_TIMEOUT_MS,Error("[opencode-swarm] v2: execute.before registration exceeded budget"));registrations.push(before);let after=await withTimeout(ctx.tool.hook("execute.after",async(event)=>{return onV2ToolAfter(event,hooks2,directory)}),V2_HOOK_TIMEOUT_MS,Error("[opencode-swarm] v2: execute.after registration exceeded budget"));registrations.push(after)}async function registerV2SessionHooks(ctx,hooks2,directory,registrations){let compaction=await withTimeout(ctx.session.hook("compaction",async(event)=>{return onV2Compaction(event,hooks2,directory)}),V2_HOOK_TIMEOUT_MS,Error("[opencode-swarm] v2: compaction registration exceeded budget"));registrations.push(compaction);let prompt=await withTimeout(ctx.session.hook("prompt",async(event)=>{return onV2Prompt(event,hooks2)}),V2_HOOK_TIMEOUT_MS,Error("[opencode-swarm] v2: prompt registration exceeded budget"));registrations.push(prompt)}init_utils();init_timeout();var V2_TOOL_EXECUTE_TIMEOUT_MS=600000;function synthesizeV1ToolContext(context,projectRoot,permissionBridge){let agentName=normalizeV2AgentRef(context.agent)??"architect";return{sessionID:context.sessionID,messageID:context.messageID,agent:agentName,directory:projectRoot,worktree:projectRoot,abort:context.signal,metadata:(input)=>{try{let progress=context.progress;if(typeof progress==="function")progress({...input.metadata??{},...input.title!==void 0?{title:input.title}:{}})}catch{}},ask:async(input)=>{if(permissionBridge){await withTimeout(Promise.resolve(permissionBridge(input)),V2_TOOL_EXECUTE_TIMEOUT_MS,Error("[opencode-swarm] v2: permission bridge exceeded budget"));return}throw Error("[opencode-swarm] v2: interactive tool permission request unavailable (no permission surface); denying by default.")}}}function mapV1ToolResult(result){if(typeof result==="string")return{content:result};if(result&&typeof result==="object"){let rec=result;return{...typeof rec.output==="string"?{content:rec.output}:{},...rec.metadata&&typeof rec.metadata==="object"?{metadata:rec.metadata}:{}}}return{content:String(result??"")}}async function registerV2Tools(ctx,hooks2,projectRoot,registrations){let toolMap=hooks2.tool??{},permissionBridge=buildPermissionBridge(ctx),registration=await withTimeout(ctx.tool.transform((editor)=>{for(let[name,definition]of Object.entries(toolMap)){let v1Execute=definition.execute;if(typeof v1Execute!=="function")continue;let info={name,description:definition.description??"",input:v2ToolInputSchema(definition.args),execute:async(input,context)=>{seedV1SessionState(context.sessionID,context.agent,projectRoot);let result=await withTimeout(Promise.resolve(v1Execute(input,synthesizeV1ToolContext(context,projectRoot,permissionBridge))),V2_TOOL_EXECUTE_TIMEOUT_MS,Error(`[opencode-swarm] v2: tool ${name} exceeded execution budget`));return mapV1ToolResult(result)}};editor.add(info)}}),V2_TOOL_EXECUTE_TIMEOUT_MS,Error("[opencode-swarm] v2: tool transform exceeded budget"));registrations.push(registration)}function buildPermissionBridge(ctx){let permission=ctx.permission;if(!permission||typeof permission.reply!=="function")return;return async(input)=>{let askInput=input;log("v2 permission bridge invoked (best-effort passthrough)",{permission:typeof askInput?.permission==="string"?askInput.permission:"unknown",patternCount:Array.isArray(askInput?.patterns)?askInput.patterns.length:0}),await withTimeout(Promise.resolve(permission.reply?.(input)),V2_TOOL_EXECUTE_TIMEOUT_MS,Error("[opencode-swarm] v2: permission reply exceeded budget"))}}async function deferredV2StartupModelPreflight(directory){try{let loaded=await withTimeout(Promise.resolve(loadPluginConfigWithMeta(directory)),2000,Error("[opencode-swarm] v2: startup preflight config read exceeded budget")),models=collectEnabledAgentModels(loaded?.config).map((entry)=>entry.model).filter((model)=>typeof model==="string"&&model.length>0),quiet=loaded?.config?.quiet===!0;for(let warning of collectModelRosterWarnings(models,VERIFIED_KEYLESS_MODEL_ROSTER))if(addDeferredWarning(warning),!quiet)console.warn(warning)}catch(err){log("v2 startup model preflight failed (non-fatal)",{error:err instanceof Error?err.message:String(err)})}}var V2_SETUP_TIMEOUT_MS=60000;function normalizeV2AgentRef(agent){if(typeof agent==="string")return agent;if(agent&&typeof agent==="object"){let rec=agent;if(typeof rec.id==="string"&&rec.id.length>0)return rec.id;if(typeof rec.name==="string"&&rec.name.length>0)return rec.name}return}async function openCodeSwarmV2Setup(ctx,deps){let rawDirectory=ctx?.location?.directory;if(typeof rawDirectory!=="string"||rawDirectory.length===0)throw Error("[opencode-swarm] v2 setup: host Context carried no location.directory; refusing to start (invariant 4).");let rootDecision=resolveProjectRootDecision(rawDirectory),directory=rootDecision.kind==="redirect"?rootDecision.owningRoot:rootDecision.kind==="root"?rootDecision.directory:rawDirectory,state2={registrations:[]},input={client:createV2SessionClient(ctx),directory,worktree:directory},hooks2=await withTimeout(deps.runInit(input),V2_SETUP_TIMEOUT_MS,Error("[opencode-swarm] v2 setup: initialization exceeded budget"));await withTimeout(registerV2AgentsAndCommands(ctx,hooks2,directory,state2.registrations),V2_SETUP_TIMEOUT_MS,Error("[opencode-swarm] v2 setup: agent/command registration exceeded budget")).catch((err)=>{log("v2 agent/command registration failed (non-fatal)",{error:err instanceof Error?err.message:String(err)})}),await withTimeout(registerV2Tools(ctx,hooks2,directory,state2.registrations),V2_SETUP_TIMEOUT_MS,Error("[opencode-swarm] v2 setup: tool registration exceeded budget")).catch((err)=>{log("v2 tool registration failed (non-fatal)",{error:err instanceof Error?err.message:String(err)})}),await withTimeout(registerV2ContextHook(ctx,hooks2,directory,state2.registrations),V2_SETUP_TIMEOUT_MS,Error("[opencode-swarm] v2 setup: guidance registration exceeded budget")).catch((err)=>{log("v2 context-hook registration failed (non-fatal)",{error:err instanceof Error?err.message:String(err)})}),await withTimeout(registerV2ToolHooks(ctx,hooks2,directory,state2.registrations),V2_SETUP_TIMEOUT_MS,Error("[opencode-swarm] v2 setup: tool-hook registration exceeded budget")).catch((err)=>{log("v2 tool-hook registration failed (non-fatal)",{error:err instanceof Error?err.message:String(err)})}),await withTimeout(registerV2SessionHooks(ctx,hooks2,directory,state2.registrations),V2_SETUP_TIMEOUT_MS,Error("[opencode-swarm] v2 setup: prompt-hook registration exceeded budget")).catch((err)=>{log("v2 prompt-hook registration failed (non-fatal)",{error:err instanceof Error?err.message:String(err)})});let stopPump=startDeferredEventPump(ctx,hooks2);return state2.pumpStop=stopPump,registerV2AgentTransformSurface(ctx),await withTimeout(deferredV2StartupModelPreflight(directory),V2_SETUP_TIMEOUT_MS,Error("[opencode-swarm] v2: startup model preflight exceeded budget")),state2.disposeV1=typeof hooks2.dispose==="function"?hooks2.dispose:void 0,log("[opencode-swarm] v2 setup complete",{directory,tools:Object.keys(hooks2.tool??{}).length}),async function(){if(typeof state2.pumpStop==="function")state2.pumpStop();clearV2SessionClientState(),clearV2AgentTransformSurface();for(let registration of state2.registrations)try{await withTimeout(registration.dispose(),V2_SETUP_TIMEOUT_MS,Error("[opencode-swarm] v2 cleanup: registration dispose exceeded budget"))}catch(err){log("v2 registration dispose failed (non-fatal)",{error:err instanceof Error?err.message:String(err)})}if(state2.disposeV1)await withTimeout(state2.disposeV1(),V2_SETUP_TIMEOUT_MS,Error("[opencode-swarm] v2 cleanup: v1 dispose exceeded budget")).catch((err)=>{log("v1 dispose during v2 cleanup failed (non-fatal)",{error:err instanceof Error?err.message:String(err)})})}}function seedV1SessionState(sessionID,agentRef,directory){if(typeof sessionID!=="string"||sessionID.length===0)return;let agentName=normalizeV2AgentRef(agentRef);if(agentName===void 0)return sessionID;try{ensureAgentSession(sessionID,agentName,directory)}catch{}return swarmState.activeAgent.set(sessionID,agentName),sessionID}function v2ToolInputSchema(args2){try{if(args2&&typeof args2==="object")return exports_external.toJSONSchema(exports_external.object(args2))}catch{}return{type:"object"}}init_manifest_files();init_p_limit();init_knowledge_curator();init_knowledge_reinforcement();init_knowledge_store();init_knowledge_validator();init_micro_reflector();init_logger();init_timeout();init_candidate_queue();init_provenance();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(entries2,marker){return entries2.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(`
|
|
7434
|
+
`):"";if(isSubagent2){let wrapper=parseV2SubagentWrapper(content);if(wrapper)return{title:"",state:wrapper.state==="running"?"running":wrapper.state==="completed"?"completed":wrapper.state==="error"?"error":"cancelled",output:renderV1TaskEnvelopeFromV2(wrapper),metadata:result?.metadata??{}};if(content.includes("<subagent"))log("v2 subagent wrapper not recognized; passing result text through",{chars:content.length})}return{title:"",state:"completed",output:content,metadata:result?.metadata??{}}}async function onV2Compaction(event,hooks2,directory){let handler=hooks2["experimental.session.compacting"];if(typeof handler!=="function")return;seedV1SessionState(event.sessionID,event.agent,directory);let model=event.model,output={};await withTimeout(Promise.resolve(handler({sessionID:event.sessionID,providerID:typeof model?.providerID==="string"?model.providerID:"unknown",modelID:typeof model?.id==="string"?model.id:"unknown"},output)),V2_HOOK_TIMEOUT_MS,Error("[opencode-swarm] v2: compaction hook exceeded budget")).catch((err)=>{log("v2 compaction hook failed (non-fatal)",{error:err instanceof Error?err.message:String(err)})})}async function onV2Prompt(event,hooks2){let handler=hooks2["chat.message"];if(typeof handler!=="function")return;let text=event.prompt?.text??"",message={id:event.messageID,role:"user",sessionID:event.sessionID},parts=[{type:"text",text}],input={sessionID:event.sessionID,message:{...message},parts:[...parts]},output={message:{...message},parts:[...parts]};if(await withTimeout(Promise.resolve(handler(input,output)),V2_HOOK_TIMEOUT_MS,Error("[opencode-swarm] v2: prompt hook exceeded budget")).catch((err)=>{log("v2 prompt (chat.message) hook failed (non-fatal)",{error:err instanceof Error?err.message:String(err)})}),typeof event.prompt==="object"&&event.prompt!==null){let rewritten=output.parts.find((p)=>p.type==="text"&&typeof p.text==="string");if(rewritten&&typeof rewritten.text==="string"&&rewritten.text!==text)event.prompt.text=rewritten.text}}async function registerV2ToolHooks(ctx,hooks2,directory,registrations){let before=await withTimeout(ctx.tool.hook("execute.before",async(event)=>{return onV2ToolBefore(event,hooks2,directory)}),V2_HOOK_TIMEOUT_MS,Error("[opencode-swarm] v2: execute.before registration exceeded budget"));registrations.push(before);let after=await withTimeout(ctx.tool.hook("execute.after",async(event)=>{return onV2ToolAfter(event,hooks2,directory)}),V2_HOOK_TIMEOUT_MS,Error("[opencode-swarm] v2: execute.after registration exceeded budget"));registrations.push(after)}async function registerV2SessionHooks(ctx,hooks2,directory,registrations){let compaction=await withTimeout(ctx.session.hook("compaction",async(event)=>{return onV2Compaction(event,hooks2,directory)}),V2_HOOK_TIMEOUT_MS,Error("[opencode-swarm] v2: compaction registration exceeded budget"));registrations.push(compaction);let prompt=await withTimeout(ctx.session.hook("prompt",async(event)=>{return onV2Prompt(event,hooks2)}),V2_HOOK_TIMEOUT_MS,Error("[opencode-swarm] v2: prompt registration exceeded budget"));registrations.push(prompt)}init_utils();init_timeout();var V2_TOOL_EXECUTE_TIMEOUT_MS=600000;function synthesizeV1ToolContext(context,projectRoot,permissionBridge){let agentName=normalizeV2AgentRef(context.agent)??"architect";return{sessionID:context.sessionID,messageID:context.messageID,agent:agentName,directory:projectRoot,worktree:projectRoot,abort:context.signal,metadata:(input)=>{try{let progress=context.progress;if(typeof progress==="function")progress({...input.metadata??{},...input.title!==void 0?{title:input.title}:{}})}catch{}},ask:async(input)=>{if(permissionBridge){await withTimeout(Promise.resolve(permissionBridge(input)),V2_TOOL_EXECUTE_TIMEOUT_MS,Error("[opencode-swarm] v2: permission bridge exceeded budget"));return}throw Error("[opencode-swarm] v2: interactive tool permission request unavailable (no permission surface); denying by default.")}}}function mapV1ToolResult(result){if(typeof result==="string")return{content:result};if(result&&typeof result==="object"){let rec=result;return{...typeof rec.output==="string"?{content:rec.output}:{},...rec.metadata&&typeof rec.metadata==="object"?{metadata:rec.metadata}:{}}}return{content:String(result??"")}}async function registerV2Tools(ctx,hooks2,projectRoot,registrations){let toolMap=hooks2.tool??{},permissionBridge=buildPermissionBridge(ctx),registration=await withTimeout(ctx.tool.transform((editor)=>{for(let[name,definition]of Object.entries(toolMap)){let v1Execute=definition.execute;if(typeof v1Execute!=="function")continue;let info={name,description:definition.description??"",input:v2ToolInputSchema(definition.args),execute:async(input,context)=>{seedV1SessionState(context.sessionID,context.agent,projectRoot);let result=await withTimeout(Promise.resolve(v1Execute(input,synthesizeV1ToolContext(context,projectRoot,permissionBridge))),V2_TOOL_EXECUTE_TIMEOUT_MS,Error(`[opencode-swarm] v2: tool ${name} exceeded execution budget`));return mapV1ToolResult(result)}};editor.add(info)}}),V2_TOOL_EXECUTE_TIMEOUT_MS,Error("[opencode-swarm] v2: tool transform exceeded budget"));registrations.push(registration)}function buildPermissionBridge(ctx){let permission=ctx.permission;if(!permission||typeof permission.reply!=="function")return;return async(input)=>{let askInput=input;log("v2 permission bridge invoked (best-effort passthrough)",{permission:typeof askInput?.permission==="string"?askInput.permission:"unknown",patternCount:Array.isArray(askInput?.patterns)?askInput.patterns.length:0}),await withTimeout(Promise.resolve(permission.reply?.(input)),V2_TOOL_EXECUTE_TIMEOUT_MS,Error("[opencode-swarm] v2: permission reply exceeded budget"))}}async function deferredV2StartupModelPreflight(directory){try{let loaded=await withTimeout(loadPluginConfigWithMetaAsync(directory),V2_PREFLIGHT_CONFIG_TIMEOUT_MS,Error("[opencode-swarm] v2: startup preflight config read exceeded budget")),models=collectEnabledAgentModels(loaded?.config).map((entry)=>entry.model).filter((model)=>typeof model==="string"&&model.length>0),quiet=loaded?.config?.quiet===!0;for(let warning of collectModelRosterWarnings(models,VERIFIED_KEYLESS_MODEL_ROSTER))if(addDeferredWarning(warning),!quiet)console.warn(warning)}catch(err){log("v2 startup model preflight failed (non-fatal)",{error:err instanceof Error?err.message:String(err)})}}var V2_SETUP_TIMEOUT_MS=60000,V2_REGISTRATION_TIMEOUT_MS2=3500,V2_PREFLIGHT_CONFIG_TIMEOUT_MS=2000;function createRegistrationSink(){let registrations=[],push=registrations.push.bind(registrations),closed=!1;return registrations.push=(...items)=>{if(!closed)return push(...items);for(let item of items)withTimeout(Promise.resolve().then(()=>item.dispose()),V2_SETUP_TIMEOUT_MS,Error("[opencode-swarm] v2 cleanup: late registration dispose exceeded budget")).catch((err)=>{log("v2 late registration dispose failed (non-fatal)",{error:err instanceof Error?err.message:String(err)})});return registrations.length},{registrations,closeRegistrations:()=>{closed=!0}}}function normalizeV2AgentRef(agent){if(typeof agent==="string")return agent;if(agent&&typeof agent==="object"){let rec=agent;if(typeof rec.id==="string"&&rec.id.length>0)return rec.id;if(typeof rec.name==="string"&&rec.name.length>0)return rec.name}return}async function openCodeSwarmV2Setup(ctx,deps){let rawDirectory=ctx?.location?.directory;if(typeof rawDirectory!=="string"||rawDirectory.length===0)throw Error("[opencode-swarm] v2 setup: host Context carried no location.directory; refusing to start (invariant 4).");let rootDecision=resolveProjectRootDecision(rawDirectory),directory=rootDecision.kind==="redirect"?rootDecision.owningRoot:rootDecision.kind==="root"?rootDecision.directory:rawDirectory,state2=createRegistrationSink(),input={client:createV2SessionClient(ctx),directory,worktree:directory},hooks2=await withTimeout(deps.runInit(input),V2_SETUP_TIMEOUT_MS,Error("[opencode-swarm] v2 setup: initialization exceeded budget")),pendingDomains=new Set,runRegistration=(domain3,register)=>{return pendingDomains.add(domain3),register().catch((err)=>{log(`v2 ${domain3} registration failed (non-fatal)`,{error:err instanceof Error?err.message:String(err)})}).finally(()=>{pendingDomains.delete(domain3)})};await withTimeout(Promise.all([runRegistration("agent/command",()=>registerV2AgentsAndCommands(ctx,hooks2,directory,state2.registrations)),runRegistration("tool",()=>registerV2Tools(ctx,hooks2,directory,state2.registrations)),runRegistration("context-hook",()=>registerV2ContextHook(ctx,hooks2,directory,state2.registrations)),runRegistration("tool-hook",()=>registerV2ToolHooks(ctx,hooks2,directory,state2.registrations)),runRegistration("prompt-hook",()=>registerV2SessionHooks(ctx,hooks2,directory,state2.registrations))]),V2_REGISTRATION_TIMEOUT_MS2,Error("[opencode-swarm] v2 setup: parallel registration exceeded budget")).catch((err)=>{let pending=[...pendingDomains];if(log("v2 registration failed (non-fatal)",{error:err instanceof Error?err.message:String(err),pending}),pending.length>0)addDeferredWarning(`[opencode-swarm] v2 setup: registration still pending after ${V2_REGISTRATION_TIMEOUT_MS2}ms (${pending.join(", ")}); the plugin loaded with partial registration.`)});let stopPump=startDeferredEventPump(ctx,hooks2);return state2.pumpStop=stopPump,registerV2AgentTransformSurface(ctx),await withTimeout(deferredV2StartupModelPreflight(directory),V2_SETUP_TIMEOUT_MS,Error("[opencode-swarm] v2: startup model preflight exceeded budget")),state2.disposeV1=typeof hooks2.dispose==="function"?hooks2.dispose:void 0,log("[opencode-swarm] v2 setup complete",{directory,tools:Object.keys(hooks2.tool??{}).length}),async function(){if(state2.closeRegistrations(),typeof state2.pumpStop==="function")state2.pumpStop();clearV2SessionClientState(),clearV2AgentTransformSurface();for(let registration of state2.registrations)try{await withTimeout(registration.dispose(),V2_SETUP_TIMEOUT_MS,Error("[opencode-swarm] v2 cleanup: registration dispose exceeded budget"))}catch(err){log("v2 registration dispose failed (non-fatal)",{error:err instanceof Error?err.message:String(err)})}if(state2.disposeV1)await withTimeout(state2.disposeV1(),V2_SETUP_TIMEOUT_MS,Error("[opencode-swarm] v2 cleanup: v1 dispose exceeded budget")).catch((err)=>{log("v1 dispose during v2 cleanup failed (non-fatal)",{error:err instanceof Error?err.message:String(err)})})}}function seedV1SessionState(sessionID,agentRef,directory){if(typeof sessionID!=="string"||sessionID.length===0)return;let agentName=normalizeV2AgentRef(agentRef);if(agentName===void 0)return sessionID;try{ensureAgentSession(sessionID,agentName,directory)}catch{}return swarmState.activeAgent.set(sessionID,agentName),sessionID}function v2ToolInputSchema(args2){try{if(args2&&typeof args2==="object")return exports_external.toJSONSchema(exports_external.object(args2))}catch{}return{type:"object"}}init_manifest_files();init_p_limit();init_knowledge_curator();init_knowledge_reinforcement();init_knowledge_store();init_knowledge_validator();init_micro_reflector();init_logger();init_timeout();init_candidate_queue();init_provenance();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(entries2,marker){return entries2.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(`
|
|
7435
7435
|
`).slice(0,SCREENING_PROMPT_CAP)}async function screenCandidate(candidate2,deps){let perCandidateMs=deps.llmTimeoutMs??0;if(!deps.llmDelegate||perCandidateMs<=0||!deps.sessionID)return!0;let llmDelegate=deps.llmDelegate;if(!deps.llmBudget)return!0;let remainingMs2=deps.remainingBudgetMs?.()??Number.POSITIVE_INFINITY,timeoutMs=Math.min(perCandidateMs,Math.max(0,remainingMs2));if(timeoutMs<=0)return!0;if(!reserveLlmBudget(deps.sessionID,SCREENING_TOKEN_ESTIMATE,deps.llmBudget))return!0;return!/\bREJECT\b/i.test(await withTimeoutSignal((signal2)=>llmDelegate("",buildScreeningPrompt(candidate2),signal2),timeoutMs,Error(`Knowledge admission screening timed out after ${timeoutMs}ms`)))}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_provider_pool();init_task_model_routing();init_observability();init_otlp_exporter();init_startup_contract();init_manager();init_prm();init_trajectory_store();init_sweep();init_ephemeral_agent_dispatcher();function createReviewModelDispatcher(client,pricing){return{dispatch:(request)=>dispatchEphemeralAgent({client,directory:request.directory,parentSessionId:request.parentSessionId,agentName:request.agentName,model:request.model,system:request.system,prompt:request.prompt,readOnlyTools:request.tools??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,pricing})}}init_finding_validator();init_runtime3();init_effective_spec();init_compaction_service();init_config_doctor();init_cost_accounting();init_injection_budget();init_model_preflight();init_version_check();init_snapshot_coordination_init();init_snapshot_reader();init_snapshot_store();init_snapshot_writer();init_state();init_telemetry();init_startup_contract();init_zod();init_lifecycle();init_loader();init_ephemeral_agent_dispatcher();init_gate_evidence();init_utils2();init_ledger();init_manager();init_utils3();init_runtime3();init_atomic_write();init_logger();init_model_dispatch_fallback();init_provider_error_classification();init_swarm_artifact_cache();init_config();init_lifecycle();init_next_wave_format();import{createHash as createHash105}from"node:crypto";import*as fs181 from"node:fs";import*as path316 from"node:path";var EPIC_PHASE_REVIEW_FILENAME="epic-phase-review.json",EPIC_PHASE_REVIEW_TTL_MS=86400000,EPIC_PHASE_REVIEW_FORWARD_SKEW_MS=300000,EPIC_PHASE_REVIEW_DISPATCH_TIMEOUT_MS=300000;function resolveEpicPhaseReviewTimeoutMs(directory){try{let configured=resolveEpicConfig(loadPluginConfigWithMeta(directory).config)?.phase_review?.timeout_ms;return typeof configured==="number"?configured:EPIC_PHASE_REVIEW_DISPATCH_TIMEOUT_MS}catch{return EPIC_PHASE_REVIEW_DISPATCH_TIMEOUT_MS}}var EPIC_PHASE_REVIEW_TOOL="epic_phase_review",EPIC_PHASE_REVIEW_BASH_RETRY_NOTE="You have a `bash` tool for this review. Use it only to read and inspect (for example cat, ls, grep, git log, git diff, git show). Never run a command that creates, modifies or deletes files, changes git state (checkout, stash, reset, commit), installs packages, or runs tests.",EPIC_PHASE_REVIEW_BASH_RETRY_TOOLS=Object.freeze(Object.fromEntries(Object.entries(DEFAULT_READ_ONLY_TOOLS).filter(([name])=>name!=="bash"))),MAX_REASON_CHARS=2000;function sha25612(text){return createHash105("sha256").update(text,"utf8").digest("hex")}function taskEvidenceFingerprint(directory,taskId){if(!isValidTaskId(taskId))return"invalid-task-id";try{let bytes=fs181.readFileSync(path316.join(directory,".swarm","evidence",`${taskId}.json`));return createHash105("sha256").update(bytes).digest("hex")}catch(error93){let code=error93.code;return code==="ENOENT"||code==="ENAMETOOLONG"?"missing":"unreadable"}}function currentEpicKey(directory){try{return _internals268.getOpenEpic(directory)?.epicKey??null}catch{return null}}function computeEpicPhaseBinding(directory,plan,phase){let target=plan.phases.find((item)=>item.id===phase);if(!target)return{ok:!1,reason:`phase ${phase} is not in the current plan`};let tasks=[...target.tasks].sort((a,b)=>a.id<b.id?-1:a.id>b.id?1:0),taskIds=tasks.map((task2)=>task2.id);return{ok:!0,incompleteTaskIds:tasks.filter((task2)=>task2.status!=="completed"&&task2.status!=="closed").map((task2)=>task2.id),binding:{epic_key:currentEpicKey(directory),plan_id:derivePlanId(plan),plan_structure_hash:computePlanStructureHash(plan),phase_task_ids:taskIds,phase_tasks_digest:sha25612(JSON.stringify(tasks.map((task2)=>[task2.id,task2.status]))),task_evidence_digest:sha25612(JSON.stringify(taskIds.map((id)=>[id,_internals268.taskEvidenceFingerprint(directory,id)])))}}}function evidencePath(directory,phase){return validateSwarmPath(directory,path316.posix.join("evidence",String(phase),EPIC_PHASE_REVIEW_FILENAME))}var VERDICTS=new Set(["APPROVED","NEEDS_REVISION","REJECTED"]);function isRoleVerdict(value,role){if(!value||typeof value!=="object"||Array.isArray(value))return!1;let v=value;return v.role===role&&typeof v.agent==="string"&&v.agent.length>0&&typeof v.verdict==="string"&&VERDICTS.has(v.verdict)&&(v.reason===null||typeof v.reason==="string")&&(v.dispatch==="completed"||v.dispatch==="unparseable"||v.dispatch==="failed")&&(v.tool_profile===void 0||v.tool_profile==="read-only"||v.tool_profile==="read-only-with-bash")&&typeof v.dispatched_at==="string"}function isBinding(value){if(!value||typeof value!=="object"||Array.isArray(value))return!1;let v=value;return(v.epic_key===void 0||v.epic_key===null||typeof v.epic_key==="string")&&typeof v.plan_id==="string"&&typeof v.plan_structure_hash==="string"&&Array.isArray(v.phase_task_ids)&&v.phase_task_ids.every((id)=>typeof id==="string")&&typeof v.phase_tasks_digest==="string"&&typeof v.task_evidence_digest==="string"}function parseEpicPhaseReviewEvidence(raw){if(!raw||typeof raw!=="object"||Array.isArray(raw))return null;let v=raw;if(v.schema_version!==1||v.kind!=="epic_phase_review"||typeof v.phase!=="number"||!Number.isInteger(v.phase)||typeof v.reviewed_at!=="string"||typeof v.parent_session_id!=="string"||!isBinding(v.binding)||!isRoleVerdict(v.reviewer,"reviewer")||!(v.critic===null||isRoleVerdict(v.critic,"critic")))return null;return raw}function readEpicPhaseReviewEvidence(directory,phase){let text;try{text=fs181.readFileSync(evidencePath(directory,phase),"utf-8")}catch(error93){if(error93.code==="ENOENT")return{status:"missing"};return{status:"invalid",detail:error93 instanceof Error?error93.message:String(error93)}}let parsed;try{parsed=JSON.parse(text)}catch{return{status:"invalid",detail:"evidence is not valid JSON"}}let evidence2=parseEpicPhaseReviewEvidence(parsed);return evidence2?{status:"found",evidence:evidence2}:{status:"invalid",detail:"evidence does not match schema v1"}}function rerunHint(phase){return`Call ${EPIC_PHASE_REVIEW_TOOL}({ phase: ${phase} }) — it dispatches the phase reviewer and then the phase critic and records both verdicts — then retry phase_complete.`}function openEpicWavesForPhase(record3,phase){return record3.waves.filter((wave)=>wave.phase===phase&&wave.status==="issued").map((wave)=>wave.seq)}function describeOpenEpicWaves(directory,phase){let record3;try{record3=_internals268.getOpenEpic(directory)}catch(error93){return`the open epic's record is unreadable (${error93 instanceof Error?error93.message:String(error93)}), so its waves cannot be verified (fail closed). Ask the user to run \`/swarm epic status\`.`}if(!record3)return null;let open11=openEpicWavesForPhase(record3,phase);if(open11.length===0)return null;return`wave ${open11.join(", ")} of phase ${phase} is still open. Call epic_next_wave — it closes a wave once every task in it is resolved — until it returns phase-ready-for-review.`}async function verifyEpicPhaseReadiness(directory,phase,nowMs3){let openWaves=describeOpenEpicWaves(directory,phase);if(openWaves!==null)return{ok:!1,code:"EPIC_PHASE_WAVES_OPEN",reason:`Phase ${phase} cannot complete: ${openWaves}`};let read=_internals268.readEvidence(directory,phase),rel3=`.swarm/evidence/${phase}/${EPIC_PHASE_REVIEW_FILENAME}`;if(read.status==="missing")return{ok:!1,code:"EPIC_PHASE_REVIEW_MISSING",reason:`Epic Mode requires an APPROVED phase reviewer and phase critic before phase ${phase} can complete, but ${rel3} does not exist. ${rerunHint(phase)}`};if(read.status==="invalid")return{ok:!1,code:"EPIC_PHASE_REVIEW_INVALID",reason:`Epic phase review evidence ${rel3} is unreadable or malformed (${read.detail}). Do not edit it by hand. ${rerunHint(phase)}`};let evidence2=read.evidence;if(evidence2.phase!==phase)return{ok:!1,code:"EPIC_PHASE_REVIEW_INVALID",reason:`Epic phase review evidence at ${rel3} records phase ${evidence2.phase}, not phase ${phase}. ${rerunHint(phase)}`};if(evidence2.reviewer.verdict!=="APPROVED")return{ok:!1,code:"EPIC_PHASE_REVIEWER_NOT_APPROVED",reason:`Epic phase reviewer (${evidence2.reviewer.agent}) returned ${evidence2.reviewer.verdict} for phase ${phase}${evidence2.reviewer.reason?`: ${evidence2.reviewer.reason}`:""}. ${epicPhaseFixPath(phase)} Then retry phase_complete.`};if(!evidence2.critic)return{ok:!1,code:"EPIC_PHASE_CRITIC_MISSING",reason:`Epic phase critic verdict is missing for phase ${phase}. ${rerunHint(phase)}`};if(evidence2.critic.verdict!=="APPROVED")return{ok:!1,code:"EPIC_PHASE_CRITIC_NOT_APPROVED",reason:`Epic phase critic (${evidence2.critic.agent}) returned ${evidence2.critic.verdict} for phase ${phase}${evidence2.critic.reason?`: ${evidence2.critic.reason}`:""}. ${epicPhaseFixPath(phase)} Then retry phase_complete.`};let reviewedAtMs=Date.parse(evidence2.reviewed_at);if(!Number.isFinite(reviewedAtMs))return{ok:!1,code:"EPIC_PHASE_REVIEW_INVALID",reason:`Epic phase review evidence for phase ${phase} has an invalid reviewed_at timestamp. ${rerunHint(phase)}`};let age=nowMs3-reviewedAtMs;if(age<-EPIC_PHASE_REVIEW_FORWARD_SKEW_MS)return{ok:!1,code:"EPIC_PHASE_REVIEW_STALE",reason:`Epic phase review evidence for phase ${phase} is future-dated (${evidence2.reviewed_at}); rejected as forged or clock-skewed. ${rerunHint(phase)}`};if(age>EPIC_PHASE_REVIEW_TTL_MS)return{ok:!1,code:"EPIC_PHASE_REVIEW_STALE",reason:`Epic phase review evidence for phase ${phase} is older than 24h. ${rerunHint(phase)}`};let plan;try{plan=await _internals268.loadPlan(directory)}catch{plan=null}if(!plan)return{ok:!1,code:"EPIC_PHASE_PLAN_UNREADABLE",reason:`Cannot verify Epic phase review freshness for phase ${phase}: the plan could not be loaded.`};let current=computeEpicPhaseBinding(directory,plan,phase);if(!current.ok)return{ok:!1,code:"EPIC_PHASE_PLAN_UNREADABLE",reason:`Cannot verify Epic phase review freshness: ${current.reason}.`};let recorded=evidence2.binding,drift=[];if((recorded.epic_key??null)!==current.binding.epic_key)drift.push("epic instance");if(recorded.plan_id!==current.binding.plan_id)drift.push("plan identity");if(recorded.plan_structure_hash!==current.binding.plan_structure_hash)drift.push("plan structure");if(recorded.phase_tasks_digest!==current.binding.phase_tasks_digest)drift.push("phase task set/status");if(recorded.task_evidence_digest!==current.binding.task_evidence_digest)drift.push("task gate evidence (rework after review)");if(drift.length>0)return{ok:!1,code:"EPIC_PHASE_REVIEW_STALE",reason:`Epic phase review evidence for phase ${phase} is stale — ${drift.join(", ")} changed after the review. ${rerunHint(phase)}`};return{ok:!0,evidence:evidence2}}function parseEpicPhaseVerdict(text){let lines=text.split(/\r?\n/),found=[];for(let i=0;i<lines.length;i++){let match=/^\s*(?:\*\*)?VERDICT(?:\*\*)?\s*:\s*(?:\*\*)?\s*(APPROVED|NEEDS_REVISION|REJECTED)\s*(?:\*\*)?\s*$/i.exec(lines[i]);if(match)found.push({verdict:match[1].toUpperCase(),index:i})}if(found.length===0)return null;if(new Set(found.map((item)=>item.verdict)).size>1)return null;let last=found[found.length-1],reason=null;for(let i=last.index+1;i<Math.min(lines.length,last.index+4);i++){let reasonMatch=/^\s*(?:\*\*)?REASON(?:\*\*)?\s*:\s*(.+)$/i.exec(lines[i]);if(reasonMatch){reason=reasonMatch[1].trim().slice(0,MAX_REASON_CHARS);break}}return{verdict:last.verdict,reason}}function buildReviewPackage(directory,plan,phase){let target=plan.phases.find((item)=>item.id===phase),tasks=target?.tasks??[],outcomes={};try{outcomes=_internals268.getOpenEpic(directory)?.tasks??{}}catch(error93){warn(`[epic-phase-readiness] epic record unreadable; reviewing without divergence: ${error93 instanceof Error?error93.message:String(error93)}`)}let filesChanged=new Set,packaged=tasks.map((task2)=>{let outcome=Object.hasOwn(outcomes,task2.id)?outcomes[task2.id]:void 0,divergence=outcome&&outcome.resolution!=="removed"?outcome:void 0,attributed=divergence?.attribution==="session"||divergence?.attribution==="git-single-task";for(let file3 of divergence&&attributed?[...divergence.declared,...divergence.undeclared]:[...divergence?.declared??[],...task2.files_touched])filesChanged.add(file3);return{id:task2.id,status:task2.status,description:task2.description,...task2.acceptance?{acceptance:task2.acceptance}:{},files_touched:[...task2.files_touched],depends:[...task2.depends],...divergence?{divergence:{declared_scope:[...divergence.declared],undeclared:[...divergence.undeclared],attribution:divergence.attribution}}:{}}});return{phase,phase_name:target?.name??`Phase ${phase}`,tasks:packaged,files_changed:[...filesChanged].sort()}}var VERDICT_FOOTER=`Conclude with exactly ONE verdict line followed by a REASON line:
|
|
7436
7436
|
|
|
7437
7437
|
VERDICT: APPROVED
|