opencode-swarm 7.48.0 → 7.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -52,7 +52,7 @@ var package_default;
52
52
  var init_package = __esm(() => {
53
53
  package_default = {
54
54
  name: "opencode-swarm",
55
- version: "7.48.0",
55
+ version: "7.49.0",
56
56
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
57
57
  main: "dist/index.js",
58
58
  types: "dist/index.d.ts",
@@ -16449,94 +16449,561 @@ var init_acknowledge_spec_drift = __esm(() => {
16449
16449
  init_spec_hash();
16450
16450
  });
16451
16451
 
16452
- // src/tools/tool-names.ts
16453
- var TOOL_NAMES, TOOL_NAME_SET;
16454
- var init_tool_names = __esm(() => {
16455
- TOOL_NAMES = [
16456
- "diff",
16457
- "diff_summary",
16458
- "syntax_check",
16459
- "placeholder_scan",
16460
- "imports",
16461
- "lint",
16462
- "secretscan",
16463
- "sast_scan",
16464
- "build_check",
16465
- "pre_check_batch",
16466
- "quality_budget",
16467
- "symbols",
16468
- "complexity_hotspots",
16469
- "schema_drift",
16470
- "todo_extract",
16471
- "evidence_check",
16472
- "check_gate_status",
16473
- "completion_verify",
16474
- "submit_council_verdicts",
16475
- "submit_phase_council_verdicts",
16476
- "declare_council_criteria",
16477
- "sbom_generate",
16478
- "checkpoint",
16479
- "pkg_audit",
16480
- "test_runner",
16481
- "test_impact",
16482
- "mutation_test",
16483
- "generate_mutants",
16484
- "detect_domains",
16485
- "gitingest",
16486
- "retrieve_summary",
16487
- "extract_code_blocks",
16488
- "phase_complete",
16489
- "save_plan",
16490
- "update_task_status",
16491
- "lint_spec",
16492
- "write_retro",
16493
- "write_drift_evidence",
16494
- "write_hallucination_evidence",
16495
- "write_mutation_evidence",
16496
- "declare_scope",
16497
- "knowledge_query",
16498
- "doc_scan",
16499
- "doc_extract",
16500
- "curator_analyze",
16501
- "knowledge_add",
16502
- "knowledge_recall",
16503
- "knowledge_remove",
16504
- "co_change_analyzer",
16505
- "search",
16506
- "batch_symbols",
16507
- "suggest_patch",
16508
- "req_coverage",
16509
- "get_approved_plan",
16510
- "repo_map",
16511
- "get_qa_gate_profile",
16512
- "set_qa_gates",
16513
- "web_search",
16514
- "convene_general_council",
16515
- "write_final_council_evidence",
16516
- "skill_generate",
16517
- "skill_list",
16518
- "skill_apply",
16519
- "skill_inspect",
16520
- "skill_regenerate",
16521
- "skill_retire",
16522
- "skill_improve",
16523
- "spec_write",
16524
- "knowledge_ack",
16525
- "knowledge_receipt",
16526
- "knowledge_archive",
16527
- "swarm_memory_recall",
16528
- "swarm_memory_propose",
16529
- "swarm_command",
16530
- "summarize_work",
16531
- "write_architecture_supervisor_evidence",
16532
- "lean_turbo_plan_lanes",
16533
- "lean_turbo_acquire_locks",
16534
- "lean_turbo_runner_status",
16535
- "lean_turbo_review",
16536
- "lean_turbo_run_phase",
16537
- "lean_turbo_status"
16452
+ // src/config/agent-names.ts
16453
+ var QA_AGENTS, PIPELINE_AGENTS, ORCHESTRATOR_NAME = "architect", ALL_SUBAGENT_NAMES, ALL_AGENT_NAMES;
16454
+ var init_agent_names = __esm(() => {
16455
+ QA_AGENTS = ["reviewer", "critic", "critic_oversight"];
16456
+ PIPELINE_AGENTS = ["explorer", "coder", "test_engineer"];
16457
+ ALL_SUBAGENT_NAMES = [
16458
+ "sme",
16459
+ "docs",
16460
+ "docs_design",
16461
+ "designer",
16462
+ "critic_sounding_board",
16463
+ "critic_drift_verifier",
16464
+ "critic_hallucination_verifier",
16465
+ "critic_architecture_supervisor",
16466
+ "curator_init",
16467
+ "curator_phase",
16468
+ "council_generalist",
16469
+ "council_skeptic",
16470
+ "council_domain_expert",
16471
+ "skill_improver",
16472
+ "spec_writer",
16473
+ ...QA_AGENTS,
16474
+ ...PIPELINE_AGENTS
16538
16475
  ];
16476
+ ALL_AGENT_NAMES = [
16477
+ ORCHESTRATOR_NAME,
16478
+ ...ALL_SUBAGENT_NAMES
16479
+ ];
16480
+ });
16481
+
16482
+ // src/tools/tool-metadata.ts
16483
+ var TOOL_METADATA, TOOL_NAMES, TOOL_NAME_SET, TOOL_DESCRIPTIONS, AGENT_TOOL_MAP;
16484
+ var init_tool_metadata = __esm(() => {
16485
+ init_agent_names();
16486
+ TOOL_METADATA = {
16487
+ diff: {
16488
+ description: "structured git diff with contract change detection",
16489
+ agents: [
16490
+ "architect",
16491
+ "reviewer",
16492
+ "critic_oversight",
16493
+ "coder",
16494
+ "test_engineer"
16495
+ ]
16496
+ },
16497
+ diff_summary: {
16498
+ description: "filter classified AST changes by category, risk level, or file for reviewer drill-down",
16499
+ agents: ["architect", "reviewer", "critic_oversight"]
16500
+ },
16501
+ syntax_check: {
16502
+ description: "syntax validation",
16503
+ agents: ["architect", "coder", "test_engineer"]
16504
+ },
16505
+ placeholder_scan: {
16506
+ description: "todo and FIXME comment detection",
16507
+ agents: ["architect", "reviewer"]
16508
+ },
16509
+ imports: {
16510
+ description: "dependency audit",
16511
+ agents: [
16512
+ "architect",
16513
+ "sme",
16514
+ "docs",
16515
+ "docs_design",
16516
+ "critic_sounding_board",
16517
+ "critic_drift_verifier",
16518
+ "critic_hallucination_verifier",
16519
+ "reviewer",
16520
+ "critic",
16521
+ "critic_oversight",
16522
+ "explorer",
16523
+ "coder",
16524
+ "test_engineer"
16525
+ ]
16526
+ },
16527
+ lint: {
16528
+ description: "code quality",
16529
+ agents: ["architect", "reviewer", "coder"]
16530
+ },
16531
+ secretscan: {
16532
+ description: "secret detection",
16533
+ agents: ["architect", "reviewer", "critic_oversight"]
16534
+ },
16535
+ sast_scan: {
16536
+ description: "static analysis security scan",
16537
+ agents: ["architect", "reviewer", "critic_oversight"]
16538
+ },
16539
+ build_check: {
16540
+ description: "build verification",
16541
+ agents: ["architect", "coder", "test_engineer"]
16542
+ },
16543
+ pre_check_batch: {
16544
+ description: "parallel verification: lint:check + secretscan + sast_scan + quality_budget",
16545
+ agents: ["architect", "reviewer"]
16546
+ },
16547
+ quality_budget: {
16548
+ description: "code quality budget check",
16549
+ agents: ["architect"]
16550
+ },
16551
+ symbols: {
16552
+ description: "code symbol search",
16553
+ agents: [
16554
+ "architect",
16555
+ "sme",
16556
+ "docs",
16557
+ "docs_design",
16558
+ "designer",
16559
+ "critic_sounding_board",
16560
+ "critic_drift_verifier",
16561
+ "critic_hallucination_verifier",
16562
+ "spec_writer",
16563
+ "reviewer",
16564
+ "critic",
16565
+ "critic_oversight",
16566
+ "explorer",
16567
+ "coder",
16568
+ "test_engineer"
16569
+ ]
16570
+ },
16571
+ complexity_hotspots: {
16572
+ description: "git churn \xD7 complexity risk map",
16573
+ agents: [
16574
+ "architect",
16575
+ "sme",
16576
+ "critic_sounding_board",
16577
+ "critic_drift_verifier",
16578
+ "critic_hallucination_verifier",
16579
+ "reviewer",
16580
+ "critic",
16581
+ "critic_oversight",
16582
+ "explorer",
16583
+ "test_engineer"
16584
+ ]
16585
+ },
16586
+ schema_drift: {
16587
+ description: "OpenAPI spec vs route drift",
16588
+ agents: ["architect", "sme", "docs", "explorer"]
16589
+ },
16590
+ todo_extract: {
16591
+ description: "structured TODO/FIXME extraction",
16592
+ agents: ["architect", "docs", "explorer"]
16593
+ },
16594
+ evidence_check: {
16595
+ description: "verify task evidence completeness",
16596
+ agents: ["architect", "critic_oversight"]
16597
+ },
16598
+ check_gate_status: {
16599
+ description: "check the gate status of a specific task",
16600
+ agents: ["architect", "critic_oversight"]
16601
+ },
16602
+ completion_verify: {
16603
+ description: "verify completed tasks have required evidence",
16604
+ agents: ["architect", "critic_oversight"]
16605
+ },
16606
+ submit_council_verdicts: {
16607
+ 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)",
16608
+ agents: ["architect"]
16609
+ },
16610
+ submit_phase_council_verdicts: {
16611
+ 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)",
16612
+ agents: ["architect"]
16613
+ },
16614
+ declare_council_criteria: {
16615
+ description: "pre-declare acceptance criteria for a task before the coder starts work; criteria are read back during council evaluation",
16616
+ agents: ["architect"]
16617
+ },
16618
+ sbom_generate: {
16619
+ description: "SBOM generation for dependency inventory",
16620
+ agents: ["architect"]
16621
+ },
16622
+ checkpoint: {
16623
+ description: "state snapshots",
16624
+ agents: ["architect"]
16625
+ },
16626
+ pkg_audit: {
16627
+ description: "dependency vulnerability scan \u2014 npm/pip/cargo",
16628
+ agents: [
16629
+ "architect",
16630
+ "critic_hallucination_verifier",
16631
+ "reviewer",
16632
+ "critic_oversight",
16633
+ "test_engineer"
16634
+ ]
16635
+ },
16636
+ test_runner: {
16637
+ description: "auto-detect and run tests",
16638
+ agents: ["architect", "reviewer", "test_engineer"]
16639
+ },
16640
+ test_impact: {
16641
+ description: "identify test files impacted by changed source files via import analysis",
16642
+ agents: ["architect", "reviewer", "critic_oversight", "test_engineer"]
16643
+ },
16644
+ mutation_test: {
16645
+ description: "executes pre-generated mutation patches against tests, evaluates kill rate against quality gate thresholds",
16646
+ agents: ["architect", "test_engineer"]
16647
+ },
16648
+ generate_mutants: {
16649
+ description: "generate LLM-based mutation testing patches for source files; returns MutationPatch[] for direct consumption by the mutation_test tool",
16650
+ agents: ["architect"]
16651
+ },
16652
+ detect_domains: {
16653
+ description: "detect which SME domains are relevant for a given text",
16654
+ agents: [
16655
+ "architect",
16656
+ "sme",
16657
+ "docs",
16658
+ "docs_design",
16659
+ "critic_sounding_board",
16660
+ "critic_drift_verifier",
16661
+ "critic_hallucination_verifier",
16662
+ "critic",
16663
+ "critic_oversight",
16664
+ "explorer"
16665
+ ]
16666
+ },
16667
+ gitingest: {
16668
+ description: "fetch a GitHub repository full content via gitingest.com",
16669
+ agents: ["architect", "docs", "explorer"]
16670
+ },
16671
+ retrieve_summary: {
16672
+ description: "retrieve the full content of a stored tool output summary",
16673
+ agents: [
16674
+ "architect",
16675
+ "sme",
16676
+ "docs",
16677
+ "docs_design",
16678
+ "designer",
16679
+ "critic_sounding_board",
16680
+ "critic_drift_verifier",
16681
+ "critic_hallucination_verifier",
16682
+ "critic_architecture_supervisor",
16683
+ "spec_writer",
16684
+ "reviewer",
16685
+ "critic",
16686
+ "critic_oversight",
16687
+ "explorer",
16688
+ "coder",
16689
+ "test_engineer"
16690
+ ]
16691
+ },
16692
+ extract_code_blocks: {
16693
+ description: "extract code blocks from text content and save them to files",
16694
+ agents: [
16695
+ "architect",
16696
+ "sme",
16697
+ "docs",
16698
+ "docs_design",
16699
+ "designer",
16700
+ "spec_writer",
16701
+ "reviewer",
16702
+ "explorer",
16703
+ "coder",
16704
+ "test_engineer"
16705
+ ]
16706
+ },
16707
+ phase_complete: {
16708
+ description: "mark a phase as complete and track dispatched agents",
16709
+ agents: ["architect"]
16710
+ },
16711
+ save_plan: {
16712
+ description: "save a structured implementation plan",
16713
+ agents: ["architect"]
16714
+ },
16715
+ update_task_status: {
16716
+ description: "mark tasks complete, track phase progress",
16717
+ agents: ["architect"]
16718
+ },
16719
+ lint_spec: {
16720
+ description: "validate .swarm/spec.md format and required fields",
16721
+ agents: ["architect", "spec_writer"]
16722
+ },
16723
+ write_retro: {
16724
+ description: "document phase retrospectives via phase_complete workflow, capture lessons learned",
16725
+ agents: ["architect"]
16726
+ },
16727
+ write_drift_evidence: {
16728
+ description: "write drift verification evidence for a completed phase",
16729
+ agents: ["architect"]
16730
+ },
16731
+ write_hallucination_evidence: {
16732
+ description: "write hallucination verification evidence for a completed phase",
16733
+ agents: ["architect"]
16734
+ },
16735
+ write_mutation_evidence: {
16736
+ description: "write mutation gate evidence for a completed phase; normalizes PASS/WARN/FAIL/SKIP verdicts and writes .swarm/evidence/{phase}/mutation-gate.json",
16737
+ agents: ["architect"]
16738
+ },
16739
+ declare_scope: {
16740
+ description: "declare file scope for next coder delegation",
16741
+ agents: ["architect"]
16742
+ },
16743
+ knowledge_query: {
16744
+ description: "query swarm or hive knowledge with optional filters",
16745
+ agents: ["architect", "skill_improver", "spec_writer"]
16746
+ },
16747
+ doc_scan: {
16748
+ description: "scan project documentation files and build an index manifest",
16749
+ agents: [
16750
+ "architect",
16751
+ "docs_design",
16752
+ "skill_improver",
16753
+ "spec_writer",
16754
+ "explorer"
16755
+ ]
16756
+ },
16757
+ doc_extract: {
16758
+ description: "extract actionable constraints from project documentation",
16759
+ agents: ["architect", "docs_design", "skill_improver", "spec_writer"]
16760
+ },
16761
+ curator_analyze: {
16762
+ description: "run curator phase analysis and optionally apply knowledge recommendations",
16763
+ agents: ["architect"]
16764
+ },
16765
+ knowledge_add: {
16766
+ description: "store a new lesson in the knowledge base",
16767
+ agents: ["architect", "coder"]
16768
+ },
16769
+ knowledge_recall: {
16770
+ description: "search the knowledge base for relevant past decisions",
16771
+ agents: [
16772
+ "architect",
16773
+ "sme",
16774
+ "docs",
16775
+ "docs_design",
16776
+ "designer",
16777
+ "critic_sounding_board",
16778
+ "critic_drift_verifier",
16779
+ "critic_hallucination_verifier",
16780
+ "critic_architecture_supervisor",
16781
+ "curator_init",
16782
+ "curator_phase",
16783
+ "skill_improver",
16784
+ "spec_writer",
16785
+ "reviewer",
16786
+ "critic",
16787
+ "critic_oversight",
16788
+ "explorer",
16789
+ "coder",
16790
+ "test_engineer"
16791
+ ]
16792
+ },
16793
+ knowledge_remove: {
16794
+ description: "delete an outdated swarm knowledge entry by ID (swarm tier only)",
16795
+ agents: ["architect"]
16796
+ },
16797
+ co_change_analyzer: {
16798
+ description: "detect hidden couplings by analyzing git history",
16799
+ agents: ["architect"]
16800
+ },
16801
+ search: {
16802
+ 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 \u2014 use symbols and imports tools for structural queries.",
16803
+ agents: [
16804
+ "architect",
16805
+ "sme",
16806
+ "docs",
16807
+ "docs_design",
16808
+ "designer",
16809
+ "critic_hallucination_verifier",
16810
+ "skill_improver",
16811
+ "spec_writer",
16812
+ "reviewer",
16813
+ "critic_oversight",
16814
+ "explorer",
16815
+ "coder",
16816
+ "test_engineer"
16817
+ ]
16818
+ },
16819
+ batch_symbols: {
16820
+ description: "Batched symbol extraction across multiple files. Returns per-file symbol summaries with isolated error handling.",
16821
+ agents: [
16822
+ "architect",
16823
+ "critic_hallucination_verifier",
16824
+ "reviewer",
16825
+ "critic_oversight",
16826
+ "explorer"
16827
+ ]
16828
+ },
16829
+ suggest_patch: {
16830
+ description: "Reviewer-safe structured patch suggestion tool. Produces context-anchored patch artifacts without file modification. Returns structured diagnostics on context mismatch.",
16831
+ agents: ["architect", "reviewer"]
16832
+ },
16833
+ req_coverage: {
16834
+ description: "query requirement coverage status for tracked functional requirements",
16835
+ agents: [
16836
+ "critic_sounding_board",
16837
+ "critic_drift_verifier",
16838
+ "critic_hallucination_verifier",
16839
+ "spec_writer",
16840
+ "critic",
16841
+ "critic_oversight"
16842
+ ]
16843
+ },
16844
+ get_approved_plan: {
16845
+ description: "retrieve the last critic-approved immutable plan snapshot for baseline drift comparison",
16846
+ agents: ["critic_drift_verifier", "critic", "critic_oversight"]
16847
+ },
16848
+ repo_map: {
16849
+ description: "query the repo code graph: importers, dependencies, blast radius, and localization context for structural awareness before refactoring",
16850
+ agents: [
16851
+ "architect",
16852
+ "critic_sounding_board",
16853
+ "critic_drift_verifier",
16854
+ "critic_hallucination_verifier",
16855
+ "critic_architecture_supervisor",
16856
+ "reviewer",
16857
+ "critic",
16858
+ "critic_oversight",
16859
+ "explorer",
16860
+ "coder"
16861
+ ]
16862
+ },
16863
+ get_qa_gate_profile: {
16864
+ description: "retrieve the QA gate profile for the current plan: gates (reviewer, test_engineer, sme_enabled, critic_pre_plan, sast_enabled, council_mode, hallucination_guard, mutation_test, council_general_review, drift_check, final_council), lock state, and profile hash. Read-only.",
16865
+ agents: ["architect"]
16866
+ },
16867
+ set_qa_gates: {
16868
+ description: "configure the QA gate profile for the current plan. Architect-only. Ratchet-tighter only \u2014 rejected once the profile is locked after critic approval. Supports: reviewer, test_engineer, sme_enabled, critic_pre_plan, sast_enabled, council_mode, hallucination_guard, mutation_test, council_general_review, drift_check, final_council.",
16869
+ agents: ["architect"]
16870
+ },
16871
+ web_search: {
16872
+ description: "External web search (Tavily or Brave) for architect-driven council research. Returns titled results with snippets and URLs. Config-gated on council.general.enabled; requires a search API key. Used by the architect in MODE: COUNCIL to gather a RESEARCH CONTEXT before dispatching council agents.",
16873
+ agents: ["architect", "skill_improver"]
16874
+ },
16875
+ convene_general_council: {
16876
+ 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.",
16877
+ agents: ["architect"]
16878
+ },
16879
+ write_final_council_evidence: {
16880
+ description: "write final council evidence for project completion",
16881
+ agents: ["architect"]
16882
+ },
16883
+ skill_generate: {
16884
+ description: "compile knowledge entries into a structured SKILL.md draft",
16885
+ agents: ["architect", "skill_improver"]
16886
+ },
16887
+ skill_list: {
16888
+ description: "list generated skill files and their status",
16889
+ agents: ["architect", "skill_improver"]
16890
+ },
16891
+ skill_apply: {
16892
+ description: "activate a draft skill proposal",
16893
+ agents: ["architect"]
16894
+ },
16895
+ skill_inspect: {
16896
+ description: "inspect the content and source entries of a skill file",
16897
+ agents: ["architect", "skill_improver"]
16898
+ },
16899
+ skill_regenerate: {
16900
+ description: "regenerate an active skill by re-clustering its source knowledge entries and updating the SKILL.md in place",
16901
+ agents: ["architect"]
16902
+ },
16903
+ skill_retire: {
16904
+ description: "retire a generated skill by adding a retired.marker file; retired skills are excluded from scoring and injection",
16905
+ agents: ["architect"]
16906
+ },
16907
+ skill_improve: {
16908
+ description: "run the skill_improver agent to review and refine skills",
16909
+ agents: ["architect", "skill_improver"]
16910
+ },
16911
+ spec_write: {
16912
+ description: "author or update .swarm/spec.md for the current project",
16913
+ agents: ["spec_writer"]
16914
+ },
16915
+ knowledge_ack: {
16916
+ description: "record an explicit KNOWLEDGE_APPLIED/IGNORED/VIOLATED acknowledgment",
16917
+ agents: ["architect"]
16918
+ },
16919
+ knowledge_receipt: {
16920
+ description: "file a receipt for retrieved knowledge (applied/ignored/contradicted + new lessons), recorded as immutable knowledge events",
16921
+ agents: ["architect", "coder"]
16922
+ },
16923
+ knowledge_archive: {
16924
+ description: "archive (default), quarantine, or purge a swarm knowledge entry by ID with an immutable audit tombstone; purge requires an admin flag",
16925
+ agents: ["architect"]
16926
+ },
16927
+ swarm_memory_recall: {
16928
+ description: "recall scoped Swarm memory for the current repository as untrusted background",
16929
+ agents: []
16930
+ },
16931
+ swarm_memory_propose: {
16932
+ description: "create a pending Swarm memory proposal; does not write durable memory directly",
16933
+ agents: []
16934
+ },
16935
+ swarm_command: {
16936
+ description: "run supported /swarm commands through the canonical command registry",
16937
+ agents: [
16938
+ "architect",
16939
+ "sme",
16940
+ "docs",
16941
+ "docs_design",
16942
+ "designer",
16943
+ "reviewer",
16944
+ "critic",
16945
+ "explorer",
16946
+ "coder",
16947
+ "test_engineer"
16948
+ ]
16949
+ },
16950
+ summarize_work: {
16951
+ 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.",
16952
+ agents: [
16953
+ "architect",
16954
+ "sme",
16955
+ "docs",
16956
+ "docs_design",
16957
+ "designer",
16958
+ "explorer",
16959
+ "coder",
16960
+ "test_engineer"
16961
+ ]
16962
+ },
16963
+ write_architecture_supervisor_evidence: {
16964
+ 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)",
16965
+ agents: ["architect"]
16966
+ },
16967
+ lean_turbo_plan_lanes: {
16968
+ description: "partition phase tasks into parallel lanes based on file-scope conflicts for Lean Turbo execution",
16969
+ agents: ["architect"]
16970
+ },
16971
+ lean_turbo_acquire_locks: {
16972
+ description: "acquire file locks for all files in a lane (all-or-nothing) before lane execution",
16973
+ agents: ["architect"]
16974
+ },
16975
+ lean_turbo_runner_status: {
16976
+ description: "read Lean Turbo run state from .swarm/turbo-state.json",
16977
+ agents: ["architect"]
16978
+ },
16979
+ lean_turbo_review: {
16980
+ description: "dispatch a read-only reviewer agent to evaluate a completed Lean Turbo phase",
16981
+ agents: ["architect"]
16982
+ },
16983
+ lean_turbo_run_phase: {
16984
+ 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.",
16985
+ agents: ["architect"]
16986
+ },
16987
+ lean_turbo_status: {
16988
+ description: "returns Lean Turbo configuration and active status for the current session",
16989
+ agents: ["architect"]
16990
+ }
16991
+ };
16992
+ TOOL_NAMES = Object.keys(TOOL_METADATA);
16539
16993
  TOOL_NAME_SET = new Set(TOOL_NAMES);
16994
+ TOOL_DESCRIPTIONS = Object.fromEntries(Object.entries(TOOL_METADATA).map(([name, meta3]) => [
16995
+ name,
16996
+ meta3.description
16997
+ ]));
16998
+ AGENT_TOOL_MAP = (() => {
16999
+ const map2 = Object.fromEntries(ALL_AGENT_NAMES.map((agent) => [agent, []]));
17000
+ for (const [name, meta3] of Object.entries(TOOL_METADATA)) {
17001
+ for (const agent of meta3.agents) {
17002
+ map2[agent].push(name);
17003
+ }
17004
+ }
17005
+ return map2;
17006
+ })();
16540
17007
  });
16541
17008
 
16542
17009
  // src/config/constants.ts
@@ -16573,34 +17040,11 @@ function freezeSet(items) {
16573
17040
  });
16574
17041
  return proxy;
16575
17042
  }
16576
- var QA_AGENTS, PIPELINE_AGENTS, ORCHESTRATOR_NAME = "architect", ALL_SUBAGENT_NAMES, ALL_AGENT_NAMES, OPENCODE_NATIVE_AGENTS, CLAUDE_CODE_NATIVE_COMMANDS, AGENT_TOOL_MAP, TOOL_DESCRIPTIONS, DEFAULT_AGENT_CONFIGS;
17043
+ var OPENCODE_NATIVE_AGENTS, CLAUDE_CODE_NATIVE_COMMANDS, DEFAULT_AGENT_CONFIGS;
16577
17044
  var init_constants = __esm(() => {
16578
- init_tool_names();
16579
- QA_AGENTS = ["reviewer", "critic", "critic_oversight"];
16580
- PIPELINE_AGENTS = ["explorer", "coder", "test_engineer"];
16581
- ALL_SUBAGENT_NAMES = [
16582
- "sme",
16583
- "docs",
16584
- "docs_design",
16585
- "designer",
16586
- "critic_sounding_board",
16587
- "critic_drift_verifier",
16588
- "critic_hallucination_verifier",
16589
- "critic_architecture_supervisor",
16590
- "curator_init",
16591
- "curator_phase",
16592
- "council_generalist",
16593
- "council_skeptic",
16594
- "council_domain_expert",
16595
- "skill_improver",
16596
- "spec_writer",
16597
- ...QA_AGENTS,
16598
- ...PIPELINE_AGENTS
16599
- ];
16600
- ALL_AGENT_NAMES = [
16601
- ORCHESTRATOR_NAME,
16602
- ...ALL_SUBAGENT_NAMES
16603
- ];
17045
+ init_agent_names();
17046
+ init_tool_metadata();
17047
+ init_agent_names();
16604
17048
  OPENCODE_NATIVE_AGENTS = new Set([
16605
17049
  "build",
16606
17050
  "plan",
@@ -16717,405 +17161,6 @@ var init_constants = __esm(() => {
16717
17161
  "team-onboarding",
16718
17162
  "bashes"
16719
17163
  ]);
16720
- AGENT_TOOL_MAP = {
16721
- architect: [
16722
- "checkpoint",
16723
- "check_gate_status",
16724
- "completion_verify",
16725
- "complexity_hotspots",
16726
- "submit_council_verdicts",
16727
- "submit_phase_council_verdicts",
16728
- "declare_council_criteria",
16729
- "detect_domains",
16730
- "evidence_check",
16731
- "extract_code_blocks",
16732
- "gitingest",
16733
- "imports",
16734
- "knowledge_query",
16735
- "lint",
16736
- "diff",
16737
- "diff_summary",
16738
- "pkg_audit",
16739
- "pre_check_batch",
16740
- "quality_budget",
16741
- "retrieve_summary",
16742
- "save_plan",
16743
- "search",
16744
- "batch_symbols",
16745
- "schema_drift",
16746
- "secretscan",
16747
- "symbols",
16748
- "test_runner",
16749
- "test_impact",
16750
- "mutation_test",
16751
- "generate_mutants",
16752
- "write_mutation_evidence",
16753
- "todo_extract",
16754
- "update_task_status",
16755
- "lint_spec",
16756
- "write_retro",
16757
- "write_drift_evidence",
16758
- "write_hallucination_evidence",
16759
- "declare_scope",
16760
- "sast_scan",
16761
- "sbom_generate",
16762
- "build_check",
16763
- "syntax_check",
16764
- "placeholder_scan",
16765
- "phase_complete",
16766
- "doc_scan",
16767
- "doc_extract",
16768
- "curator_analyze",
16769
- "knowledge_add",
16770
- "knowledge_recall",
16771
- "knowledge_remove",
16772
- "knowledge_archive",
16773
- "co_change_analyzer",
16774
- "suggest_patch",
16775
- "repo_map",
16776
- "get_qa_gate_profile",
16777
- "set_qa_gates",
16778
- "convene_general_council",
16779
- "web_search",
16780
- "write_final_council_evidence",
16781
- "skill_generate",
16782
- "skill_list",
16783
- "skill_apply",
16784
- "skill_inspect",
16785
- "skill_regenerate",
16786
- "skill_retire",
16787
- "skill_improve",
16788
- "knowledge_ack",
16789
- "knowledge_receipt",
16790
- "summarize_work",
16791
- "write_architecture_supervisor_evidence",
16792
- "swarm_command",
16793
- "lean_turbo_plan_lanes",
16794
- "lean_turbo_acquire_locks",
16795
- "lean_turbo_runner_status",
16796
- "lean_turbo_review",
16797
- "lean_turbo_run_phase",
16798
- "lean_turbo_status"
16799
- ],
16800
- explorer: [
16801
- "complexity_hotspots",
16802
- "detect_domains",
16803
- "extract_code_blocks",
16804
- "gitingest",
16805
- "imports",
16806
- "retrieve_summary",
16807
- "schema_drift",
16808
- "search",
16809
- "batch_symbols",
16810
- "symbols",
16811
- "todo_extract",
16812
- "doc_scan",
16813
- "knowledge_recall",
16814
- "repo_map",
16815
- "summarize_work",
16816
- "swarm_command"
16817
- ],
16818
- coder: [
16819
- "diff",
16820
- "imports",
16821
- "lint",
16822
- "symbols",
16823
- "extract_code_blocks",
16824
- "retrieve_summary",
16825
- "search",
16826
- "build_check",
16827
- "syntax_check",
16828
- "knowledge_add",
16829
- "knowledge_recall",
16830
- "knowledge_receipt",
16831
- "repo_map",
16832
- "summarize_work",
16833
- "swarm_command"
16834
- ],
16835
- test_engineer: [
16836
- "test_runner",
16837
- "test_impact",
16838
- "mutation_test",
16839
- "diff",
16840
- "symbols",
16841
- "extract_code_blocks",
16842
- "retrieve_summary",
16843
- "imports",
16844
- "complexity_hotspots",
16845
- "pkg_audit",
16846
- "build_check",
16847
- "syntax_check",
16848
- "search",
16849
- "summarize_work",
16850
- "knowledge_recall",
16851
- "swarm_command"
16852
- ],
16853
- sme: [
16854
- "complexity_hotspots",
16855
- "detect_domains",
16856
- "extract_code_blocks",
16857
- "imports",
16858
- "retrieve_summary",
16859
- "schema_drift",
16860
- "search",
16861
- "symbols",
16862
- "knowledge_recall",
16863
- "summarize_work",
16864
- "swarm_command"
16865
- ],
16866
- reviewer: [
16867
- "diff",
16868
- "diff_summary",
16869
- "imports",
16870
- "lint",
16871
- "pkg_audit",
16872
- "pre_check_batch",
16873
- "secretscan",
16874
- "symbols",
16875
- "complexity_hotspots",
16876
- "retrieve_summary",
16877
- "extract_code_blocks",
16878
- "test_runner",
16879
- "test_impact",
16880
- "sast_scan",
16881
- "placeholder_scan",
16882
- "knowledge_recall",
16883
- "search",
16884
- "batch_symbols",
16885
- "suggest_patch",
16886
- "repo_map",
16887
- "swarm_command"
16888
- ],
16889
- critic: [
16890
- "complexity_hotspots",
16891
- "detect_domains",
16892
- "imports",
16893
- "retrieve_summary",
16894
- "symbols",
16895
- "knowledge_recall",
16896
- "req_coverage",
16897
- "get_approved_plan",
16898
- "repo_map",
16899
- "swarm_command"
16900
- ],
16901
- critic_sounding_board: [
16902
- "complexity_hotspots",
16903
- "detect_domains",
16904
- "imports",
16905
- "retrieve_summary",
16906
- "symbols",
16907
- "knowledge_recall",
16908
- "req_coverage",
16909
- "repo_map"
16910
- ],
16911
- critic_drift_verifier: [
16912
- "complexity_hotspots",
16913
- "detect_domains",
16914
- "imports",
16915
- "retrieve_summary",
16916
- "symbols",
16917
- "knowledge_recall",
16918
- "req_coverage",
16919
- "get_approved_plan",
16920
- "repo_map"
16921
- ],
16922
- critic_hallucination_verifier: [
16923
- "complexity_hotspots",
16924
- "detect_domains",
16925
- "imports",
16926
- "retrieve_summary",
16927
- "symbols",
16928
- "batch_symbols",
16929
- "search",
16930
- "pkg_audit",
16931
- "knowledge_recall",
16932
- "req_coverage",
16933
- "repo_map"
16934
- ],
16935
- critic_architecture_supervisor: [
16936
- "retrieve_summary",
16937
- "knowledge_recall",
16938
- "repo_map"
16939
- ],
16940
- critic_oversight: [
16941
- "diff",
16942
- "diff_summary",
16943
- "evidence_check",
16944
- "check_gate_status",
16945
- "completion_verify",
16946
- "get_approved_plan",
16947
- "req_coverage",
16948
- "test_impact",
16949
- "pkg_audit",
16950
- "secretscan",
16951
- "sast_scan",
16952
- "repo_map",
16953
- "retrieve_summary",
16954
- "knowledge_recall",
16955
- "symbols",
16956
- "batch_symbols",
16957
- "search",
16958
- "imports",
16959
- "complexity_hotspots",
16960
- "detect_domains"
16961
- ],
16962
- docs: [
16963
- "detect_domains",
16964
- "extract_code_blocks",
16965
- "gitingest",
16966
- "imports",
16967
- "retrieve_summary",
16968
- "schema_drift",
16969
- "search",
16970
- "symbols",
16971
- "todo_extract",
16972
- "knowledge_recall",
16973
- "summarize_work",
16974
- "swarm_command"
16975
- ],
16976
- docs_design: [
16977
- "detect_domains",
16978
- "extract_code_blocks",
16979
- "imports",
16980
- "retrieve_summary",
16981
- "search",
16982
- "symbols",
16983
- "doc_scan",
16984
- "doc_extract",
16985
- "knowledge_recall",
16986
- "summarize_work",
16987
- "swarm_command"
16988
- ],
16989
- designer: [
16990
- "extract_code_blocks",
16991
- "retrieve_summary",
16992
- "search",
16993
- "symbols",
16994
- "knowledge_recall",
16995
- "summarize_work",
16996
- "swarm_command"
16997
- ],
16998
- curator_init: ["knowledge_recall"],
16999
- curator_phase: ["knowledge_recall"],
17000
- council_generalist: [],
17001
- council_skeptic: [],
17002
- council_domain_expert: [],
17003
- skill_improver: [
17004
- "knowledge_recall",
17005
- "knowledge_query",
17006
- "skill_list",
17007
- "skill_inspect",
17008
- "skill_generate",
17009
- "skill_improve",
17010
- "search",
17011
- "doc_scan",
17012
- "doc_extract",
17013
- "web_search"
17014
- ],
17015
- spec_writer: [
17016
- "search",
17017
- "knowledge_recall",
17018
- "knowledge_query",
17019
- "doc_scan",
17020
- "doc_extract",
17021
- "req_coverage",
17022
- "lint_spec",
17023
- "retrieve_summary",
17024
- "symbols",
17025
- "extract_code_blocks",
17026
- "spec_write"
17027
- ]
17028
- };
17029
- TOOL_DESCRIPTIONS = {
17030
- symbols: "code symbol search",
17031
- checkpoint: "state snapshots",
17032
- diff: "structured git diff with contract change detection",
17033
- diff_summary: "filter classified AST changes by category, risk level, or file for reviewer drill-down",
17034
- imports: "dependency audit",
17035
- lint: "code quality",
17036
- placeholder_scan: "todo and FIXME comment detection",
17037
- secretscan: "secret detection",
17038
- sast_scan: "static analysis security scan",
17039
- syntax_check: "syntax validation",
17040
- test_runner: "auto-detect and run tests",
17041
- test_impact: "identify test files impacted by changed source files via import analysis",
17042
- mutation_test: "executes pre-generated mutation patches against tests, evaluates kill rate against quality gate thresholds",
17043
- generate_mutants: "generate LLM-based mutation testing patches for source files; returns MutationPatch[] for direct consumption by the mutation_test tool",
17044
- write_mutation_evidence: "write mutation gate evidence for a completed phase; normalizes PASS/WARN/FAIL/SKIP verdicts and writes .swarm/evidence/{phase}/mutation-gate.json",
17045
- pkg_audit: "dependency vulnerability scan \u2014 npm/pip/cargo",
17046
- complexity_hotspots: "git churn \xD7 complexity risk map",
17047
- schema_drift: "OpenAPI spec vs route drift",
17048
- todo_extract: "structured TODO/FIXME extraction",
17049
- evidence_check: "verify task evidence completeness",
17050
- sbom_generate: "SBOM generation for dependency inventory",
17051
- build_check: "build verification",
17052
- quality_budget: "code quality budget check",
17053
- pre_check_batch: "parallel verification: lint:check + secretscan + sast_scan + quality_budget",
17054
- update_task_status: "mark tasks complete, track phase progress",
17055
- write_retro: "document phase retrospectives via phase_complete workflow, capture lessons learned",
17056
- write_drift_evidence: "write drift verification evidence for a completed phase",
17057
- write_hallucination_evidence: "write hallucination verification evidence for a completed phase",
17058
- write_final_council_evidence: "write final council evidence for project completion",
17059
- declare_scope: "declare file scope for next coder delegation",
17060
- phase_complete: "mark a phase as complete and track dispatched agents",
17061
- save_plan: "save a structured implementation plan",
17062
- doc_scan: "scan project documentation files and build an index manifest",
17063
- doc_extract: "extract actionable constraints from project documentation",
17064
- curator_analyze: "run curator phase analysis and optionally apply knowledge recommendations",
17065
- knowledge_add: "store a new lesson in the knowledge base",
17066
- knowledge_recall: "search the knowledge base for relevant past decisions",
17067
- knowledge_remove: "delete an outdated swarm knowledge entry by ID (swarm tier only)",
17068
- knowledge_archive: "archive (default), quarantine, or purge a swarm knowledge entry by ID with an immutable audit tombstone; purge requires an admin flag",
17069
- knowledge_query: "query swarm or hive knowledge with optional filters",
17070
- co_change_analyzer: "detect hidden couplings by analyzing git history",
17071
- check_gate_status: "check the gate status of a specific task",
17072
- completion_verify: "verify completed tasks have required evidence",
17073
- submit_council_verdicts: "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)",
17074
- submit_phase_council_verdicts: "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)",
17075
- declare_council_criteria: "pre-declare acceptance criteria for a task before the coder starts work; criteria are read back during council evaluation",
17076
- detect_domains: "detect which SME domains are relevant for a given text",
17077
- summarize_work: "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.",
17078
- write_architecture_supervisor_evidence: "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)",
17079
- extract_code_blocks: "extract code blocks from text content and save them to files",
17080
- gitingest: "fetch a GitHub repository full content via gitingest.com",
17081
- retrieve_summary: "retrieve the full content of a stored tool output summary",
17082
- search: "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 \u2014 use symbols and imports tools for structural queries.",
17083
- web_search: "External web search (Tavily or Brave) for architect-driven council research. Returns titled results with snippets and URLs. Config-gated on council.general.enabled; requires a search API key. Used by the architect in MODE: COUNCIL to gather a RESEARCH CONTEXT before dispatching council agents.",
17084
- convene_general_council: "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.",
17085
- batch_symbols: "Batched symbol extraction across multiple files. Returns per-file symbol summaries with isolated error handling.",
17086
- suggest_patch: "Reviewer-safe structured patch suggestion tool. Produces context-anchored patch artifacts without file modification. Returns structured diagnostics on context mismatch.",
17087
- lint_spec: "validate .swarm/spec.md format and required fields",
17088
- get_approved_plan: "retrieve the last critic-approved immutable plan snapshot for baseline drift comparison",
17089
- repo_map: "query the repo code graph: importers, dependencies, blast radius, and localization context for structural awareness before refactoring",
17090
- get_qa_gate_profile: "retrieve the QA gate profile for the current plan: gates (reviewer, test_engineer, sme_enabled, critic_pre_plan, sast_enabled, council_mode, hallucination_guard, mutation_test, council_general_review, drift_check, final_council), lock state, and profile hash. Read-only.",
17091
- set_qa_gates: "configure the QA gate profile for the current plan. Architect-only. Ratchet-tighter only \u2014 rejected once the profile is locked after critic approval. Supports: reviewer, test_engineer, sme_enabled, critic_pre_plan, sast_enabled, council_mode, hallucination_guard, mutation_test, council_general_review, drift_check, final_council.",
17092
- req_coverage: "query requirement coverage status for tracked functional requirements",
17093
- skill_generate: "compile knowledge entries into a structured SKILL.md draft",
17094
- skill_list: "list generated skill files and their status",
17095
- skill_apply: "activate a draft skill proposal",
17096
- skill_inspect: "inspect the content and source entries of a skill file",
17097
- skill_improve: "run the skill_improver agent to review and refine skills",
17098
- skill_regenerate: "regenerate an active skill by re-clustering its source knowledge entries and updating the SKILL.md in place",
17099
- skill_retire: "retire a generated skill by adding a retired.marker file; retired skills are excluded from scoring and injection",
17100
- spec_write: "author or update .swarm/spec.md for the current project",
17101
- knowledge_ack: "record an explicit KNOWLEDGE_APPLIED/IGNORED/VIOLATED acknowledgment",
17102
- knowledge_receipt: "file a receipt for retrieved knowledge (applied/ignored/contradicted + new lessons), recorded as immutable knowledge events",
17103
- swarm_memory_recall: "recall scoped Swarm memory for the current repository as untrusted background",
17104
- swarm_memory_propose: "create a pending Swarm memory proposal; does not write durable memory directly",
17105
- swarm_command: "run supported /swarm commands through the canonical command registry",
17106
- lean_turbo_plan_lanes: "partition phase tasks into parallel lanes based on file-scope conflicts for Lean Turbo execution",
17107
- lean_turbo_acquire_locks: "acquire file locks for all files in a lane (all-or-nothing) before lane execution",
17108
- lean_turbo_runner_status: "read Lean Turbo run state from .swarm/turbo-state.json",
17109
- lean_turbo_review: "dispatch a read-only reviewer agent to evaluate a completed Lean Turbo phase",
17110
- lean_turbo_run_phase: "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.",
17111
- lean_turbo_status: "returns Lean Turbo configuration and active status for the current session"
17112
- };
17113
- for (const [agentName, tools] of Object.entries(AGENT_TOOL_MAP)) {
17114
- const invalidTools = tools.filter((tool) => !TOOL_NAME_SET.has(tool));
17115
- if (invalidTools.length > 0) {
17116
- throw new Error(`Agent '${agentName}' has invalid tool names: [${invalidTools.join(", ")}]. ` + `All tools must be registered in TOOL_NAME_SET.`);
17117
- }
17118
- }
17119
17164
  DEFAULT_AGENT_CONFIGS = {
17120
17165
  coder: {
17121
17166
  model: "opencode/minimax-m2.5-free",
@@ -43831,24 +43876,14 @@ var init_discovery = __esm(() => {
43831
43876
  });
43832
43877
  });
43833
43878
 
43879
+ // src/tools/tool-names.ts
43880
+ var init_tool_names = __esm(() => {
43881
+ init_tool_metadata();
43882
+ });
43883
+
43834
43884
  // src/services/tool-doctor.ts
43835
- import * as fs11 from "fs";
43836
- import * as path27 from "path";
43837
- function extractRegisteredToolKeys(indexPath) {
43838
- const registeredKeys = new Set;
43839
- try {
43840
- const content = fs11.readFileSync(indexPath, "utf-8");
43841
- const toolBlockMatch = content.match(/tool:\s*\{([^}]+(?:\{[^}]*\}[^}]*)*)\}/s);
43842
- if (!toolBlockMatch) {
43843
- return registeredKeys;
43844
- }
43845
- const toolBlock = toolBlockMatch[1];
43846
- const keyPattern = /^\s*(\w+)(?:\s*:|,)/gm;
43847
- for (const match of toolBlock.matchAll(keyPattern)) {
43848
- registeredKeys.add(match[1]);
43849
- }
43850
- } catch (_error) {}
43851
- return registeredKeys;
43885
+ function getRegisteredToolKeys() {
43886
+ return new Set(TOOL_NAME_SET);
43852
43887
  }
43853
43888
  function checkAgentToolMapAlignment(registeredKeys) {
43854
43889
  const findings = [];
@@ -43858,7 +43893,7 @@ function checkAgentToolMapAlignment(registeredKeys) {
43858
43893
  findings.push({
43859
43894
  id: `agent-tool-map-mismatch-${agentName}-${toolName}`,
43860
43895
  title: "AGENT_TOOL_MAP alignment gap",
43861
- description: `Tool "${toolName}" is assigned to agent "${agentName}" in AGENT_TOOL_MAP but is not registered in the plugin's tool: {} block. The agent will not be able to use this tool.`,
43896
+ description: `Tool "${toolName}" is assigned to agent "${agentName}" in AGENT_TOOL_MAP but is not a registered tool name. The agent will not be able to use this tool.`,
43862
43897
  severity: "error",
43863
43898
  path: `AGENT_TOOL_MAP.${agentName}`,
43864
43899
  currentValue: toolName,
@@ -43886,36 +43921,15 @@ function checkBinaryReadiness() {
43886
43921
  }
43887
43922
  return findings;
43888
43923
  }
43889
- function runToolDoctor(_directory, pluginRoot) {
43924
+ function runToolDoctor(_directory, _pluginRoot) {
43890
43925
  const findings = [];
43891
- const resolvedPluginRoot = pluginRoot ?? path27.resolve(import.meta.dir, "..", "..");
43892
- const indexPath = path27.join(resolvedPluginRoot, "src", "index.ts");
43893
- if (!fs11.existsSync(indexPath)) {
43894
- return {
43895
- findings: [
43896
- {
43897
- id: "plugin-src-unavailable",
43898
- title: "Plugin source not available",
43899
- description: `Tool registration check requires plugin source files. Expected: ${indexPath}. This check is available in development environments; in production npm installs, only compiled dist/ is present.`,
43900
- severity: "warn",
43901
- path: indexPath,
43902
- currentValue: undefined,
43903
- autoFixable: false
43904
- }
43905
- ],
43906
- summary: { info: 0, warn: 1, error: 0 },
43907
- hasAutoFixableIssues: false,
43908
- timestamp: Date.now(),
43909
- configSource: indexPath
43910
- };
43911
- }
43912
- const registeredKeys = extractRegisteredToolKeys(indexPath);
43926
+ const registeredKeys = getRegisteredToolKeys();
43913
43927
  for (const toolName of TOOL_NAMES) {
43914
43928
  if (!registeredKeys.has(toolName)) {
43915
43929
  findings.push({
43916
43930
  id: `missing-tool-registration-${toolName}`,
43917
43931
  title: "Missing tool registration",
43918
- description: `Tool "${toolName}" is defined in TOOL_NAMES but is not registered in the plugin's tool: {} block. This means the tool will not be available at runtime.`,
43932
+ description: `Tool "${toolName}" is defined in TOOL_NAMES but is not present in the plugin tool object derived from TOOL_MANIFEST. This means the tool will not be available at runtime.`,
43919
43933
  severity: "error",
43920
43934
  path: `tool.${toolName}`,
43921
43935
  currentValue: undefined,
@@ -43936,7 +43950,7 @@ function runToolDoctor(_directory, pluginRoot) {
43936
43950
  summary,
43937
43951
  hasAutoFixableIssues,
43938
43952
  timestamp: Date.now(),
43939
- configSource: indexPath
43953
+ configSource: "src/tools/manifest.ts"
43940
43954
  };
43941
43955
  }
43942
43956
  var BINARY_CHECKLIST;
@@ -44646,15 +44660,15 @@ var init_export = __esm(() => {
44646
44660
  });
44647
44661
 
44648
44662
  // src/full-auto/state.ts
44649
- import * as fs12 from "fs";
44650
- import * as path28 from "path";
44663
+ import * as fs11 from "fs";
44664
+ import * as path27 from "path";
44651
44665
  function nowISO() {
44652
44666
  return new Date().toISOString();
44653
44667
  }
44654
44668
  function ensureSwarmDir(directory) {
44655
- const swarmDir = path28.resolve(directory, ".swarm");
44656
- if (!fs12.existsSync(swarmDir)) {
44657
- fs12.mkdirSync(swarmDir, { recursive: true });
44669
+ const swarmDir = path27.resolve(directory, ".swarm");
44670
+ if (!fs11.existsSync(swarmDir)) {
44671
+ fs11.mkdirSync(swarmDir, { recursive: true });
44658
44672
  }
44659
44673
  return swarmDir;
44660
44674
  }
@@ -44686,7 +44700,7 @@ function withStateLock(directory, fn) {
44686
44700
  let release;
44687
44701
  try {
44688
44702
  const lockTarget = validateSwarmPath(directory, STATE_FILE);
44689
- if (!fs12.existsSync(lockTarget)) {
44703
+ if (!fs11.existsSync(lockTarget)) {
44690
44704
  ensureSwarmDir(directory);
44691
44705
  const seed = {
44692
44706
  version: 2,
@@ -44694,7 +44708,7 @@ function withStateLock(directory, fn) {
44694
44708
  oversightSequence: 0,
44695
44709
  sessions: {}
44696
44710
  };
44697
- fs12.writeFileSync(lockTarget, `${JSON.stringify(seed, null, 2)}
44711
+ fs11.writeFileSync(lockTarget, `${JSON.stringify(seed, null, 2)}
44698
44712
  `, "utf-8");
44699
44713
  }
44700
44714
  release = lockfile7.lockSync(lockTarget, {
@@ -44736,11 +44750,11 @@ function clearStateUnreadable() {
44736
44750
  function readPersisted(directory) {
44737
44751
  try {
44738
44752
  const filePath = validateSwarmPath(directory, STATE_FILE);
44739
- if (!fs12.existsSync(filePath)) {
44753
+ if (!fs11.existsSync(filePath)) {
44740
44754
  clearStateUnreadable();
44741
44755
  return emptyPersisted();
44742
44756
  }
44743
- const raw = fs12.readFileSync(filePath, "utf-8");
44757
+ const raw = fs11.readFileSync(filePath, "utf-8");
44744
44758
  const parsed = JSON.parse(raw);
44745
44759
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || parsed.version !== 2 || !parsed.sessions || typeof parsed.sessions !== "object" || Array.isArray(parsed.sessions)) {
44746
44760
  markStateUnreadable(`malformed shape (version=${parsed?.version}, sessions type=${Array.isArray(parsed?.sessions) ? "array" : typeof parsed?.sessions})`);
@@ -44758,8 +44772,8 @@ function readPersisted(directory) {
44758
44772
  error(`[full-auto/state] Failed to read ${STATE_FILE}: ${reason} \u2014 attempting .bak recovery`);
44759
44773
  try {
44760
44774
  const bakPath = validateSwarmPath(directory, `${STATE_FILE}.bak`);
44761
- if (fs12.existsSync(bakPath)) {
44762
- const raw = fs12.readFileSync(bakPath, "utf-8");
44775
+ if (fs11.existsSync(bakPath)) {
44776
+ const raw = fs11.readFileSync(bakPath, "utf-8");
44763
44777
  const parsed = JSON.parse(raw);
44764
44778
  if (parsed?.version === 2 && parsed.sessions && !Array.isArray(parsed.sessions)) {
44765
44779
  warn(`[full-auto/state] Recovered from ${STATE_FILE}.bak`);
@@ -44798,22 +44812,22 @@ function writePersisted(directory, persisted) {
44798
44812
  throw new Error(`Full-Auto state persistence prepare failed: ${msg}`);
44799
44813
  }
44800
44814
  try {
44801
- if (fs12.existsSync(filePath)) {
44802
- fs12.copyFileSync(filePath, bakPath);
44815
+ if (fs11.existsSync(filePath)) {
44816
+ fs11.copyFileSync(filePath, bakPath);
44803
44817
  }
44804
44818
  } catch {}
44805
44819
  try {
44806
- fs12.writeFileSync(tmpPath, payload, "utf-8");
44820
+ fs11.writeFileSync(tmpPath, payload, "utf-8");
44807
44821
  try {
44808
- const fd = fs12.openSync(tmpPath, "r+");
44822
+ const fd = fs11.openSync(tmpPath, "r+");
44809
44823
  try {
44810
- fs12.fsyncSync(fd);
44824
+ fs11.fsyncSync(fd);
44811
44825
  } finally {
44812
- fs12.closeSync(fd);
44826
+ fs11.closeSync(fd);
44813
44827
  }
44814
44828
  } catch {}
44815
- fs12.renameSync(tmpPath, filePath);
44816
- const readback = fs12.readFileSync(filePath, "utf-8");
44829
+ fs11.renameSync(tmpPath, filePath);
44830
+ const readback = fs11.readFileSync(filePath, "utf-8");
44817
44831
  const parsed = JSON.parse(readback);
44818
44832
  if (parsed?.version !== 2) {
44819
44833
  throw new Error("Round-trip readback returned wrong version");
@@ -45353,7 +45367,7 @@ var init_handoff_service = __esm(() => {
45353
45367
 
45354
45368
  // src/session/snapshot-writer.ts
45355
45369
  import { closeSync as closeSync4, fsyncSync as fsyncSync2, mkdirSync as mkdirSync12, openSync as openSync4, renameSync as renameSync8 } from "fs";
45356
- import * as path29 from "path";
45370
+ import * as path28 from "path";
45357
45371
  function serializeAgentSession(s) {
45358
45372
  const gateLog = {};
45359
45373
  const rawGateLog = s.gateLog ?? new Map;
@@ -45453,7 +45467,7 @@ async function writeSnapshot(directory, state) {
45453
45467
  }
45454
45468
  const content = JSON.stringify(snapshot, null, 2);
45455
45469
  const resolvedPath = validateSwarmPath(directory, "session/state.json");
45456
- const dir = path29.dirname(resolvedPath);
45470
+ const dir = path28.dirname(resolvedPath);
45457
45471
  mkdirSync12(dir, { recursive: true });
45458
45472
  const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
45459
45473
  await bunWrite(tempPath, content);
@@ -45913,9 +45927,9 @@ var KNOWLEDGE_SCHEMA_VERSION = 2;
45913
45927
 
45914
45928
  // src/hooks/knowledge-migrator.ts
45915
45929
  import { randomUUID as randomUUID3 } from "crypto";
45916
- import { existsSync as existsSync20, readFileSync as readFileSync14 } from "fs";
45930
+ import { existsSync as existsSync19, readFileSync as readFileSync13 } from "fs";
45917
45931
  import { mkdir as mkdir8, readFile as readFile9, writeFile as writeFile9 } from "fs/promises";
45918
- import * as path30 from "path";
45932
+ import * as path29 from "path";
45919
45933
  async function migrateKnowledgeToExternal(_directory, _config) {
45920
45934
  return {
45921
45935
  migrated: false,
@@ -45926,10 +45940,10 @@ async function migrateKnowledgeToExternal(_directory, _config) {
45926
45940
  };
45927
45941
  }
45928
45942
  async function migrateContextToKnowledge(directory, config3) {
45929
- const sentinelPath = path30.join(directory, ".swarm", ".knowledge-migrated");
45930
- const contextPath = path30.join(directory, ".swarm", "context.md");
45943
+ const sentinelPath = path29.join(directory, ".swarm", ".knowledge-migrated");
45944
+ const contextPath = path29.join(directory, ".swarm", "context.md");
45931
45945
  const knowledgePath = resolveSwarmKnowledgePath(directory);
45932
- if (existsSync20(sentinelPath)) {
45946
+ if (existsSync19(sentinelPath)) {
45933
45947
  return {
45934
45948
  migrated: false,
45935
45949
  entriesMigrated: 0,
@@ -45938,7 +45952,7 @@ async function migrateContextToKnowledge(directory, config3) {
45938
45952
  skippedReason: "sentinel-exists"
45939
45953
  };
45940
45954
  }
45941
- if (!existsSync20(contextPath)) {
45955
+ if (!existsSync19(contextPath)) {
45942
45956
  return {
45943
45957
  migrated: false,
45944
45958
  entriesMigrated: 0,
@@ -46123,16 +46137,16 @@ function truncateLesson(text) {
46123
46137
  return `${text.slice(0, 277)}...`;
46124
46138
  }
46125
46139
  function inferProjectName(directory) {
46126
- const packageJsonPath = path30.join(directory, "package.json");
46127
- if (existsSync20(packageJsonPath)) {
46140
+ const packageJsonPath = path29.join(directory, "package.json");
46141
+ if (existsSync19(packageJsonPath)) {
46128
46142
  try {
46129
- const pkg = JSON.parse(readFileSync14(packageJsonPath, "utf-8"));
46143
+ const pkg = JSON.parse(readFileSync13(packageJsonPath, "utf-8"));
46130
46144
  if (pkg.name && typeof pkg.name === "string") {
46131
46145
  return pkg.name;
46132
46146
  }
46133
46147
  } catch {}
46134
46148
  }
46135
- return path30.basename(directory);
46149
+ return path29.basename(directory);
46136
46150
  }
46137
46151
  async function writeSentinel(sentinelPath, migrated, dropped) {
46138
46152
  const sentinel = {
@@ -46144,7 +46158,7 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
46144
46158
  schema_version: 1,
46145
46159
  migration_tool: "knowledge-migrator.ts"
46146
46160
  };
46147
- await mkdir8(path30.dirname(sentinelPath), { recursive: true });
46161
+ await mkdir8(path29.dirname(sentinelPath), { recursive: true });
46148
46162
  await writeFile9(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
46149
46163
  }
46150
46164
  var _internals19;
@@ -46166,7 +46180,7 @@ var init_knowledge_migrator = __esm(() => {
46166
46180
  });
46167
46181
 
46168
46182
  // src/commands/knowledge.ts
46169
- import { join as join28 } from "path";
46183
+ import { join as join27 } from "path";
46170
46184
  function resolveEntryByPrefix(entries, inputId) {
46171
46185
  const exact = entries.find((e) => e.id === inputId);
46172
46186
  if (exact)
@@ -46217,7 +46231,7 @@ async function handleKnowledgeRestoreCommand(directory, args) {
46217
46231
  return "Invalid entry ID. IDs must be 1-64 characters: letters, digits, hyphens, underscores only.";
46218
46232
  }
46219
46233
  try {
46220
- const quarantinePath = join28(directory, ".swarm", "knowledge-quarantined.jsonl");
46234
+ const quarantinePath = join27(directory, ".swarm", "knowledge-quarantined.jsonl");
46221
46235
  const entries = await readKnowledge(quarantinePath);
46222
46236
  const resolved = resolveEntryByPrefix(entries, inputId);
46223
46237
  if ("error" in resolved) {
@@ -47192,7 +47206,7 @@ var init_scoring = __esm(() => {
47192
47206
 
47193
47207
  // src/memory/local-jsonl-provider.ts
47194
47208
  import { randomUUID as randomUUID4 } from "crypto";
47195
- import { existsSync as existsSync21 } from "fs";
47209
+ import { existsSync as existsSync20 } from "fs";
47196
47210
  import {
47197
47211
  appendFile as appendFile5,
47198
47212
  mkdir as mkdir9,
@@ -47200,7 +47214,7 @@ import {
47200
47214
  rename as rename6,
47201
47215
  writeFile as writeFile10
47202
47216
  } from "fs/promises";
47203
- import * as path31 from "path";
47217
+ import * as path30 from "path";
47204
47218
 
47205
47219
  class LocalJsonlMemoryProvider {
47206
47220
  name = "local-jsonl";
@@ -47216,7 +47230,7 @@ class LocalJsonlMemoryProvider {
47216
47230
  pathFor(file3) {
47217
47231
  const storageDir = this.config.storageDir.replace(/^\.swarm[/\\]?/, "");
47218
47232
  const filename = file3 === "memories" ? "memories.jsonl" : file3 === "proposals" ? "proposals.jsonl" : "audit.jsonl";
47219
- return validateSwarmPath(this.rootDirectory, path31.join(storageDir, filename));
47233
+ return validateSwarmPath(this.rootDirectory, path30.join(storageDir, filename));
47220
47234
  }
47221
47235
  async initialize() {
47222
47236
  if (this.initialized)
@@ -47543,7 +47557,7 @@ function validateLoadedProposals(values, config3) {
47543
47557
  return { records, invalidCount };
47544
47558
  }
47545
47559
  async function readJsonl(filePath) {
47546
- if (!existsSync21(filePath))
47560
+ if (!existsSync20(filePath))
47547
47561
  return [];
47548
47562
  const content = await readFile10(filePath, "utf-8");
47549
47563
  const records = [];
@@ -47599,12 +47613,12 @@ function parseRecallUsageEvent(event) {
47599
47613
  }
47600
47614
  }
47601
47615
  async function appendJsonl(filePath, value) {
47602
- await mkdir9(path31.dirname(filePath), { recursive: true });
47616
+ await mkdir9(path30.dirname(filePath), { recursive: true });
47603
47617
  await appendFile5(filePath, `${JSON.stringify(value)}
47604
47618
  `, "utf-8");
47605
47619
  }
47606
47620
  async function writeJsonlAtomic(filePath, values) {
47607
- await mkdir9(path31.dirname(filePath), { recursive: true });
47621
+ await mkdir9(path30.dirname(filePath), { recursive: true });
47608
47622
  const tmp = `${filePath}.tmp.${randomUUID4()}`;
47609
47623
  const content = values.map((value) => JSON.stringify(value)).join(`
47610
47624
  `) + (values.length > 0 ? `
@@ -47629,9 +47643,9 @@ var init_prompt_block = __esm(() => {
47629
47643
  });
47630
47644
 
47631
47645
  // src/memory/jsonl-migration.ts
47632
- import { existsSync as existsSync22 } from "fs";
47646
+ import { existsSync as existsSync21 } from "fs";
47633
47647
  import { copyFile, mkdir as mkdir10, readFile as readFile11, stat as stat3, writeFile as writeFile11 } from "fs/promises";
47634
- import * as path32 from "path";
47648
+ import * as path31 from "path";
47635
47649
  function resolveMemoryStorageDir(rootDirectory, config3 = {}) {
47636
47650
  const resolved = resolveConfig(config3);
47637
47651
  const storageDir = resolved.storageDir.replace(/^\.swarm[/\\]?/, "");
@@ -47645,8 +47659,8 @@ function resolveSqliteDatabasePath(rootDirectory, config3 = {}) {
47645
47659
  async function readLegacyJsonl(rootDirectory, config3 = {}) {
47646
47660
  const resolved = resolveConfig(config3);
47647
47661
  const storageDir = resolveMemoryStorageDir(rootDirectory, resolved);
47648
- const memoryLoad = await readMemoryJsonl(path32.join(storageDir, "memories.jsonl"), resolved);
47649
- const proposalLoad = await readProposalJsonl(path32.join(storageDir, "proposals.jsonl"), resolved);
47662
+ const memoryLoad = await readMemoryJsonl(path31.join(storageDir, "memories.jsonl"), resolved);
47663
+ const proposalLoad = await readProposalJsonl(path31.join(storageDir, "proposals.jsonl"), resolved);
47650
47664
  return {
47651
47665
  memories: memoryLoad.records,
47652
47666
  proposals: proposalLoad.records,
@@ -47656,15 +47670,15 @@ async function readLegacyJsonl(rootDirectory, config3 = {}) {
47656
47670
  }
47657
47671
  async function backupLegacyJsonl(rootDirectory, config3 = {}) {
47658
47672
  const storageDir = resolveMemoryStorageDir(rootDirectory, config3);
47659
- const backupDir = path32.join(storageDir, "backups");
47673
+ const backupDir = path31.join(storageDir, "backups");
47660
47674
  await mkdir10(backupDir, { recursive: true });
47661
47675
  const results = [];
47662
47676
  for (const filename of ["memories.jsonl", "proposals.jsonl"]) {
47663
- const source = path32.join(storageDir, filename);
47664
- if (!existsSync22(source))
47677
+ const source = path31.join(storageDir, filename);
47678
+ if (!existsSync21(source))
47665
47679
  continue;
47666
- const backup = path32.join(backupDir, `${filename}.pre-sqlite-migration`);
47667
- if (existsSync22(backup)) {
47680
+ const backup = path31.join(backupDir, `${filename}.pre-sqlite-migration`);
47681
+ if (existsSync21(backup)) {
47668
47682
  results.push({ source, backup, created: false });
47669
47683
  continue;
47670
47684
  }
@@ -47674,24 +47688,24 @@ async function backupLegacyJsonl(rootDirectory, config3 = {}) {
47674
47688
  return results;
47675
47689
  }
47676
47690
  async function writeJsonlExport(rootDirectory, config3, memories, proposals) {
47677
- const exportDir = path32.join(resolveMemoryStorageDir(rootDirectory, config3), "export");
47691
+ const exportDir = path31.join(resolveMemoryStorageDir(rootDirectory, config3), "export");
47678
47692
  await mkdir10(exportDir, { recursive: true });
47679
- const memoriesPath = path32.join(exportDir, "memories.jsonl");
47680
- const proposalsPath = path32.join(exportDir, "proposals.jsonl");
47693
+ const memoriesPath = path31.join(exportDir, "memories.jsonl");
47694
+ const proposalsPath = path31.join(exportDir, "proposals.jsonl");
47681
47695
  await writeFile11(memoriesPath, toJsonl(memories), "utf-8");
47682
47696
  await writeFile11(proposalsPath, toJsonl(proposals), "utf-8");
47683
47697
  return { directory: exportDir, memoriesPath, proposalsPath };
47684
47698
  }
47685
47699
  async function writeMigrationReport(rootDirectory, report, config3 = {}) {
47686
- const reportPath = path32.join(resolveMemoryStorageDir(rootDirectory, config3), "migration-report.json");
47687
- await mkdir10(path32.dirname(reportPath), { recursive: true });
47700
+ const reportPath = path31.join(resolveMemoryStorageDir(rootDirectory, config3), "migration-report.json");
47701
+ await mkdir10(path31.dirname(reportPath), { recursive: true });
47688
47702
  await writeFile11(reportPath, `${JSON.stringify(report, null, 2)}
47689
47703
  `, "utf-8");
47690
47704
  return reportPath;
47691
47705
  }
47692
47706
  async function readMigrationReport(rootDirectory, config3 = {}) {
47693
- const reportPath = path32.join(resolveMemoryStorageDir(rootDirectory, config3), "migration-report.json");
47694
- if (!existsSync22(reportPath))
47707
+ const reportPath = path31.join(resolveMemoryStorageDir(rootDirectory, config3), "migration-report.json");
47708
+ if (!existsSync21(reportPath))
47695
47709
  return null;
47696
47710
  try {
47697
47711
  return JSON.parse(await readFile11(reportPath, "utf-8"));
@@ -47703,15 +47717,15 @@ async function getLegacyJsonlFileStatus(rootDirectory, config3 = {}) {
47703
47717
  const storageDir = resolveMemoryStorageDir(rootDirectory, config3);
47704
47718
  const statuses = [];
47705
47719
  for (const file3 of ["memories.jsonl", "proposals.jsonl"]) {
47706
- const filePath = path32.join(storageDir, file3);
47720
+ const filePath = path31.join(storageDir, file3);
47707
47721
  let sizeBytes = 0;
47708
- if (existsSync22(filePath)) {
47722
+ if (existsSync21(filePath)) {
47709
47723
  sizeBytes = (await stat3(filePath)).size;
47710
47724
  }
47711
47725
  statuses.push({
47712
47726
  file: file3,
47713
47727
  path: filePath,
47714
- exists: existsSync22(filePath),
47728
+ exists: existsSync21(filePath),
47715
47729
  sizeBytes
47716
47730
  });
47717
47731
  }
@@ -47792,7 +47806,7 @@ async function readProposalJsonl(filePath, config3) {
47792
47806
  return { records, invalidRows, totalRows: rows.totalRows };
47793
47807
  }
47794
47808
  async function readJsonlRows(filePath) {
47795
- if (!existsSync22(filePath)) {
47809
+ if (!existsSync21(filePath)) {
47796
47810
  return { rows: [], invalidRows: [], totalRows: 0 };
47797
47811
  }
47798
47812
  const content = await readFile11(filePath, "utf-8");
@@ -47832,7 +47846,7 @@ var init_jsonl_migration = __esm(() => {
47832
47846
  import { randomUUID as randomUUID5 } from "crypto";
47833
47847
  import { mkdirSync as mkdirSync13 } from "fs";
47834
47848
  import { createRequire as createRequire2 } from "module";
47835
- import * as path33 from "path";
47849
+ import * as path32 from "path";
47836
47850
  function loadDatabaseCtor2() {
47837
47851
  if (_DatabaseCtor2)
47838
47852
  return _DatabaseCtor2;
@@ -47890,7 +47904,7 @@ class SQLiteMemoryProvider {
47890
47904
  if (this.initialized)
47891
47905
  return;
47892
47906
  const dbPath = this.databasePath();
47893
- mkdirSync13(path33.dirname(dbPath), { recursive: true });
47907
+ mkdirSync13(path32.dirname(dbPath), { recursive: true });
47894
47908
  const Db = loadDatabaseCtor2();
47895
47909
  this.db = new Db(dbPath);
47896
47910
  this.db.run("PRAGMA journal_mode = WAL;");
@@ -48774,11 +48788,11 @@ var init_gateway = __esm(() => {
48774
48788
  });
48775
48789
 
48776
48790
  // src/memory/evaluation.ts
48777
- import * as fs13 from "fs/promises";
48791
+ import * as fs12 from "fs/promises";
48778
48792
  import * as os7 from "os";
48779
- import * as path34 from "path";
48793
+ import * as path33 from "path";
48780
48794
  async function evaluateMemoryRecallFixtures(options) {
48781
- const fixtureDirectory = path34.resolve(options.fixtureDirectory);
48795
+ const fixtureDirectory = path33.resolve(options.fixtureDirectory);
48782
48796
  const providers = options.providers ?? DEFAULT_PROVIDERS;
48783
48797
  const modes = options.modes ?? DEFAULT_MODES;
48784
48798
  const generatedAt = new Date().toISOString();
@@ -48787,7 +48801,7 @@ async function evaluateMemoryRecallFixtures(options) {
48787
48801
  for (const fixture of fixtures) {
48788
48802
  const materialized = materializeFixture(fixture);
48789
48803
  for (const providerName of providers) {
48790
- const tempRoot = await fs13.realpath(await fs13.mkdtemp(path34.join(os7.tmpdir(), "swarm-memory-eval-")));
48804
+ const tempRoot = await fs12.realpath(await fs12.mkdtemp(path33.join(os7.tmpdir(), "swarm-memory-eval-")));
48791
48805
  const provider = createEvaluationProvider(providerName, tempRoot);
48792
48806
  try {
48793
48807
  await provider.initialize?.();
@@ -48811,7 +48825,7 @@ async function evaluateMemoryRecallFixtures(options) {
48811
48825
  } finally {
48812
48826
  await provider.close?.();
48813
48827
  if (!options.keepTempRoots) {
48814
- await fs13.rm(tempRoot, { recursive: true, force: true });
48828
+ await fs12.rm(tempRoot, { recursive: true, force: true });
48815
48829
  }
48816
48830
  }
48817
48831
  }
@@ -48827,11 +48841,11 @@ async function evaluateMemoryRecallFixtures(options) {
48827
48841
  };
48828
48842
  }
48829
48843
  async function loadRecallEvaluationFixtures(fixtureDirectory) {
48830
- const entries = await fs13.readdir(fixtureDirectory, { withFileTypes: true });
48844
+ const entries = await fs12.readdir(fixtureDirectory, { withFileTypes: true });
48831
48845
  const files = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort((a, b) => a.localeCompare(b));
48832
48846
  const fixtures = [];
48833
48847
  for (const file3 of files) {
48834
- const raw = await fs13.readFile(path34.join(fixtureDirectory, file3), "utf-8");
48848
+ const raw = await fs12.readFile(path33.join(fixtureDirectory, file3), "utf-8");
48835
48849
  fixtures.push(validateFixture(JSON.parse(raw), file3));
48836
48850
  }
48837
48851
  return fixtures;
@@ -49169,8 +49183,8 @@ var init_memory = __esm(() => {
49169
49183
  });
49170
49184
 
49171
49185
  // src/commands/memory.ts
49172
- import { existsSync as existsSync23 } from "fs";
49173
- import * as path35 from "path";
49186
+ import { existsSync as existsSync22 } from "fs";
49187
+ import * as path34 from "path";
49174
49188
  import { fileURLToPath as fileURLToPath2 } from "url";
49175
49189
  async function handleMemoryCommand(_directory, _args) {
49176
49190
  return [
@@ -49201,7 +49215,7 @@ async function handleMemoryStatusCommand(directory, _args) {
49201
49215
  `- Provider: \`${config3.provider}\``,
49202
49216
  `- Storage: \`${storageDir}\``,
49203
49217
  `- SQLite path: \`${sqlitePath}\``,
49204
- `- SQLite database exists: \`${existsSync23(sqlitePath)}\``,
49218
+ `- SQLite database exists: \`${existsSync22(sqlitePath)}\``,
49205
49219
  `- Automatic destructive cleanup: \`disabled\``,
49206
49220
  "",
49207
49221
  "### Legacy JSONL"
@@ -49440,7 +49454,7 @@ function resolveCommandMemoryConfig(directory) {
49440
49454
  }
49441
49455
  function parseEvaluateArgs(directory, args) {
49442
49456
  let json3 = false;
49443
- let fixtureDirectory = path35.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall");
49457
+ let fixtureDirectory = path34.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall");
49444
49458
  for (let i = 0;i < args.length; i++) {
49445
49459
  const arg = args[i];
49446
49460
  if (arg === "--json") {
@@ -49454,7 +49468,7 @@ function parseEvaluateArgs(directory, args) {
49454
49468
  error: "Usage: /swarm memory evaluate [--json] [--fixtures <directory>]"
49455
49469
  };
49456
49470
  }
49457
- fixtureDirectory = path35.resolve(directory, next);
49471
+ fixtureDirectory = path34.resolve(directory, next);
49458
49472
  i++;
49459
49473
  continue;
49460
49474
  }
@@ -49487,15 +49501,15 @@ function parseMaintenanceArgs(args, options) {
49487
49501
  return { limit, confirm };
49488
49502
  }
49489
49503
  function resolvePackageRootFromModule(modulePath) {
49490
- const moduleDir = path35.dirname(modulePath);
49491
- const leaf = path35.basename(moduleDir);
49504
+ const moduleDir = path34.dirname(modulePath);
49505
+ const leaf = path34.basename(moduleDir);
49492
49506
  if (leaf === "commands" || leaf === "cli") {
49493
- return path35.resolve(moduleDir, "..", "..");
49507
+ return path34.resolve(moduleDir, "..", "..");
49494
49508
  }
49495
49509
  if (leaf === "dist") {
49496
- return path35.resolve(moduleDir, "..");
49510
+ return path34.resolve(moduleDir, "..");
49497
49511
  }
49498
- return path35.resolve(moduleDir, "..");
49512
+ return path34.resolve(moduleDir, "..");
49499
49513
  }
49500
49514
  function formatMigrationResult(label, report) {
49501
49515
  if (!report) {
@@ -49614,7 +49628,7 @@ var PACKAGE_ROOT;
49614
49628
  var init_memory2 = __esm(() => {
49615
49629
  init_loader();
49616
49630
  init_memory();
49617
- PACKAGE_ROOT = path35.resolve(resolvePackageRootFromModule(fileURLToPath2(import.meta.url)));
49631
+ PACKAGE_ROOT = path34.resolve(resolvePackageRootFromModule(fileURLToPath2(import.meta.url)));
49618
49632
  });
49619
49633
 
49620
49634
  // src/services/plan-service.ts
@@ -50001,8 +50015,8 @@ function containsControlChars(str) {
50001
50015
  var init_path_security = () => {};
50002
50016
 
50003
50017
  // src/tools/lint.ts
50004
- import * as fs14 from "fs";
50005
- import * as path36 from "path";
50018
+ import * as fs13 from "fs";
50019
+ import * as path35 from "path";
50006
50020
  function validateArgs(args) {
50007
50021
  if (typeof args !== "object" || args === null)
50008
50022
  return false;
@@ -50013,9 +50027,9 @@ function validateArgs(args) {
50013
50027
  }
50014
50028
  function getLinterCommand(linter, mode, projectDir) {
50015
50029
  const isWindows = process.platform === "win32";
50016
- const binDir = path36.join(projectDir, "node_modules", ".bin");
50017
- const biomeBin = isWindows ? path36.join(binDir, "biome.EXE") : path36.join(binDir, "biome");
50018
- const eslintBin = isWindows ? path36.join(binDir, "eslint.cmd") : path36.join(binDir, "eslint");
50030
+ const binDir = path35.join(projectDir, "node_modules", ".bin");
50031
+ const biomeBin = isWindows ? path35.join(binDir, "biome.EXE") : path35.join(binDir, "biome");
50032
+ const eslintBin = isWindows ? path35.join(binDir, "eslint.cmd") : path35.join(binDir, "eslint");
50019
50033
  switch (linter) {
50020
50034
  case "biome":
50021
50035
  if (mode === "fix") {
@@ -50031,7 +50045,7 @@ function getLinterCommand(linter, mode, projectDir) {
50031
50045
  }
50032
50046
  function getAdditionalLinterCommand(linter, mode, cwd) {
50033
50047
  const gradlewName = process.platform === "win32" ? "gradlew.bat" : "gradlew";
50034
- const gradlew = fs14.existsSync(path36.join(cwd, gradlewName)) ? path36.join(cwd, gradlewName) : null;
50048
+ const gradlew = fs13.existsSync(path35.join(cwd, gradlewName)) ? path35.join(cwd, gradlewName) : null;
50035
50049
  switch (linter) {
50036
50050
  case "ruff":
50037
50051
  return mode === "fix" ? ["ruff", "check", "--fix", "."] : ["ruff", "check", "."];
@@ -50065,12 +50079,12 @@ function getAdditionalLinterCommand(linter, mode, cwd) {
50065
50079
  }
50066
50080
  }
50067
50081
  function detectRuff(cwd) {
50068
- if (fs14.existsSync(path36.join(cwd, "ruff.toml")))
50082
+ if (fs13.existsSync(path35.join(cwd, "ruff.toml")))
50069
50083
  return isCommandAvailable("ruff");
50070
50084
  try {
50071
- const pyproject = path36.join(cwd, "pyproject.toml");
50072
- if (fs14.existsSync(pyproject)) {
50073
- const content = fs14.readFileSync(pyproject, "utf-8");
50085
+ const pyproject = path35.join(cwd, "pyproject.toml");
50086
+ if (fs13.existsSync(pyproject)) {
50087
+ const content = fs13.readFileSync(pyproject, "utf-8");
50074
50088
  if (content.includes("[tool.ruff]"))
50075
50089
  return isCommandAvailable("ruff");
50076
50090
  }
@@ -50078,21 +50092,21 @@ function detectRuff(cwd) {
50078
50092
  return false;
50079
50093
  }
50080
50094
  function detectClippy(cwd) {
50081
- return fs14.existsSync(path36.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
50095
+ return fs13.existsSync(path35.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
50082
50096
  }
50083
50097
  function detectGolangciLint(cwd) {
50084
- return fs14.existsSync(path36.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
50098
+ return fs13.existsSync(path35.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
50085
50099
  }
50086
50100
  function detectCheckstyle(cwd) {
50087
- const hasMaven = fs14.existsSync(path36.join(cwd, "pom.xml"));
50088
- const hasGradle = fs14.existsSync(path36.join(cwd, "build.gradle")) || fs14.existsSync(path36.join(cwd, "build.gradle.kts"));
50089
- const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs14.existsSync(path36.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
50101
+ const hasMaven = fs13.existsSync(path35.join(cwd, "pom.xml"));
50102
+ const hasGradle = fs13.existsSync(path35.join(cwd, "build.gradle")) || fs13.existsSync(path35.join(cwd, "build.gradle.kts"));
50103
+ const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs13.existsSync(path35.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
50090
50104
  return (hasMaven || hasGradle) && hasBinary;
50091
50105
  }
50092
50106
  function detectKtlint(cwd) {
50093
- const hasKotlin = fs14.existsSync(path36.join(cwd, "build.gradle.kts")) || fs14.existsSync(path36.join(cwd, "build.gradle")) || (() => {
50107
+ const hasKotlin = fs13.existsSync(path35.join(cwd, "build.gradle.kts")) || fs13.existsSync(path35.join(cwd, "build.gradle")) || (() => {
50094
50108
  try {
50095
- return fs14.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
50109
+ return fs13.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
50096
50110
  } catch {
50097
50111
  return false;
50098
50112
  }
@@ -50101,7 +50115,7 @@ function detectKtlint(cwd) {
50101
50115
  }
50102
50116
  function detectDotnetFormat(cwd) {
50103
50117
  try {
50104
- const files = fs14.readdirSync(cwd);
50118
+ const files = fs13.readdirSync(cwd);
50105
50119
  const hasCsproj = files.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"));
50106
50120
  return hasCsproj && isCommandAvailable("dotnet");
50107
50121
  } catch {
@@ -50109,14 +50123,14 @@ function detectDotnetFormat(cwd) {
50109
50123
  }
50110
50124
  }
50111
50125
  function detectCppcheck(cwd) {
50112
- if (fs14.existsSync(path36.join(cwd, "CMakeLists.txt"))) {
50126
+ if (fs13.existsSync(path35.join(cwd, "CMakeLists.txt"))) {
50113
50127
  return isCommandAvailable("cppcheck");
50114
50128
  }
50115
50129
  try {
50116
- const dirsToCheck = [cwd, path36.join(cwd, "src")];
50130
+ const dirsToCheck = [cwd, path35.join(cwd, "src")];
50117
50131
  const hasCpp = dirsToCheck.some((dir) => {
50118
50132
  try {
50119
- return fs14.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
50133
+ return fs13.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
50120
50134
  } catch {
50121
50135
  return false;
50122
50136
  }
@@ -50127,13 +50141,13 @@ function detectCppcheck(cwd) {
50127
50141
  }
50128
50142
  }
50129
50143
  function detectSwiftlint(cwd) {
50130
- return fs14.existsSync(path36.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
50144
+ return fs13.existsSync(path35.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
50131
50145
  }
50132
50146
  function detectDartAnalyze(cwd) {
50133
- return fs14.existsSync(path36.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
50147
+ return fs13.existsSync(path35.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
50134
50148
  }
50135
50149
  function detectRubocop(cwd) {
50136
- return (fs14.existsSync(path36.join(cwd, "Gemfile")) || fs14.existsSync(path36.join(cwd, "gems.rb")) || fs14.existsSync(path36.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
50150
+ return (fs13.existsSync(path35.join(cwd, "Gemfile")) || fs13.existsSync(path35.join(cwd, "gems.rb")) || fs13.existsSync(path35.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
50137
50151
  }
50138
50152
  function detectAdditionalLinter(cwd) {
50139
50153
  if (detectRuff(cwd))
@@ -50161,10 +50175,10 @@ function detectAdditionalLinter(cwd) {
50161
50175
  function findBinInAncestors(startDir, binName) {
50162
50176
  let dir = startDir;
50163
50177
  while (true) {
50164
- const candidate = path36.join(dir, "node_modules", ".bin", binName);
50165
- if (fs14.existsSync(candidate))
50178
+ const candidate = path35.join(dir, "node_modules", ".bin", binName);
50179
+ if (fs13.existsSync(candidate))
50166
50180
  return candidate;
50167
- const parent = path36.dirname(dir);
50181
+ const parent = path35.dirname(dir);
50168
50182
  if (parent === dir)
50169
50183
  break;
50170
50184
  dir = parent;
@@ -50173,11 +50187,11 @@ function findBinInAncestors(startDir, binName) {
50173
50187
  }
50174
50188
  function findBinInEnvPath(binName) {
50175
50189
  const searchPath = process.env.PATH ?? "";
50176
- for (const dir of searchPath.split(path36.delimiter)) {
50190
+ for (const dir of searchPath.split(path35.delimiter)) {
50177
50191
  if (!dir)
50178
50192
  continue;
50179
- const candidate = path36.join(dir, binName);
50180
- if (fs14.existsSync(candidate))
50193
+ const candidate = path35.join(dir, binName);
50194
+ if (fs13.existsSync(candidate))
50181
50195
  return candidate;
50182
50196
  }
50183
50197
  return null;
@@ -50185,17 +50199,17 @@ function findBinInEnvPath(binName) {
50185
50199
  async function detectAvailableLinter(directory) {
50186
50200
  if (!directory)
50187
50201
  return null;
50188
- if (!fs14.existsSync(directory))
50202
+ if (!fs13.existsSync(directory))
50189
50203
  return null;
50190
50204
  const projectDir = directory;
50191
50205
  const isWindows = process.platform === "win32";
50192
- const biomeBin = isWindows ? path36.join(projectDir, "node_modules", ".bin", "biome.EXE") : path36.join(projectDir, "node_modules", ".bin", "biome");
50193
- const eslintBin = isWindows ? path36.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path36.join(projectDir, "node_modules", ".bin", "eslint");
50206
+ const biomeBin = isWindows ? path35.join(projectDir, "node_modules", ".bin", "biome.EXE") : path35.join(projectDir, "node_modules", ".bin", "biome");
50207
+ const eslintBin = isWindows ? path35.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path35.join(projectDir, "node_modules", ".bin", "eslint");
50194
50208
  const localResult = await _detectAvailableLinter(projectDir, biomeBin, eslintBin);
50195
50209
  if (localResult)
50196
50210
  return localResult;
50197
- const biomeAncestor = findBinInAncestors(path36.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
50198
- const eslintAncestor = findBinInAncestors(path36.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
50211
+ const biomeAncestor = findBinInAncestors(path35.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
50212
+ const eslintAncestor = findBinInAncestors(path35.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
50199
50213
  if (biomeAncestor || eslintAncestor) {
50200
50214
  return _detectAvailableLinter(projectDir, biomeAncestor ?? biomeBin, eslintAncestor ?? eslintBin);
50201
50215
  }
@@ -50214,11 +50228,11 @@ async function _detectAvailableLinter(_projectDir, biomeBin, eslintBin) {
50214
50228
  stderr: "pipe"
50215
50229
  });
50216
50230
  const biomeExit = biomeProc.exited;
50217
- const timeout = new Promise((resolve13) => setTimeout(() => resolve13("timeout"), DETECT_TIMEOUT));
50231
+ const timeout = new Promise((resolve12) => setTimeout(() => resolve12("timeout"), DETECT_TIMEOUT));
50218
50232
  const result = await Promise.race([biomeExit, timeout]);
50219
50233
  if (result === "timeout") {
50220
50234
  biomeProc.kill();
50221
- } else if (biomeProc.exitCode === 0 && fs14.existsSync(biomeBin)) {
50235
+ } else if (biomeProc.exitCode === 0 && fs13.existsSync(biomeBin)) {
50222
50236
  return "biome";
50223
50237
  }
50224
50238
  } catch {}
@@ -50228,11 +50242,11 @@ async function _detectAvailableLinter(_projectDir, biomeBin, eslintBin) {
50228
50242
  stderr: "pipe"
50229
50243
  });
50230
50244
  const eslintExit = eslintProc.exited;
50231
- const timeout = new Promise((resolve13) => setTimeout(() => resolve13("timeout"), DETECT_TIMEOUT));
50245
+ const timeout = new Promise((resolve12) => setTimeout(() => resolve12("timeout"), DETECT_TIMEOUT));
50232
50246
  const result = await Promise.race([eslintExit, timeout]);
50233
50247
  if (result === "timeout") {
50234
50248
  eslintProc.kill();
50235
- } else if (eslintProc.exitCode === 0 && fs14.existsSync(eslintBin)) {
50249
+ } else if (eslintProc.exitCode === 0 && fs13.existsSync(eslintBin)) {
50236
50250
  return "eslint";
50237
50251
  }
50238
50252
  } catch {}
@@ -50417,8 +50431,8 @@ For Rust: rustup component add clippy`
50417
50431
  });
50418
50432
 
50419
50433
  // src/tools/secretscan.ts
50420
- import * as fs15 from "fs";
50421
- import * as path37 from "path";
50434
+ import * as fs14 from "fs";
50435
+ import * as path36 from "path";
50422
50436
  function calculateShannonEntropy(str) {
50423
50437
  if (str.length === 0)
50424
50438
  return 0;
@@ -50466,11 +50480,11 @@ function isGlobOrPathPattern(pattern) {
50466
50480
  return pattern.includes("/") || pattern.includes("\\") || /[*?[\]{}]/.test(pattern);
50467
50481
  }
50468
50482
  function loadSecretScanIgnore(scanDir) {
50469
- const ignorePath = path37.join(scanDir, ".secretscanignore");
50483
+ const ignorePath = path36.join(scanDir, ".secretscanignore");
50470
50484
  try {
50471
- if (!fs15.existsSync(ignorePath))
50485
+ if (!fs14.existsSync(ignorePath))
50472
50486
  return [];
50473
- const content = fs15.readFileSync(ignorePath, "utf8");
50487
+ const content = fs14.readFileSync(ignorePath, "utf8");
50474
50488
  const patterns = [];
50475
50489
  for (const rawLine of content.split(/\r?\n/)) {
50476
50490
  const line = rawLine.trim();
@@ -50489,7 +50503,7 @@ function isExcluded(entry, relPath, exactNames, globPatterns) {
50489
50503
  if (exactNames.has(entry))
50490
50504
  return true;
50491
50505
  for (const pattern of globPatterns) {
50492
- if (path37.matchesGlob(relPath, pattern))
50506
+ if (path36.matchesGlob(relPath, pattern))
50493
50507
  return true;
50494
50508
  }
50495
50509
  return false;
@@ -50510,7 +50524,7 @@ function validateDirectoryInput(dir) {
50510
50524
  return null;
50511
50525
  }
50512
50526
  function isBinaryFile(filePath, buffer) {
50513
- const ext = path37.extname(filePath).toLowerCase();
50527
+ const ext = path36.extname(filePath).toLowerCase();
50514
50528
  if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
50515
50529
  return true;
50516
50530
  }
@@ -50588,7 +50602,7 @@ function createRedactedContext(line, findings) {
50588
50602
  function scanFileForSecrets(filePath) {
50589
50603
  const findings = [];
50590
50604
  try {
50591
- const lstat = fs15.lstatSync(filePath);
50605
+ const lstat = fs14.lstatSync(filePath);
50592
50606
  if (lstat.isSymbolicLink()) {
50593
50607
  return findings;
50594
50608
  }
@@ -50597,14 +50611,14 @@ function scanFileForSecrets(filePath) {
50597
50611
  }
50598
50612
  let buffer;
50599
50613
  if (O_NOFOLLOW !== undefined) {
50600
- const fd = fs15.openSync(filePath, "r", O_NOFOLLOW);
50614
+ const fd = fs14.openSync(filePath, "r", O_NOFOLLOW);
50601
50615
  try {
50602
- buffer = fs15.readFileSync(fd);
50616
+ buffer = fs14.readFileSync(fd);
50603
50617
  } finally {
50604
- fs15.closeSync(fd);
50618
+ fs14.closeSync(fd);
50605
50619
  }
50606
50620
  } else {
50607
- buffer = fs15.readFileSync(filePath);
50621
+ buffer = fs14.readFileSync(filePath);
50608
50622
  }
50609
50623
  if (isBinaryFile(filePath, buffer)) {
50610
50624
  return findings;
@@ -50646,9 +50660,9 @@ function isSymlinkLoop(realPath, visited) {
50646
50660
  return false;
50647
50661
  }
50648
50662
  function isPathWithinScope(realPath, scanDir) {
50649
- const resolvedScanDir = path37.resolve(scanDir);
50650
- const resolvedRealPath = path37.resolve(realPath);
50651
- return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path37.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
50663
+ const resolvedScanDir = path36.resolve(scanDir);
50664
+ const resolvedRealPath = path36.resolve(realPath);
50665
+ return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path36.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
50652
50666
  }
50653
50667
  function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, stats = {
50654
50668
  skippedDirs: 0,
@@ -50659,7 +50673,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
50659
50673
  const files = [];
50660
50674
  let entries;
50661
50675
  try {
50662
- entries = fs15.readdirSync(dir);
50676
+ entries = fs14.readdirSync(dir);
50663
50677
  } catch {
50664
50678
  stats.fileErrors++;
50665
50679
  return files;
@@ -50674,15 +50688,15 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
50674
50688
  return a.localeCompare(b);
50675
50689
  });
50676
50690
  for (const entry of entries) {
50677
- const fullPath = path37.join(dir, entry);
50678
- const relPath = path37.relative(scanDir, fullPath).replace(/\\/g, "/");
50691
+ const fullPath = path36.join(dir, entry);
50692
+ const relPath = path36.relative(scanDir, fullPath).replace(/\\/g, "/");
50679
50693
  if (isExcluded(entry, relPath, excludeExact, excludeGlobs)) {
50680
50694
  stats.skippedDirs++;
50681
50695
  continue;
50682
50696
  }
50683
50697
  let lstat;
50684
50698
  try {
50685
- lstat = fs15.lstatSync(fullPath);
50699
+ lstat = fs14.lstatSync(fullPath);
50686
50700
  } catch {
50687
50701
  stats.fileErrors++;
50688
50702
  continue;
@@ -50694,7 +50708,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
50694
50708
  if (lstat.isDirectory()) {
50695
50709
  let realPath;
50696
50710
  try {
50697
- realPath = fs15.realpathSync(fullPath);
50711
+ realPath = fs14.realpathSync(fullPath);
50698
50712
  } catch {
50699
50713
  stats.fileErrors++;
50700
50714
  continue;
@@ -50710,7 +50724,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
50710
50724
  const subFiles = findScannableFiles(fullPath, excludeExact, excludeGlobs, scanDir, visited, stats);
50711
50725
  files.push(...subFiles);
50712
50726
  } else if (lstat.isFile()) {
50713
- const ext = path37.extname(fullPath).toLowerCase();
50727
+ const ext = path36.extname(fullPath).toLowerCase();
50714
50728
  if (!DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
50715
50729
  files.push(fullPath);
50716
50730
  } else {
@@ -50913,7 +50927,7 @@ var init_secretscan = __esm(() => {
50913
50927
  redactTemplate: () => "SK[REDACTED]"
50914
50928
  }
50915
50929
  ];
50916
- O_NOFOLLOW = process.platform !== "win32" ? fs15.constants.O_NOFOLLOW : undefined;
50930
+ O_NOFOLLOW = process.platform !== "win32" ? fs14.constants.O_NOFOLLOW : undefined;
50917
50931
  secretscan = createSwarmTool({
50918
50932
  description: "Scan directory for potential secrets (API keys, tokens, passwords) using regex patterns and entropy heuristics. Returns metadata-only findings with redacted previews - NEVER returns raw secrets. Excludes common directories (node_modules, .git, dist, etc.) by default. Supports glob patterns (e.g. **/.svelte-kit/**, **/*.test.ts) and reads .secretscanignore at the scan root.",
50919
50933
  args: {
@@ -50970,15 +50984,15 @@ var init_secretscan = __esm(() => {
50970
50984
  }
50971
50985
  }
50972
50986
  try {
50973
- const _scanDirRaw = path37.resolve(directory);
50987
+ const _scanDirRaw = path36.resolve(directory);
50974
50988
  const scanDir = (() => {
50975
50989
  try {
50976
- return fs15.realpathSync(_scanDirRaw);
50990
+ return fs14.realpathSync(_scanDirRaw);
50977
50991
  } catch {
50978
50992
  return _scanDirRaw;
50979
50993
  }
50980
50994
  })();
50981
- if (!fs15.existsSync(scanDir)) {
50995
+ if (!fs14.existsSync(scanDir)) {
50982
50996
  const errorResult = {
50983
50997
  error: "directory not found",
50984
50998
  scan_dir: directory,
@@ -50989,7 +51003,7 @@ var init_secretscan = __esm(() => {
50989
51003
  };
50990
51004
  return JSON.stringify(errorResult, null, 2);
50991
51005
  }
50992
- const dirStat = fs15.statSync(scanDir);
51006
+ const dirStat = fs14.statSync(scanDir);
50993
51007
  if (!dirStat.isDirectory()) {
50994
51008
  const errorResult = {
50995
51009
  error: "target must be a directory, not a file",
@@ -51040,7 +51054,7 @@ var init_secretscan = __esm(() => {
51040
51054
  break;
51041
51055
  const fileFindings = scanFileForSecrets(filePath);
51042
51056
  try {
51043
- const stat4 = fs15.statSync(filePath);
51057
+ const stat4 = fs14.statSync(filePath);
51044
51058
  if (stat4.size > MAX_FILE_SIZE_BYTES) {
51045
51059
  skippedFiles++;
51046
51060
  continue;
@@ -51116,12 +51130,12 @@ var init_secretscan = __esm(() => {
51116
51130
  });
51117
51131
 
51118
51132
  // src/lang/default-backend.ts
51119
- import * as fs16 from "fs";
51120
- import * as path38 from "path";
51133
+ import * as fs15 from "fs";
51134
+ import * as path37 from "path";
51121
51135
  function detectFileExists(dir, pattern) {
51122
51136
  if (pattern.includes("*") || pattern.includes("?")) {
51123
51137
  try {
51124
- const files = fs16.readdirSync(dir);
51138
+ const files = fs15.readdirSync(dir);
51125
51139
  const regex = new RegExp(`^${pattern.replace(/\./g, "\\.").replace(/\*/g, ".*").replace(/\?/g, ".")}$`);
51126
51140
  return files.some((f) => regex.test(f));
51127
51141
  } catch {
@@ -51129,7 +51143,7 @@ function detectFileExists(dir, pattern) {
51129
51143
  }
51130
51144
  }
51131
51145
  try {
51132
- fs16.accessSync(path38.join(dir, pattern));
51146
+ fs15.accessSync(path37.join(dir, pattern));
51133
51147
  return true;
51134
51148
  } catch {
51135
51149
  return false;
@@ -51257,8 +51271,8 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
51257
51271
  return ["mvn", "test"];
51258
51272
  case "gradle": {
51259
51273
  const isWindows = process.platform === "win32";
51260
- const hasGradlewBat = fs16.existsSync(path38.join(dir, "gradlew.bat"));
51261
- const hasGradlew = fs16.existsSync(path38.join(dir, "gradlew"));
51274
+ const hasGradlewBat = fs15.existsSync(path37.join(dir, "gradlew.bat"));
51275
+ const hasGradlew = fs15.existsSync(path37.join(dir, "gradlew"));
51262
51276
  if (hasGradlewBat && isWindows)
51263
51277
  return ["gradlew.bat", "test"];
51264
51278
  if (hasGradlew)
@@ -51275,7 +51289,7 @@ function defaultBuildTestCommand(profile, framework, files, dir = ".", opts = {}
51275
51289
  "cmake-build-release",
51276
51290
  "out"
51277
51291
  ];
51278
- const actualBuildDir = buildDirCandidates.find((d) => fs16.existsSync(path38.join(dir, d, "CMakeCache.txt"))) ?? "build";
51292
+ const actualBuildDir = buildDirCandidates.find((d) => fs15.existsSync(path37.join(dir, d, "CMakeCache.txt"))) ?? "build";
51279
51293
  return ["ctest", "--test-dir", actualBuildDir];
51280
51294
  }
51281
51295
  case "swift-test":
@@ -51562,23 +51576,23 @@ async function defaultSelectBuildCommand(profile, dir) {
51562
51576
  return null;
51563
51577
  }
51564
51578
  async function defaultTestFilesFor(profile, sourceFile, dir) {
51565
- const ext = path38.extname(sourceFile);
51579
+ const ext = path37.extname(sourceFile);
51566
51580
  if (!profile.extensions.includes(ext))
51567
51581
  return [];
51568
- const base = path38.basename(sourceFile, ext);
51569
- const rel = path38.relative(dir, sourceFile);
51570
- const relDir = path38.dirname(rel);
51582
+ const base = path37.basename(sourceFile, ext);
51583
+ const rel = path37.relative(dir, sourceFile);
51584
+ const relDir = path37.dirname(rel);
51571
51585
  const stripSrc = relDir.replace(/^src(\/|\\)/, "");
51572
51586
  const candidates = new Set;
51573
51587
  for (const tDir of ["tests", "test", "__tests__", "spec"]) {
51574
51588
  for (const suffix of ["", "_test", ".test", "_spec", ".spec"]) {
51575
- candidates.add(path38.join(dir, tDir, stripSrc, `${base}${suffix}${ext}`));
51589
+ candidates.add(path37.join(dir, tDir, stripSrc, `${base}${suffix}${ext}`));
51576
51590
  }
51577
51591
  }
51578
51592
  const existing = [];
51579
51593
  for (const c of candidates) {
51580
51594
  try {
51581
- fs16.accessSync(c);
51595
+ fs15.accessSync(c);
51582
51596
  existing.push(c);
51583
51597
  } catch {}
51584
51598
  }
@@ -51612,8 +51626,8 @@ var init_default_backend = __esm(() => {
51612
51626
  });
51613
51627
 
51614
51628
  // src/lang/backends/go.ts
51615
- import * as fs17 from "fs";
51616
- import * as path39 from "path";
51629
+ import * as fs16 from "fs";
51630
+ import * as path38 from "path";
51617
51631
  function extractImports(_sourceFile, source) {
51618
51632
  const out = new Set;
51619
51633
  IMPORT_REGEX_SINGLE.lastIndex = 0;
@@ -51639,7 +51653,7 @@ function extractImports(_sourceFile, source) {
51639
51653
  async function selectFramework(dir) {
51640
51654
  let content;
51641
51655
  try {
51642
- content = fs17.readFileSync(path39.join(dir, "go.mod"), "utf-8");
51656
+ content = fs16.readFileSync(path38.join(dir, "go.mod"), "utf-8");
51643
51657
  } catch {
51644
51658
  return null;
51645
51659
  }
@@ -51660,16 +51674,16 @@ async function selectFramework(dir) {
51660
51674
  async function selectEntryPoints(dir) {
51661
51675
  const points = [];
51662
51676
  try {
51663
- fs17.accessSync(path39.join(dir, "main.go"));
51677
+ fs16.accessSync(path38.join(dir, "main.go"));
51664
51678
  points.push("main.go");
51665
51679
  } catch {}
51666
51680
  try {
51667
- const cmdDir = path39.join(dir, "cmd");
51668
- const subdirs = fs17.readdirSync(cmdDir, { withFileTypes: true }).filter((d) => d.isDirectory());
51681
+ const cmdDir = path38.join(dir, "cmd");
51682
+ const subdirs = fs16.readdirSync(cmdDir, { withFileTypes: true }).filter((d) => d.isDirectory());
51669
51683
  for (const sub of subdirs) {
51670
- const main = path39.join("cmd", sub.name, "main.go");
51684
+ const main = path38.join("cmd", sub.name, "main.go");
51671
51685
  try {
51672
- fs17.accessSync(path39.join(dir, main));
51686
+ fs16.accessSync(path38.join(dir, main));
51673
51687
  points.push(main);
51674
51688
  } catch {}
51675
51689
  }
@@ -51699,8 +51713,8 @@ var init_go = __esm(() => {
51699
51713
  });
51700
51714
 
51701
51715
  // src/lang/backends/python.ts
51702
- import * as fs18 from "fs";
51703
- import * as path40 from "path";
51716
+ import * as fs17 from "fs";
51717
+ import * as path39 from "path";
51704
51718
  function parseImportTargets(rawTargets) {
51705
51719
  const cleaned = rawTargets.replace(/[()]/g, "").split(`
51706
51720
  `).map((line) => line.replace(/#.*$/, "").replace(/\\\s*$/, "")).join(" ");
@@ -51760,7 +51774,7 @@ async function selectFramework2(dir) {
51760
51774
  ];
51761
51775
  for (const candidate of ["pyproject.toml", "requirements.txt", "setup.py"]) {
51762
51776
  try {
51763
- const content = fs18.readFileSync(path40.join(dir, candidate), "utf-8");
51777
+ const content = fs17.readFileSync(path39.join(dir, candidate), "utf-8");
51764
51778
  const lower = content.toLowerCase();
51765
51779
  for (const [pkg, name] of candidates) {
51766
51780
  if (lower.includes(pkg)) {
@@ -51774,7 +51788,7 @@ async function selectFramework2(dir) {
51774
51788
  async function selectEntryPoints2(dir) {
51775
51789
  const points = new Set;
51776
51790
  try {
51777
- const content = fs18.readFileSync(path40.join(dir, "pyproject.toml"), "utf-8");
51791
+ const content = fs17.readFileSync(path39.join(dir, "pyproject.toml"), "utf-8");
51778
51792
  const scriptsBlock = content.match(/\[project\.scripts\][\s\S]*?(?=\n\[|$)/);
51779
51793
  if (scriptsBlock) {
51780
51794
  for (const line of scriptsBlock[0].split(`
@@ -51789,7 +51803,7 @@ async function selectEntryPoints2(dir) {
51789
51803
  } catch {}
51790
51804
  for (const name of ["manage.py", "main.py", "app.py", "__main__.py"]) {
51791
51805
  try {
51792
- fs18.accessSync(path40.join(dir, name));
51806
+ fs17.accessSync(path39.join(dir, name));
51793
51807
  points.add(name);
51794
51808
  } catch {}
51795
51809
  }
@@ -51817,8 +51831,8 @@ var init_python = __esm(() => {
51817
51831
  });
51818
51832
 
51819
51833
  // src/test-impact/analyzer.ts
51820
- import fs19 from "fs";
51821
- import path41 from "path";
51834
+ import fs18 from "fs";
51835
+ import path40 from "path";
51822
51836
  function normalizePath(p) {
51823
51837
  return p.replace(/\\/g, "/");
51824
51838
  }
@@ -51838,7 +51852,7 @@ function sharedTrailingSegments(a, b) {
51838
51852
  function isCacheStale(impactMap, generatedAtMs) {
51839
51853
  for (const sourcePath of Object.keys(impactMap)) {
51840
51854
  try {
51841
- const stat4 = fs19.statSync(sourcePath);
51855
+ const stat4 = fs18.statSync(sourcePath);
51842
51856
  if (stat4.mtimeMs > generatedAtMs) {
51843
51857
  return true;
51844
51858
  }
@@ -51852,15 +51866,15 @@ function resolveRelativeImport(fromDir, importPath) {
51852
51866
  if (!importPath.startsWith(".")) {
51853
51867
  return null;
51854
51868
  }
51855
- const resolved = path41.resolve(fromDir, importPath);
51856
- if (path41.extname(resolved)) {
51857
- if (fs19.existsSync(resolved) && fs19.statSync(resolved).isFile()) {
51869
+ const resolved = path40.resolve(fromDir, importPath);
51870
+ if (path40.extname(resolved)) {
51871
+ if (fs18.existsSync(resolved) && fs18.statSync(resolved).isFile()) {
51858
51872
  return normalizePath(resolved);
51859
51873
  }
51860
51874
  } else {
51861
51875
  for (const ext of EXTENSIONS_TO_TRY) {
51862
51876
  const withExt = resolved + ext;
51863
- if (fs19.existsSync(withExt) && fs19.statSync(withExt).isFile()) {
51877
+ if (fs18.existsSync(withExt) && fs18.statSync(withExt).isFile()) {
51864
51878
  return normalizePath(withExt);
51865
51879
  }
51866
51880
  }
@@ -51873,29 +51887,29 @@ function resolvePythonImport(fromDir, module) {
51873
51887
  const leadingDots = module.match(/^\.+/)?.[0].length ?? 0;
51874
51888
  let baseDir = fromDir;
51875
51889
  for (let i = 1;i < leadingDots; i++) {
51876
- baseDir = path41.dirname(baseDir);
51890
+ baseDir = path40.dirname(baseDir);
51877
51891
  }
51878
51892
  const rest = module.slice(leadingDots);
51879
51893
  if (rest.length === 0) {
51880
- const initPath = path41.join(baseDir, "__init__.py");
51881
- if (fs19.existsSync(initPath) && fs19.statSync(initPath).isFile()) {
51894
+ const initPath = path40.join(baseDir, "__init__.py");
51895
+ if (fs18.existsSync(initPath) && fs18.statSync(initPath).isFile()) {
51882
51896
  return normalizePath(initPath);
51883
51897
  }
51884
51898
  return null;
51885
51899
  }
51886
- const subpath = rest.replace(/\./g, path41.sep);
51900
+ const subpath = rest.replace(/\./g, path40.sep);
51887
51901
  const candidates = [
51888
- `${path41.join(baseDir, subpath)}.py`,
51889
- path41.join(baseDir, subpath, "__init__.py")
51902
+ `${path40.join(baseDir, subpath)}.py`,
51903
+ path40.join(baseDir, subpath, "__init__.py")
51890
51904
  ];
51891
51905
  for (const c of candidates) {
51892
- if (fs19.existsSync(c) && fs19.statSync(c).isFile())
51906
+ if (fs18.existsSync(c) && fs18.statSync(c).isFile())
51893
51907
  return normalizePath(c);
51894
51908
  }
51895
51909
  return null;
51896
51910
  }
51897
51911
  function findGoModule(fromDir) {
51898
- const resolved = path41.resolve(fromDir);
51912
+ const resolved = path40.resolve(fromDir);
51899
51913
  let cur = resolved;
51900
51914
  const walked = [];
51901
51915
  for (let i = 0;i < 16; i++) {
@@ -51907,8 +51921,8 @@ function findGoModule(fromDir) {
51907
51921
  }
51908
51922
  walked.push(cur);
51909
51923
  try {
51910
- const goMod = path41.join(cur, "go.mod");
51911
- const content = fs19.readFileSync(goMod, "utf-8");
51924
+ const goMod = path40.join(cur, "go.mod");
51925
+ const content = fs18.readFileSync(goMod, "utf-8");
51912
51926
  const moduleMatch = content.match(/^\s*module\s+"?([^"\s/]+(?:\/[^"\s]+)*)"?/m);
51913
51927
  if (moduleMatch) {
51914
51928
  const result = { moduleRoot: cur, modulePath: moduleMatch[1] };
@@ -51918,10 +51932,10 @@ function findGoModule(fromDir) {
51918
51932
  }
51919
51933
  } catch {}
51920
51934
  try {
51921
- fs19.accessSync(path41.join(cur, ".git"));
51935
+ fs18.accessSync(path40.join(cur, ".git"));
51922
51936
  break;
51923
51937
  } catch {}
51924
- const parent = path41.dirname(cur);
51938
+ const parent = path40.dirname(cur);
51925
51939
  if (parent === cur)
51926
51940
  break;
51927
51941
  cur = parent;
@@ -51933,20 +51947,20 @@ function findGoModule(fromDir) {
51933
51947
  function resolveGoImport(fromDir, importPath) {
51934
51948
  let dir = null;
51935
51949
  if (importPath.startsWith(".")) {
51936
- dir = path41.resolve(fromDir, importPath);
51950
+ dir = path40.resolve(fromDir, importPath);
51937
51951
  } else {
51938
51952
  const mod = findGoModule(fromDir);
51939
51953
  if (mod && (importPath === mod.modulePath || importPath.startsWith(`${mod.modulePath}/`))) {
51940
51954
  const subpath = importPath.slice(mod.modulePath.length);
51941
- dir = path41.join(mod.moduleRoot, subpath);
51955
+ dir = path40.join(mod.moduleRoot, subpath);
51942
51956
  }
51943
51957
  }
51944
51958
  if (dir === null)
51945
51959
  return [];
51946
- if (!fs19.existsSync(dir) || !fs19.statSync(dir).isDirectory())
51960
+ if (!fs18.existsSync(dir) || !fs18.statSync(dir).isDirectory())
51947
51961
  return [];
51948
51962
  try {
51949
- return fs19.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath(path41.join(dir, f)));
51963
+ return fs18.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath(path40.join(dir, f)));
51950
51964
  } catch {
51951
51965
  return [];
51952
51966
  }
@@ -51966,13 +51980,13 @@ function findTestFilesSync(cwd) {
51966
51980
  function walk(dir, visitedInodes) {
51967
51981
  let entries;
51968
51982
  try {
51969
- entries = fs19.readdirSync(dir, { withFileTypes: true });
51983
+ entries = fs18.readdirSync(dir, { withFileTypes: true });
51970
51984
  } catch {
51971
51985
  return;
51972
51986
  }
51973
51987
  let dirInode;
51974
51988
  try {
51975
- dirInode = fs19.statSync(dir).ino;
51989
+ dirInode = fs18.statSync(dir).ino;
51976
51990
  } catch {
51977
51991
  return;
51978
51992
  }
@@ -51985,15 +51999,15 @@ function findTestFilesSync(cwd) {
51985
51999
  for (const entry of entries) {
51986
52000
  if (entry.isDirectory()) {
51987
52001
  if (!skipDirs.has(entry.name)) {
51988
- walk(path41.join(dir, entry.name), visitedInodes);
52002
+ walk(path40.join(dir, entry.name), visitedInodes);
51989
52003
  }
51990
52004
  } else if (entry.isFile()) {
51991
52005
  const name = entry.name;
51992
52006
  const isTsTest = /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(name) || dir.includes("__tests__") && /\.(ts|tsx|js|jsx)$/.test(name);
51993
- const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${path41.sep}tests${path41.sep}`) && name.endsWith(".py");
52007
+ const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${path40.sep}tests${path40.sep}`) && name.endsWith(".py");
51994
52008
  const isGoTest = /.+_test\.go$/.test(name);
51995
52009
  if (isTsTest || isPyTest || isGoTest) {
51996
- testFiles.push(normalizePath(path41.join(dir, entry.name)));
52010
+ testFiles.push(normalizePath(path40.join(dir, entry.name)));
51997
52011
  }
51998
52012
  }
51999
52013
  }
@@ -52018,8 +52032,8 @@ function extractImports3(content) {
52018
52032
  ];
52019
52033
  }
52020
52034
  function addImpactEdgesForTestFile(testFile, content, impactMap) {
52021
- const ext = path41.extname(testFile).toLowerCase();
52022
- const testDir = path41.dirname(testFile);
52035
+ const ext = path40.extname(testFile).toLowerCase();
52036
+ const testDir = path40.dirname(testFile);
52023
52037
  function addEdge(source) {
52024
52038
  if (!impactMap[source])
52025
52039
  impactMap[source] = [];
@@ -52061,7 +52075,7 @@ async function buildImpactMapInternal(cwd) {
52061
52075
  for (const testFile of testFiles) {
52062
52076
  let content;
52063
52077
  try {
52064
- content = fs19.readFileSync(testFile, "utf-8");
52078
+ content = fs18.readFileSync(testFile, "utf-8");
52065
52079
  } catch {
52066
52080
  continue;
52067
52081
  }
@@ -52078,10 +52092,10 @@ async function buildImpactMap(cwd) {
52078
52092
  return impactMap;
52079
52093
  }
52080
52094
  async function loadImpactMap(cwd, options) {
52081
- const cachePath = path41.join(cwd, ".swarm", "cache", "impact-map.json");
52082
- if (fs19.existsSync(cachePath)) {
52095
+ const cachePath = path40.join(cwd, ".swarm", "cache", "impact-map.json");
52096
+ if (fs18.existsSync(cachePath)) {
52083
52097
  try {
52084
- const content = fs19.readFileSync(cachePath, "utf-8");
52098
+ const content = fs18.readFileSync(cachePath, "utf-8");
52085
52099
  const data = JSON.parse(content);
52086
52100
  if (data.map !== null && typeof data.map === "object" && !Array.isArray(data.map)) {
52087
52101
  const map3 = data.map;
@@ -52111,21 +52125,21 @@ async function loadImpactMap(cwd, options) {
52111
52125
  return _internals25.buildImpactMap(cwd);
52112
52126
  }
52113
52127
  async function saveImpactMap(cwd, impactMap) {
52114
- if (!path41.isAbsolute(cwd)) {
52128
+ if (!path40.isAbsolute(cwd)) {
52115
52129
  throw new Error(`saveImpactMap requires an absolute project root path, got: "${cwd}"`);
52116
52130
  }
52117
52131
  _internals25.validateProjectRoot(cwd);
52118
- const cacheDir2 = path41.join(cwd, ".swarm", "cache");
52119
- const cachePath = path41.join(cacheDir2, "impact-map.json");
52120
- if (!fs19.existsSync(cacheDir2)) {
52121
- fs19.mkdirSync(cacheDir2, { recursive: true });
52132
+ const cacheDir2 = path40.join(cwd, ".swarm", "cache");
52133
+ const cachePath = path40.join(cacheDir2, "impact-map.json");
52134
+ if (!fs18.existsSync(cacheDir2)) {
52135
+ fs18.mkdirSync(cacheDir2, { recursive: true });
52122
52136
  }
52123
52137
  const data = {
52124
52138
  generatedAt: new Date().toISOString(),
52125
52139
  fileCount: Object.keys(impactMap).length,
52126
52140
  map: impactMap
52127
52141
  };
52128
- fs19.writeFileSync(cachePath, JSON.stringify(data, null, 2), "utf-8");
52142
+ fs18.writeFileSync(cachePath, JSON.stringify(data, null, 2), "utf-8");
52129
52143
  }
52130
52144
  async function analyzeImpact(changedFiles, cwd, budget) {
52131
52145
  if (!Array.isArray(changedFiles)) {
@@ -52148,7 +52162,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
52148
52162
  budgetExceeded = true;
52149
52163
  break;
52150
52164
  }
52151
- const normalizedChanged = normalizePath(path41.resolve(changedFile));
52165
+ const normalizedChanged = normalizePath(path40.resolve(changedFile));
52152
52166
  const tests = impactMap[normalizedChanged];
52153
52167
  if (tests && tests.length > 0) {
52154
52168
  for (const test of tests) {
@@ -52162,13 +52176,13 @@ async function analyzeImpact(changedFiles, cwd, budget) {
52162
52176
  if (budgetExceeded)
52163
52177
  break;
52164
52178
  } else {
52165
- const changedDir = normalizePath(path41.dirname(normalizedChanged));
52166
- const changedInputDir = normalizePath(path41.dirname(changedFile));
52179
+ const changedDir = normalizePath(path40.dirname(normalizedChanged));
52180
+ const changedInputDir = normalizePath(path40.dirname(changedFile));
52167
52181
  const suffixMatches = Object.entries(impactMap).filter(([sourcePath]) => {
52168
52182
  return sourcePath.endsWith(changedFile) || changedFile.endsWith(sourcePath) || sourcePath.endsWith(normalizedChanged) || normalizedChanged.endsWith(sourcePath);
52169
52183
  }).sort(([sourceA], [sourceB]) => {
52170
- const sourceDirA = normalizePath(path41.dirname(sourceA));
52171
- const sourceDirB = normalizePath(path41.dirname(sourceB));
52184
+ const sourceDirA = normalizePath(path40.dirname(sourceA));
52185
+ const sourceDirB = normalizePath(path40.dirname(sourceB));
52172
52186
  const exactA = sourceDirA === changedDir || changedInputDir !== "." && (sourceDirA === changedInputDir || sourceDirA.endsWith(`/${changedInputDir}`));
52173
52187
  const exactB = sourceDirB === changedDir || changedInputDir !== "." && (sourceDirB === changedInputDir || sourceDirB.endsWith(`/${changedInputDir}`));
52174
52188
  if (exactA !== exactB)
@@ -52458,16 +52472,16 @@ function detectFlakyTests(allHistory) {
52458
52472
  var FLAKY_THRESHOLD = 0.3, MIN_RUNS_FOR_QUARANTINE = 5, MAX_HISTORY_RUNS = 20;
52459
52473
 
52460
52474
  // src/test-impact/history-store.ts
52461
- import fs20 from "fs";
52462
- import path42 from "path";
52475
+ import fs19 from "fs";
52476
+ import path41 from "path";
52463
52477
  function getHistoryPath(workingDir) {
52464
52478
  if (!workingDir) {
52465
52479
  throw new Error("getHistoryPath requires a working directory \u2014 project root must be provided by the caller");
52466
52480
  }
52467
- if (!path42.isAbsolute(workingDir)) {
52481
+ if (!path41.isAbsolute(workingDir)) {
52468
52482
  throw new Error(`getHistoryPath requires an absolute project root path, got: "${workingDir}"`);
52469
52483
  }
52470
- return path42.join(workingDir, ".swarm", "cache", "test-history.jsonl");
52484
+ return path41.join(workingDir, ".swarm", "cache", "test-history.jsonl");
52471
52485
  }
52472
52486
  function sanitizeErrorMessage(errorMessage) {
52473
52487
  if (errorMessage === undefined) {
@@ -52554,10 +52568,10 @@ function batchAppendTestRuns(records, workingDir) {
52554
52568
  }
52555
52569
  }
52556
52570
  const historyPath = getHistoryPath(workingDir);
52557
- const historyDir = path42.dirname(historyPath);
52571
+ const historyDir = path41.dirname(historyPath);
52558
52572
  _internals26.validateProjectRoot(workingDir);
52559
- if (!fs20.existsSync(historyDir)) {
52560
- fs20.mkdirSync(historyDir, { recursive: true });
52573
+ if (!fs19.existsSync(historyDir)) {
52574
+ fs19.mkdirSync(historyDir, { recursive: true });
52561
52575
  }
52562
52576
  const existingRecords = readAllRecords(historyPath);
52563
52577
  const sanitizedRecords = records.map((record3) => ({
@@ -52590,24 +52604,24 @@ function batchAppendTestRuns(records, workingDir) {
52590
52604
  `)}
52591
52605
  `;
52592
52606
  const tempPath = `${historyPath}.tmp`;
52593
- fs20.writeFileSync(tempPath, content, "utf-8");
52594
- fs20.renameSync(tempPath, historyPath);
52607
+ fs19.writeFileSync(tempPath, content, "utf-8");
52608
+ fs19.renameSync(tempPath, historyPath);
52595
52609
  } catch (err) {
52596
52610
  try {
52597
52611
  const tempPath = `${historyPath}.tmp`;
52598
- if (fs20.existsSync(tempPath)) {
52599
- fs20.unlinkSync(tempPath);
52612
+ if (fs19.existsSync(tempPath)) {
52613
+ fs19.unlinkSync(tempPath);
52600
52614
  }
52601
52615
  } catch {}
52602
52616
  throw new Error(`Failed to write test history: ${err instanceof Error ? err.message : String(err)}`);
52603
52617
  }
52604
52618
  }
52605
52619
  function readAllRecords(historyPath) {
52606
- if (!fs20.existsSync(historyPath)) {
52620
+ if (!fs19.existsSync(historyPath)) {
52607
52621
  return [];
52608
52622
  }
52609
52623
  try {
52610
- const content = fs20.readFileSync(historyPath, "utf-8");
52624
+ const content = fs19.readFileSync(historyPath, "utf-8");
52611
52625
  const lines = content.split(`
52612
52626
  `);
52613
52627
  const records = [];
@@ -52649,8 +52663,8 @@ var init_history_store = __esm(() => {
52649
52663
  });
52650
52664
 
52651
52665
  // src/tools/resolve-working-directory.ts
52652
- import * as fs21 from "fs";
52653
- import * as path43 from "path";
52666
+ import * as fs20 from "fs";
52667
+ import * as path42 from "path";
52654
52668
  function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
52655
52669
  if (workingDirectory == null || workingDirectory === "") {
52656
52670
  return { success: true, directory: fallbackDirectory };
@@ -52670,18 +52684,18 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
52670
52684
  };
52671
52685
  }
52672
52686
  }
52673
- const normalizedDir = path43.normalize(workingDirectory);
52674
- const pathParts = normalizedDir.split(path43.sep);
52687
+ const normalizedDir = path42.normalize(workingDirectory);
52688
+ const pathParts = normalizedDir.split(path42.sep);
52675
52689
  if (pathParts.includes("..")) {
52676
52690
  return {
52677
52691
  success: false,
52678
52692
  message: "Invalid working_directory: path traversal sequences (..) are not allowed"
52679
52693
  };
52680
52694
  }
52681
- const resolvedDir = path43.resolve(normalizedDir);
52695
+ const resolvedDir = path42.resolve(normalizedDir);
52682
52696
  let statResult;
52683
52697
  try {
52684
- statResult = fs21.statSync(resolvedDir);
52698
+ statResult = fs20.statSync(resolvedDir);
52685
52699
  } catch {
52686
52700
  return {
52687
52701
  success: false,
@@ -52694,17 +52708,17 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
52694
52708
  message: `Invalid working_directory: path "${resolvedDir}" is not a directory`
52695
52709
  };
52696
52710
  }
52697
- const resolvedFallback = path43.resolve(fallbackDirectory);
52711
+ const resolvedFallback = path42.resolve(fallbackDirectory);
52698
52712
  let fallbackExists = false;
52699
52713
  try {
52700
- fs21.statSync(resolvedFallback);
52714
+ fs20.statSync(resolvedFallback);
52701
52715
  fallbackExists = true;
52702
52716
  } catch {
52703
52717
  fallbackExists = false;
52704
52718
  }
52705
52719
  if (workingDirectory != null && workingDirectory !== "") {
52706
52720
  if (fallbackExists) {
52707
- const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path43.sep);
52721
+ const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path42.sep);
52708
52722
  if (isSubdirectory) {
52709
52723
  return {
52710
52724
  success: false,
@@ -52758,11 +52772,11 @@ var init_registry_backend = __esm(() => {
52758
52772
  });
52759
52773
 
52760
52774
  // src/lang/backends/typescript.ts
52761
- import * as fs22 from "fs";
52762
- import * as path44 from "path";
52775
+ import * as fs21 from "fs";
52776
+ import * as path43 from "path";
52763
52777
  function readPackageJsonRaw(dir) {
52764
52778
  try {
52765
- const content = fs22.readFileSync(path44.join(dir, "package.json"), "utf-8");
52779
+ const content = fs21.readFileSync(path43.join(dir, "package.json"), "utf-8");
52766
52780
  return JSON.parse(content);
52767
52781
  } catch {
52768
52782
  return null;
@@ -52981,11 +52995,11 @@ __export(exports_dispatch, {
52981
52995
  clearDispatchCache: () => clearDispatchCache,
52982
52996
  _internals: () => _internals28
52983
52997
  });
52984
- import * as fs23 from "fs";
52985
- import * as path45 from "path";
52998
+ import * as fs22 from "fs";
52999
+ import * as path44 from "path";
52986
53000
  function safeReaddirSet(dir) {
52987
53001
  try {
52988
- return new Set(fs23.readdirSync(dir));
53002
+ return new Set(fs22.readdirSync(dir));
52989
53003
  } catch {
52990
53004
  return new Set;
52991
53005
  }
@@ -52999,14 +53013,14 @@ function manifestHash(dir) {
52999
53013
  if (!entries.has(name))
53000
53014
  continue;
53001
53015
  try {
53002
- const stat4 = fs23.statSync(path45.join(dir, name));
53016
+ const stat4 = fs22.statSync(path44.join(dir, name));
53003
53017
  parts.push(`${name}:${stat4.size}:${stat4.mtimeMs}:${stat4.ino}`);
53004
53018
  } catch {}
53005
53019
  }
53006
53020
  return parts.join("|");
53007
53021
  }
53008
53022
  function findManifestRoot(start) {
53009
- const resolved = path45.resolve(start);
53023
+ const resolved = path44.resolve(start);
53010
53024
  const cached3 = manifestRootCache.get(resolved);
53011
53025
  if (cached3 !== undefined)
53012
53026
  return cached3;
@@ -53025,7 +53039,7 @@ function findManifestRoot(start) {
53025
53039
  return cur;
53026
53040
  }
53027
53041
  }
53028
- const parent = path45.dirname(cur);
53042
+ const parent = path44.dirname(cur);
53029
53043
  if (parent === cur)
53030
53044
  break;
53031
53045
  cur = parent;
@@ -53134,14 +53148,14 @@ var init_dispatch = __esm(() => {
53134
53148
  });
53135
53149
 
53136
53150
  // src/tools/test-runner.ts
53137
- import * as fs24 from "fs";
53138
- import * as path46 from "path";
53151
+ import * as fs23 from "fs";
53152
+ import * as path45 from "path";
53139
53153
  async function estimateFanOut(sourceFiles, cwd) {
53140
53154
  try {
53141
53155
  const impactMap = await loadImpactMap(cwd, { skipRebuild: true });
53142
53156
  const uniqueTestFiles = new Set;
53143
53157
  for (const sourceFile of sourceFiles) {
53144
- const resolvedPath = path46.resolve(cwd, sourceFile);
53158
+ const resolvedPath = path45.resolve(cwd, sourceFile);
53145
53159
  const normalizedPath = resolvedPath.replace(/\\/g, "/");
53146
53160
  const testFiles = impactMap[normalizedPath];
53147
53161
  if (testFiles) {
@@ -53219,19 +53233,19 @@ function hasDevDependency(devDeps, ...patterns) {
53219
53233
  return hasPackageJsonDependency(devDeps, ...patterns);
53220
53234
  }
53221
53235
  function detectGoTest(cwd) {
53222
- return fs24.existsSync(path46.join(cwd, "go.mod")) && isCommandAvailable("go");
53236
+ return fs23.existsSync(path45.join(cwd, "go.mod")) && isCommandAvailable("go");
53223
53237
  }
53224
53238
  function detectJavaMaven(cwd) {
53225
- return fs24.existsSync(path46.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
53239
+ return fs23.existsSync(path45.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
53226
53240
  }
53227
53241
  function detectGradle(cwd) {
53228
- const hasBuildFile = fs24.existsSync(path46.join(cwd, "build.gradle")) || fs24.existsSync(path46.join(cwd, "build.gradle.kts"));
53229
- const hasGradlew = fs24.existsSync(path46.join(cwd, "gradlew")) || fs24.existsSync(path46.join(cwd, "gradlew.bat"));
53242
+ const hasBuildFile = fs23.existsSync(path45.join(cwd, "build.gradle")) || fs23.existsSync(path45.join(cwd, "build.gradle.kts"));
53243
+ const hasGradlew = fs23.existsSync(path45.join(cwd, "gradlew")) || fs23.existsSync(path45.join(cwd, "gradlew.bat"));
53230
53244
  return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
53231
53245
  }
53232
53246
  function detectDotnetTest(cwd) {
53233
53247
  try {
53234
- const files = fs24.readdirSync(cwd);
53248
+ const files = fs23.readdirSync(cwd);
53235
53249
  const hasCsproj = files.some((f) => f.endsWith(".csproj"));
53236
53250
  return hasCsproj && isCommandAvailable("dotnet");
53237
53251
  } catch {
@@ -53239,25 +53253,25 @@ function detectDotnetTest(cwd) {
53239
53253
  }
53240
53254
  }
53241
53255
  function detectCTest(cwd) {
53242
- const hasSource = fs24.existsSync(path46.join(cwd, "CMakeLists.txt"));
53243
- const hasBuildCache = fs24.existsSync(path46.join(cwd, "CMakeCache.txt")) || fs24.existsSync(path46.join(cwd, "build", "CMakeCache.txt"));
53256
+ const hasSource = fs23.existsSync(path45.join(cwd, "CMakeLists.txt"));
53257
+ const hasBuildCache = fs23.existsSync(path45.join(cwd, "CMakeCache.txt")) || fs23.existsSync(path45.join(cwd, "build", "CMakeCache.txt"));
53244
53258
  return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
53245
53259
  }
53246
53260
  function detectSwiftTest(cwd) {
53247
- return fs24.existsSync(path46.join(cwd, "Package.swift")) && isCommandAvailable("swift");
53261
+ return fs23.existsSync(path45.join(cwd, "Package.swift")) && isCommandAvailable("swift");
53248
53262
  }
53249
53263
  function detectDartTest(cwd) {
53250
- return fs24.existsSync(path46.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
53264
+ return fs23.existsSync(path45.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
53251
53265
  }
53252
53266
  function detectRSpec(cwd) {
53253
- const hasRSpecFile = fs24.existsSync(path46.join(cwd, ".rspec"));
53254
- const hasGemfile = fs24.existsSync(path46.join(cwd, "Gemfile"));
53255
- const hasSpecDir = fs24.existsSync(path46.join(cwd, "spec"));
53267
+ const hasRSpecFile = fs23.existsSync(path45.join(cwd, ".rspec"));
53268
+ const hasGemfile = fs23.existsSync(path45.join(cwd, "Gemfile"));
53269
+ const hasSpecDir = fs23.existsSync(path45.join(cwd, "spec"));
53256
53270
  const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
53257
53271
  return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
53258
53272
  }
53259
53273
  function detectMinitest(cwd) {
53260
- return fs24.existsSync(path46.join(cwd, "test")) && (fs24.existsSync(path46.join(cwd, "Gemfile")) || fs24.existsSync(path46.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
53274
+ return fs23.existsSync(path45.join(cwd, "test")) && (fs23.existsSync(path45.join(cwd, "Gemfile")) || fs23.existsSync(path45.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
53261
53275
  }
53262
53276
  async function detectTestFrameworkViaDispatch(cwd) {
53263
53277
  try {
@@ -53319,9 +53333,9 @@ async function parseTestOutputViaDispatch(framework, output, baseDir) {
53319
53333
  async function detectTestFramework(cwd) {
53320
53334
  const baseDir = cwd;
53321
53335
  try {
53322
- const packageJsonPath = path46.join(baseDir, "package.json");
53323
- if (fs24.existsSync(packageJsonPath)) {
53324
- const content = fs24.readFileSync(packageJsonPath, "utf-8");
53336
+ const packageJsonPath = path45.join(baseDir, "package.json");
53337
+ if (fs23.existsSync(packageJsonPath)) {
53338
+ const content = fs23.readFileSync(packageJsonPath, "utf-8");
53325
53339
  const pkg = JSON.parse(content);
53326
53340
  const _deps = pkg.dependencies || {};
53327
53341
  const devDeps = pkg.devDependencies || {};
@@ -53340,38 +53354,38 @@ async function detectTestFramework(cwd) {
53340
53354
  return "jest";
53341
53355
  if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
53342
53356
  return "mocha";
53343
- if (fs24.existsSync(path46.join(baseDir, "bun.lockb")) || fs24.existsSync(path46.join(baseDir, "bun.lock"))) {
53357
+ if (fs23.existsSync(path45.join(baseDir, "bun.lockb")) || fs23.existsSync(path45.join(baseDir, "bun.lock"))) {
53344
53358
  if (scripts.test?.includes("bun"))
53345
53359
  return "bun";
53346
53360
  }
53347
53361
  }
53348
53362
  } catch {}
53349
53363
  try {
53350
- const pyprojectTomlPath = path46.join(baseDir, "pyproject.toml");
53351
- const setupCfgPath = path46.join(baseDir, "setup.cfg");
53352
- const requirementsTxtPath = path46.join(baseDir, "requirements.txt");
53353
- if (fs24.existsSync(pyprojectTomlPath)) {
53354
- const content = fs24.readFileSync(pyprojectTomlPath, "utf-8");
53364
+ const pyprojectTomlPath = path45.join(baseDir, "pyproject.toml");
53365
+ const setupCfgPath = path45.join(baseDir, "setup.cfg");
53366
+ const requirementsTxtPath = path45.join(baseDir, "requirements.txt");
53367
+ if (fs23.existsSync(pyprojectTomlPath)) {
53368
+ const content = fs23.readFileSync(pyprojectTomlPath, "utf-8");
53355
53369
  if (content.includes("[tool.pytest"))
53356
53370
  return "pytest";
53357
53371
  if (content.includes("pytest"))
53358
53372
  return "pytest";
53359
53373
  }
53360
- if (fs24.existsSync(setupCfgPath)) {
53361
- const content = fs24.readFileSync(setupCfgPath, "utf-8");
53374
+ if (fs23.existsSync(setupCfgPath)) {
53375
+ const content = fs23.readFileSync(setupCfgPath, "utf-8");
53362
53376
  if (content.includes("[pytest]"))
53363
53377
  return "pytest";
53364
53378
  }
53365
- if (fs24.existsSync(requirementsTxtPath)) {
53366
- const content = fs24.readFileSync(requirementsTxtPath, "utf-8");
53379
+ if (fs23.existsSync(requirementsTxtPath)) {
53380
+ const content = fs23.readFileSync(requirementsTxtPath, "utf-8");
53367
53381
  if (content.includes("pytest"))
53368
53382
  return "pytest";
53369
53383
  }
53370
53384
  } catch {}
53371
53385
  try {
53372
- const cargoTomlPath = path46.join(baseDir, "Cargo.toml");
53373
- if (fs24.existsSync(cargoTomlPath)) {
53374
- const content = fs24.readFileSync(cargoTomlPath, "utf-8");
53386
+ const cargoTomlPath = path45.join(baseDir, "Cargo.toml");
53387
+ if (fs23.existsSync(cargoTomlPath)) {
53388
+ const content = fs23.readFileSync(cargoTomlPath, "utf-8");
53375
53389
  if (content.includes("[dev-dependencies]")) {
53376
53390
  if (content.includes("tokio") || content.includes("mockall") || content.includes("pretty_assertions")) {
53377
53391
  return "cargo";
@@ -53380,10 +53394,10 @@ async function detectTestFramework(cwd) {
53380
53394
  }
53381
53395
  } catch {}
53382
53396
  try {
53383
- const pesterConfigPath = path46.join(baseDir, "pester.config.ps1");
53384
- const pesterConfigJsonPath = path46.join(baseDir, "pester.config.ps1.json");
53385
- const pesterPs1Path = path46.join(baseDir, "tests.ps1");
53386
- if (fs24.existsSync(pesterConfigPath) || fs24.existsSync(pesterConfigJsonPath) || fs24.existsSync(pesterPs1Path)) {
53397
+ const pesterConfigPath = path45.join(baseDir, "pester.config.ps1");
53398
+ const pesterConfigJsonPath = path45.join(baseDir, "pester.config.ps1.json");
53399
+ const pesterPs1Path = path45.join(baseDir, "tests.ps1");
53400
+ if (fs23.existsSync(pesterConfigPath) || fs23.existsSync(pesterConfigJsonPath) || fs23.existsSync(pesterPs1Path)) {
53387
53401
  return "pester";
53388
53402
  }
53389
53403
  } catch {}
@@ -53411,12 +53425,12 @@ function isTestDirectoryPath(normalizedPath) {
53411
53425
  return normalizedPath.split("/").some((segment) => TEST_DIRECTORY_NAMES.includes(segment));
53412
53426
  }
53413
53427
  function resolveWorkspacePath(file3, workingDir) {
53414
- return path46.isAbsolute(file3) ? path46.resolve(file3) : path46.resolve(workingDir, file3);
53428
+ return path45.isAbsolute(file3) ? path45.resolve(file3) : path45.resolve(workingDir, file3);
53415
53429
  }
53416
53430
  function toWorkspaceOutputPath(absolutePath, workingDir, preferRelative) {
53417
53431
  if (!preferRelative)
53418
53432
  return absolutePath;
53419
- return path46.relative(workingDir, absolutePath);
53433
+ return path45.relative(workingDir, absolutePath);
53420
53434
  }
53421
53435
  function dedupePush(target, value) {
53422
53436
  if (!target.includes(value)) {
@@ -53453,18 +53467,18 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
53453
53467
  }
53454
53468
  }
53455
53469
  function getRepoLevelCandidateDirectories(workingDir, relativePath, ext) {
53456
- const relativeDir = path46.dirname(relativePath);
53470
+ const relativeDir = path45.dirname(relativePath);
53457
53471
  const nestedRelativeDir = relativeDir === "." ? "" : relativeDir;
53458
53472
  const directories = TEST_DIRECTORY_NAMES.flatMap((dirName) => {
53459
- const rootDir = path46.join(workingDir, dirName);
53460
- return nestedRelativeDir ? [rootDir, path46.join(rootDir, nestedRelativeDir)] : [rootDir];
53473
+ const rootDir = path45.join(workingDir, dirName);
53474
+ return nestedRelativeDir ? [rootDir, path45.join(rootDir, nestedRelativeDir)] : [rootDir];
53461
53475
  });
53462
53476
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
53463
53477
  if (ext === ".java" && normalizedRelativePath.startsWith("src/main/java/")) {
53464
- directories.push(path46.join(workingDir, "src/test/java", path46.dirname(normalizedRelativePath.slice("src/main/java/".length))));
53478
+ directories.push(path45.join(workingDir, "src/test/java", path45.dirname(normalizedRelativePath.slice("src/main/java/".length))));
53465
53479
  }
53466
53480
  if ((ext === ".kt" || ext === ".java") && normalizedRelativePath.startsWith("src/main/kotlin/")) {
53467
- directories.push(path46.join(workingDir, "src/test/kotlin", path46.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
53481
+ directories.push(path45.join(workingDir, "src/test/kotlin", path45.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
53468
53482
  }
53469
53483
  return [...new Set(directories)];
53470
53484
  }
@@ -53492,23 +53506,23 @@ function isLanguageSpecificTestFile(basename7) {
53492
53506
  }
53493
53507
  function isConventionTestFilePath(filePath) {
53494
53508
  const normalizedPath = filePath.replace(/\\/g, "/");
53495
- const basename7 = path46.basename(filePath);
53509
+ const basename7 = path45.basename(filePath);
53496
53510
  return hasCompoundTestExtension(basename7) || basename7.includes(".spec.") || basename7.includes(".test.") || isLanguageSpecificTestFile(basename7) || isTestDirectoryPath(normalizedPath);
53497
53511
  }
53498
53512
  function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
53499
53513
  const testFiles = [];
53500
53514
  for (const file3 of sourceFiles) {
53501
53515
  const absoluteFile = resolveWorkspacePath(file3, workingDir);
53502
- const relativeFile = path46.relative(workingDir, absoluteFile);
53503
- const basename7 = path46.basename(absoluteFile);
53504
- const dirname23 = path46.dirname(absoluteFile);
53505
- const preferRelativeOutput = !path46.isAbsolute(file3);
53516
+ const relativeFile = path45.relative(workingDir, absoluteFile);
53517
+ const basename7 = path45.basename(absoluteFile);
53518
+ const dirname23 = path45.dirname(absoluteFile);
53519
+ const preferRelativeOutput = !path45.isAbsolute(file3);
53506
53520
  if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file3)) {
53507
53521
  dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
53508
53522
  continue;
53509
53523
  }
53510
53524
  const nameWithoutExt = basename7.replace(/\.[^.]+$/, "");
53511
- const ext = path46.extname(basename7);
53525
+ const ext = path45.extname(basename7);
53512
53526
  const genericTestNames = [
53513
53527
  `${nameWithoutExt}.spec${ext}`,
53514
53528
  `${nameWithoutExt}.test${ext}`
@@ -53517,7 +53531,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
53517
53531
  const colocatedCandidates = [
53518
53532
  ...genericTestNames,
53519
53533
  ...languageSpecificTestNames
53520
- ].map((candidateName) => path46.join(dirname23, candidateName));
53534
+ ].map((candidateName) => path45.join(dirname23, candidateName));
53521
53535
  const testDirectoryNames = [
53522
53536
  basename7,
53523
53537
  ...genericTestNames,
@@ -53526,11 +53540,11 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
53526
53540
  const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
53527
53541
  const possibleTestFiles = [
53528
53542
  ...colocatedCandidates,
53529
- ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path46.join(dirname23, dirName, candidateName))),
53530
- ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path46.join(candidateDir, candidateName)))
53543
+ ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path45.join(dirname23, dirName, candidateName))),
53544
+ ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path45.join(candidateDir, candidateName)))
53531
53545
  ];
53532
53546
  for (const testFile of possibleTestFiles) {
53533
- if (fs24.existsSync(testFile)) {
53547
+ if (fs23.existsSync(testFile)) {
53534
53548
  dedupePush(testFiles, toWorkspaceOutputPath(testFile, workingDir, preferRelativeOutput));
53535
53549
  }
53536
53550
  }
@@ -53547,8 +53561,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
53547
53561
  for (const testFile of candidateTestFiles) {
53548
53562
  try {
53549
53563
  const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
53550
- const content = fs24.readFileSync(absoluteTestFile, "utf-8");
53551
- const testDir = path46.dirname(absoluteTestFile);
53564
+ const content = fs23.readFileSync(absoluteTestFile, "utf-8");
53565
+ const testDir = path45.dirname(absoluteTestFile);
53552
53566
  const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
53553
53567
  let match;
53554
53568
  match = importRegex.exec(content);
@@ -53556,8 +53570,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
53556
53570
  const importPath = match[1];
53557
53571
  let resolvedImport;
53558
53572
  if (importPath.startsWith(".")) {
53559
- resolvedImport = path46.resolve(testDir, importPath);
53560
- const existingExt = path46.extname(resolvedImport);
53573
+ resolvedImport = path45.resolve(testDir, importPath);
53574
+ const existingExt = path45.extname(resolvedImport);
53561
53575
  if (!existingExt) {
53562
53576
  for (const extToTry of [
53563
53577
  ".ts",
@@ -53568,7 +53582,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
53568
53582
  ".cjs"
53569
53583
  ]) {
53570
53584
  const withExt = resolvedImport + extToTry;
53571
- if (absoluteSourceFiles.includes(withExt) || fs24.existsSync(withExt)) {
53585
+ if (absoluteSourceFiles.includes(withExt) || fs23.existsSync(withExt)) {
53572
53586
  resolvedImport = withExt;
53573
53587
  break;
53574
53588
  }
@@ -53577,12 +53591,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
53577
53591
  } else {
53578
53592
  continue;
53579
53593
  }
53580
- const importBasename = path46.basename(resolvedImport, path46.extname(resolvedImport));
53581
- const importDir = path46.dirname(resolvedImport);
53594
+ const importBasename = path45.basename(resolvedImport, path45.extname(resolvedImport));
53595
+ const importDir = path45.dirname(resolvedImport);
53582
53596
  for (const sourceFile of absoluteSourceFiles) {
53583
- const sourceDir = path46.dirname(sourceFile);
53584
- const sourceBasename = path46.basename(sourceFile, path46.extname(sourceFile));
53585
- const isRelatedDir = importDir === sourceDir || importDir === path46.join(sourceDir, "__tests__") || importDir === path46.join(sourceDir, "tests") || importDir === path46.join(sourceDir, "test") || importDir === path46.join(sourceDir, "spec");
53597
+ const sourceDir = path45.dirname(sourceFile);
53598
+ const sourceBasename = path45.basename(sourceFile, path45.extname(sourceFile));
53599
+ const isRelatedDir = importDir === sourceDir || importDir === path45.join(sourceDir, "__tests__") || importDir === path45.join(sourceDir, "tests") || importDir === path45.join(sourceDir, "test") || importDir === path45.join(sourceDir, "spec");
53586
53600
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
53587
53601
  dedupePush(testFiles, testFile);
53588
53602
  break;
@@ -53595,8 +53609,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
53595
53609
  while (match !== null) {
53596
53610
  const importPath = match[1];
53597
53611
  if (importPath.startsWith(".")) {
53598
- let resolvedImport = path46.resolve(testDir, importPath);
53599
- const existingExt = path46.extname(resolvedImport);
53612
+ let resolvedImport = path45.resolve(testDir, importPath);
53613
+ const existingExt = path45.extname(resolvedImport);
53600
53614
  if (!existingExt) {
53601
53615
  for (const extToTry of [
53602
53616
  ".ts",
@@ -53607,18 +53621,18 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
53607
53621
  ".cjs"
53608
53622
  ]) {
53609
53623
  const withExt = resolvedImport + extToTry;
53610
- if (absoluteSourceFiles.includes(withExt) || fs24.existsSync(withExt)) {
53624
+ if (absoluteSourceFiles.includes(withExt) || fs23.existsSync(withExt)) {
53611
53625
  resolvedImport = withExt;
53612
53626
  break;
53613
53627
  }
53614
53628
  }
53615
53629
  }
53616
- const importDir = path46.dirname(resolvedImport);
53617
- const importBasename = path46.basename(resolvedImport, path46.extname(resolvedImport));
53630
+ const importDir = path45.dirname(resolvedImport);
53631
+ const importBasename = path45.basename(resolvedImport, path45.extname(resolvedImport));
53618
53632
  for (const sourceFile of absoluteSourceFiles) {
53619
- const sourceDir = path46.dirname(sourceFile);
53620
- const sourceBasename = path46.basename(sourceFile, path46.extname(sourceFile));
53621
- const isRelatedDir = importDir === sourceDir || importDir === path46.join(sourceDir, "__tests__") || importDir === path46.join(sourceDir, "tests") || importDir === path46.join(sourceDir, "test") || importDir === path46.join(sourceDir, "spec");
53633
+ const sourceDir = path45.dirname(sourceFile);
53634
+ const sourceBasename = path45.basename(sourceFile, path45.extname(sourceFile));
53635
+ const isRelatedDir = importDir === sourceDir || importDir === path45.join(sourceDir, "__tests__") || importDir === path45.join(sourceDir, "tests") || importDir === path45.join(sourceDir, "test") || importDir === path45.join(sourceDir, "spec");
53622
53636
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
53623
53637
  dedupePush(testFiles, testFile);
53624
53638
  break;
@@ -53728,8 +53742,8 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
53728
53742
  return ["mvn", "test"];
53729
53743
  case "gradle": {
53730
53744
  const isWindows = process.platform === "win32";
53731
- const hasGradlewBat = fs24.existsSync(path46.join(baseDir, "gradlew.bat"));
53732
- const hasGradlew = fs24.existsSync(path46.join(baseDir, "gradlew"));
53745
+ const hasGradlewBat = fs23.existsSync(path45.join(baseDir, "gradlew.bat"));
53746
+ const hasGradlew = fs23.existsSync(path45.join(baseDir, "gradlew"));
53733
53747
  if (hasGradlewBat && isWindows)
53734
53748
  return ["gradlew.bat", "test"];
53735
53749
  if (hasGradlew)
@@ -53746,7 +53760,7 @@ function buildTestCommand2(framework, scope, files, coverage, baseDir) {
53746
53760
  "cmake-build-release",
53747
53761
  "out"
53748
53762
  ];
53749
- const actualBuildDir = buildDirCandidates.find((d) => fs24.existsSync(path46.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
53763
+ const actualBuildDir = buildDirCandidates.find((d) => fs23.existsSync(path45.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
53750
53764
  return ["ctest", "--test-dir", actualBuildDir];
53751
53765
  }
53752
53766
  case "swift-test":
@@ -54178,13 +54192,13 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
54178
54192
  };
54179
54193
  }
54180
54194
  const startTime = Date.now();
54181
- const vitestJsonOutputPath = framework === "vitest" ? path46.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
54195
+ const vitestJsonOutputPath = framework === "vitest" ? path45.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
54182
54196
  try {
54183
54197
  if (vitestJsonOutputPath) {
54184
54198
  try {
54185
- fs24.mkdirSync(path46.dirname(vitestJsonOutputPath), { recursive: true });
54186
- if (fs24.existsSync(vitestJsonOutputPath)) {
54187
- fs24.unlinkSync(vitestJsonOutputPath);
54199
+ fs23.mkdirSync(path45.dirname(vitestJsonOutputPath), { recursive: true });
54200
+ if (fs23.existsSync(vitestJsonOutputPath)) {
54201
+ fs23.unlinkSync(vitestJsonOutputPath);
54188
54202
  }
54189
54203
  } catch {}
54190
54204
  }
@@ -54193,9 +54207,9 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
54193
54207
  stderr: "pipe",
54194
54208
  cwd
54195
54209
  });
54196
- const timeoutPromise = new Promise((resolve17) => setTimeout(() => {
54210
+ const timeoutPromise = new Promise((resolve16) => setTimeout(() => {
54197
54211
  proc.kill();
54198
- resolve17(-1);
54212
+ resolve16(-1);
54199
54213
  }, timeout_ms));
54200
54214
  const [exitCode, stdoutResult, stderrResult] = await Promise.all([
54201
54215
  Promise.race([proc.exited, timeoutPromise]),
@@ -54210,8 +54224,8 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
54210
54224
  }
54211
54225
  if (vitestJsonOutputPath) {
54212
54226
  try {
54213
- if (fs24.existsSync(vitestJsonOutputPath)) {
54214
- const vitestJsonOutput = fs24.readFileSync(vitestJsonOutputPath, "utf-8");
54227
+ if (fs23.existsSync(vitestJsonOutputPath)) {
54228
+ const vitestJsonOutput = fs23.readFileSync(vitestJsonOutputPath, "utf-8");
54215
54229
  if (vitestJsonOutput.trim().length > 0) {
54216
54230
  output += (output ? `
54217
54231
  ` : "") + vitestJsonOutput;
@@ -54298,10 +54312,10 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd) {
54298
54312
  }
54299
54313
  function normalizeHistoryTestFile(testFile, workingDir) {
54300
54314
  const normalized = testFile.replace(/\\/g, "/");
54301
- if (!path46.isAbsolute(testFile))
54315
+ if (!path45.isAbsolute(testFile))
54302
54316
  return normalized;
54303
- const relative9 = path46.relative(workingDir, testFile);
54304
- if (relative9.startsWith("..") || path46.isAbsolute(relative9)) {
54317
+ const relative9 = path45.relative(workingDir, testFile);
54318
+ if (relative9.startsWith("..") || path45.isAbsolute(relative9)) {
54305
54319
  return normalized;
54306
54320
  }
54307
54321
  return relative9.replace(/\\/g, "/");
@@ -54639,7 +54653,7 @@ var init_test_runner = __esm(() => {
54639
54653
  const sourceFiles = args.files.filter((file3) => {
54640
54654
  if (directTestFiles.includes(file3))
54641
54655
  return false;
54642
- const ext = path46.extname(file3).toLowerCase();
54656
+ const ext = path45.extname(file3).toLowerCase();
54643
54657
  return SOURCE_EXTENSIONS.has(ext);
54644
54658
  });
54645
54659
  const invalidFiles = args.files.filter((file3) => !directTestFiles.includes(file3) && !sourceFiles.includes(file3));
@@ -54685,7 +54699,7 @@ var init_test_runner = __esm(() => {
54685
54699
  if (isConventionTestFilePath(f)) {
54686
54700
  return false;
54687
54701
  }
54688
- const ext = path46.extname(f).toLowerCase();
54702
+ const ext = path45.extname(f).toLowerCase();
54689
54703
  return SOURCE_EXTENSIONS.has(ext);
54690
54704
  });
54691
54705
  if (sourceFiles.length === 0) {
@@ -54735,7 +54749,7 @@ var init_test_runner = __esm(() => {
54735
54749
  if (isConventionTestFilePath(f)) {
54736
54750
  return false;
54737
54751
  }
54738
- const ext = path46.extname(f).toLowerCase();
54752
+ const ext = path45.extname(f).toLowerCase();
54739
54753
  return SOURCE_EXTENSIONS.has(ext);
54740
54754
  });
54741
54755
  if (sourceFiles.length === 0) {
@@ -54787,8 +54801,8 @@ var init_test_runner = __esm(() => {
54787
54801
  }
54788
54802
  if (impactResult.impactedTests.length > 0) {
54789
54803
  testFiles = impactResult.impactedTests.map((absPath) => {
54790
- const relativePath = path46.relative(workingDir, absPath);
54791
- return path46.isAbsolute(relativePath) ? absPath : relativePath;
54804
+ const relativePath = path45.relative(workingDir, absPath);
54805
+ return path45.isAbsolute(relativePath) ? absPath : relativePath;
54792
54806
  });
54793
54807
  } else {
54794
54808
  graphFallbackReason = "no impacted tests found via impact analysis, falling back to graph";
@@ -54863,8 +54877,8 @@ var init_test_runner = __esm(() => {
54863
54877
  });
54864
54878
 
54865
54879
  // src/services/preflight-service.ts
54866
- import * as fs25 from "fs";
54867
- import * as path47 from "path";
54880
+ import * as fs24 from "fs";
54881
+ import * as path46 from "path";
54868
54882
  function validateDirectoryPath(dir) {
54869
54883
  if (!dir || typeof dir !== "string") {
54870
54884
  throw new Error("Directory path is required");
@@ -54872,8 +54886,8 @@ function validateDirectoryPath(dir) {
54872
54886
  if (dir.includes("..")) {
54873
54887
  throw new Error("Directory path must not contain path traversal sequences");
54874
54888
  }
54875
- const normalized = path47.normalize(dir);
54876
- const absolutePath = path47.isAbsolute(normalized) ? normalized : path47.resolve(normalized);
54889
+ const normalized = path46.normalize(dir);
54890
+ const absolutePath = path46.isAbsolute(normalized) ? normalized : path46.resolve(normalized);
54877
54891
  return absolutePath;
54878
54892
  }
54879
54893
  function validateTimeout(timeoutMs, defaultValue) {
@@ -54896,9 +54910,9 @@ function validateTimeout(timeoutMs, defaultValue) {
54896
54910
  }
54897
54911
  function getPackageVersion(dir) {
54898
54912
  try {
54899
- const packagePath = path47.join(dir, "package.json");
54900
- if (fs25.existsSync(packagePath)) {
54901
- const content = fs25.readFileSync(packagePath, "utf-8");
54913
+ const packagePath = path46.join(dir, "package.json");
54914
+ if (fs24.existsSync(packagePath)) {
54915
+ const content = fs24.readFileSync(packagePath, "utf-8");
54902
54916
  const pkg = JSON.parse(content);
54903
54917
  return pkg.version ?? null;
54904
54918
  }
@@ -54907,9 +54921,9 @@ function getPackageVersion(dir) {
54907
54921
  }
54908
54922
  function getChangelogVersion(dir) {
54909
54923
  try {
54910
- const changelogPath = path47.join(dir, "CHANGELOG.md");
54911
- if (fs25.existsSync(changelogPath)) {
54912
- const content = fs25.readFileSync(changelogPath, "utf-8");
54924
+ const changelogPath = path46.join(dir, "CHANGELOG.md");
54925
+ if (fs24.existsSync(changelogPath)) {
54926
+ const content = fs24.readFileSync(changelogPath, "utf-8");
54913
54927
  const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
54914
54928
  if (match) {
54915
54929
  return match[1];
@@ -54921,10 +54935,10 @@ function getChangelogVersion(dir) {
54921
54935
  function getVersionFileVersion(dir) {
54922
54936
  const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
54923
54937
  for (const file3 of possibleFiles) {
54924
- const filePath = path47.join(dir, file3);
54925
- if (fs25.existsSync(filePath)) {
54938
+ const filePath = path46.join(dir, file3);
54939
+ if (fs24.existsSync(filePath)) {
54926
54940
  try {
54927
- const content = fs25.readFileSync(filePath, "utf-8").trim();
54941
+ const content = fs24.readFileSync(filePath, "utf-8").trim();
54928
54942
  const match = content.match(/(\d+\.\d+\.\d+)/);
54929
54943
  if (match) {
54930
54944
  return match[1];
@@ -55263,8 +55277,8 @@ async function runEvidenceCheck(dir) {
55263
55277
  async function runRequirementCoverageCheck(dir, currentPhase) {
55264
55278
  const startTime = Date.now();
55265
55279
  try {
55266
- const specPath = path47.join(dir, ".swarm", "spec.md");
55267
- if (!fs25.existsSync(specPath)) {
55280
+ const specPath = path46.join(dir, ".swarm", "spec.md");
55281
+ if (!fs24.existsSync(specPath)) {
55268
55282
  return {
55269
55283
  type: "req_coverage",
55270
55284
  status: "skip",
@@ -55742,13 +55756,13 @@ class CircuitBreaker {
55742
55756
  if (this.config.callTimeoutMs <= 0) {
55743
55757
  return fn();
55744
55758
  }
55745
- return new Promise((resolve18, reject) => {
55759
+ return new Promise((resolve17, reject) => {
55746
55760
  const timeout = setTimeout(() => {
55747
55761
  reject(new Error(`Call timeout after ${this.config.callTimeoutMs}ms`));
55748
55762
  }, this.config.callTimeoutMs);
55749
55763
  fn().then((result) => {
55750
55764
  clearTimeout(timeout);
55751
- resolve18(result);
55765
+ resolve17(result);
55752
55766
  }).catch((error93) => {
55753
55767
  clearTimeout(timeout);
55754
55768
  reject(error93);
@@ -56035,7 +56049,7 @@ var init_queue = __esm(() => {
56035
56049
 
56036
56050
  // src/background/worker.ts
56037
56051
  function sleep(ms) {
56038
- return new Promise((resolve18) => setTimeout(resolve18, ms));
56052
+ return new Promise((resolve17) => setTimeout(resolve17, ms));
56039
56053
  }
56040
56054
 
56041
56055
  class WorkerManager {
@@ -56380,8 +56394,8 @@ var init_manager3 = __esm(() => {
56380
56394
  });
56381
56395
 
56382
56396
  // src/commands/reset.ts
56383
- import * as fs26 from "fs";
56384
- import * as path48 from "path";
56397
+ import * as fs25 from "fs";
56398
+ import * as path47 from "path";
56385
56399
  async function handleResetCommand(directory, args) {
56386
56400
  const hasConfirm = args.includes("--confirm");
56387
56401
  if (!hasConfirm) {
@@ -56409,8 +56423,8 @@ async function handleResetCommand(directory, args) {
56409
56423
  for (const filename of filesToReset) {
56410
56424
  try {
56411
56425
  const resolvedPath = validateSwarmPath(directory, filename);
56412
- if (fs26.existsSync(resolvedPath)) {
56413
- fs26.unlinkSync(resolvedPath);
56426
+ if (fs25.existsSync(resolvedPath)) {
56427
+ fs25.unlinkSync(resolvedPath);
56414
56428
  results.push(`- \u2705 Deleted ${filename}`);
56415
56429
  } else {
56416
56430
  results.push(`- \u23ED\uFE0F ${filename} not found (skipped)`);
@@ -56421,9 +56435,9 @@ async function handleResetCommand(directory, args) {
56421
56435
  }
56422
56436
  for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
56423
56437
  try {
56424
- const rootPath = path48.join(directory, filename);
56425
- if (fs26.existsSync(rootPath)) {
56426
- fs26.unlinkSync(rootPath);
56438
+ const rootPath = path47.join(directory, filename);
56439
+ if (fs25.existsSync(rootPath)) {
56440
+ fs25.unlinkSync(rootPath);
56427
56441
  results.push(`- \u2705 Deleted ${filename} (root)`);
56428
56442
  }
56429
56443
  } catch {}
@@ -56436,8 +56450,8 @@ async function handleResetCommand(directory, args) {
56436
56450
  }
56437
56451
  try {
56438
56452
  const summariesPath = validateSwarmPath(directory, "summaries");
56439
- if (fs26.existsSync(summariesPath)) {
56440
- fs26.rmSync(summariesPath, { recursive: true, force: true });
56453
+ if (fs25.existsSync(summariesPath)) {
56454
+ fs25.rmSync(summariesPath, { recursive: true, force: true });
56441
56455
  results.push("- \u2705 Deleted summaries/ directory");
56442
56456
  } else {
56443
56457
  results.push("- \u23ED\uFE0F summaries/ not found (skipped)");
@@ -56460,14 +56474,14 @@ var init_reset = __esm(() => {
56460
56474
  });
56461
56475
 
56462
56476
  // src/commands/reset-session.ts
56463
- import * as fs27 from "fs";
56464
- import * as path49 from "path";
56477
+ import * as fs26 from "fs";
56478
+ import * as path48 from "path";
56465
56479
  async function handleResetSessionCommand(directory, _args) {
56466
56480
  const results = [];
56467
56481
  try {
56468
56482
  const statePath = validateSwarmPath(directory, "session/state.json");
56469
- if (fs27.existsSync(statePath)) {
56470
- fs27.unlinkSync(statePath);
56483
+ if (fs26.existsSync(statePath)) {
56484
+ fs26.unlinkSync(statePath);
56471
56485
  results.push("\u2705 Deleted .swarm/session/state.json");
56472
56486
  } else {
56473
56487
  results.push("\u23ED\uFE0F state.json not found (already clean)");
@@ -56476,15 +56490,15 @@ async function handleResetSessionCommand(directory, _args) {
56476
56490
  results.push("\u274C Failed to delete state.json");
56477
56491
  }
56478
56492
  try {
56479
- const sessionDir = path49.dirname(validateSwarmPath(directory, "session/state.json"));
56480
- if (fs27.existsSync(sessionDir)) {
56481
- const files = fs27.readdirSync(sessionDir);
56493
+ const sessionDir = path48.dirname(validateSwarmPath(directory, "session/state.json"));
56494
+ if (fs26.existsSync(sessionDir)) {
56495
+ const files = fs26.readdirSync(sessionDir);
56482
56496
  const otherFiles = files.filter((f) => f !== "state.json");
56483
56497
  let deletedCount = 0;
56484
56498
  for (const file3 of otherFiles) {
56485
- const filePath = path49.join(sessionDir, file3);
56486
- if (fs27.lstatSync(filePath).isFile()) {
56487
- fs27.unlinkSync(filePath);
56499
+ const filePath = path48.join(sessionDir, file3);
56500
+ if (fs26.lstatSync(filePath).isFile()) {
56501
+ fs26.unlinkSync(filePath);
56488
56502
  deletedCount++;
56489
56503
  }
56490
56504
  }
@@ -56514,7 +56528,7 @@ var init_reset_session = __esm(() => {
56514
56528
  });
56515
56529
 
56516
56530
  // src/summaries/manager.ts
56517
- import * as path50 from "path";
56531
+ import * as path49 from "path";
56518
56532
  function sanitizeSummaryId(id) {
56519
56533
  if (!id || id.length === 0) {
56520
56534
  throw new Error("Invalid summary ID: empty string");
@@ -56537,7 +56551,7 @@ function sanitizeSummaryId(id) {
56537
56551
  }
56538
56552
  async function loadFullOutput(directory, id) {
56539
56553
  const sanitizedId = sanitizeSummaryId(id);
56540
- const relativePath = path50.join("summaries", `${sanitizedId}.json`);
56554
+ const relativePath = path49.join("summaries", `${sanitizedId}.json`);
56541
56555
  validateSwarmPath(directory, relativePath);
56542
56556
  const content = await readSwarmFileAsync(directory, relativePath);
56543
56557
  if (content === null) {
@@ -56599,18 +56613,18 @@ var init_retrieve = __esm(() => {
56599
56613
  });
56600
56614
 
56601
56615
  // src/commands/rollback.ts
56602
- import * as fs28 from "fs";
56603
- import * as path51 from "path";
56616
+ import * as fs27 from "fs";
56617
+ import * as path50 from "path";
56604
56618
  async function handleRollbackCommand(directory, args) {
56605
56619
  const phaseArg = args[0];
56606
56620
  if (!phaseArg) {
56607
56621
  const manifestPath2 = validateSwarmPath(directory, "checkpoints/manifest.json");
56608
- if (!fs28.existsSync(manifestPath2)) {
56622
+ if (!fs27.existsSync(manifestPath2)) {
56609
56623
  return "No checkpoints found. Use `/swarm checkpoint` to create checkpoints.";
56610
56624
  }
56611
56625
  let manifest2;
56612
56626
  try {
56613
- manifest2 = JSON.parse(fs28.readFileSync(manifestPath2, "utf-8"));
56627
+ manifest2 = JSON.parse(fs27.readFileSync(manifestPath2, "utf-8"));
56614
56628
  } catch {
56615
56629
  return "Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.";
56616
56630
  }
@@ -56632,12 +56646,12 @@ async function handleRollbackCommand(directory, args) {
56632
56646
  return "Error: Phase number must be a positive integer.";
56633
56647
  }
56634
56648
  const manifestPath = validateSwarmPath(directory, "checkpoints/manifest.json");
56635
- if (!fs28.existsSync(manifestPath)) {
56649
+ if (!fs27.existsSync(manifestPath)) {
56636
56650
  return `Error: No checkpoints found. Cannot rollback to phase ${targetPhase}.`;
56637
56651
  }
56638
56652
  let manifest;
56639
56653
  try {
56640
- manifest = JSON.parse(fs28.readFileSync(manifestPath, "utf-8"));
56654
+ manifest = JSON.parse(fs27.readFileSync(manifestPath, "utf-8"));
56641
56655
  } catch {
56642
56656
  return `Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.`;
56643
56657
  }
@@ -56647,10 +56661,10 @@ async function handleRollbackCommand(directory, args) {
56647
56661
  return `Error: Checkpoint for phase ${targetPhase} not found. Available phases: ${available}`;
56648
56662
  }
56649
56663
  const checkpointDir = validateSwarmPath(directory, `checkpoints/phase-${targetPhase}`);
56650
- if (!fs28.existsSync(checkpointDir)) {
56664
+ if (!fs27.existsSync(checkpointDir)) {
56651
56665
  return `Error: Checkpoint directory for phase ${targetPhase} does not exist.`;
56652
56666
  }
56653
- const checkpointFiles = fs28.readdirSync(checkpointDir);
56667
+ const checkpointFiles = fs27.readdirSync(checkpointDir);
56654
56668
  if (checkpointFiles.length === 0) {
56655
56669
  return `Error: Checkpoint for phase ${targetPhase} is empty. Cannot rollback.`;
56656
56670
  }
@@ -56665,10 +56679,10 @@ async function handleRollbackCommand(directory, args) {
56665
56679
  if (EXCLUDE_FILES.has(file3) || file3.startsWith("plan-ledger.archived-")) {
56666
56680
  continue;
56667
56681
  }
56668
- const src = path51.join(checkpointDir, file3);
56669
- const dest = path51.join(swarmDir, file3);
56682
+ const src = path50.join(checkpointDir, file3);
56683
+ const dest = path50.join(swarmDir, file3);
56670
56684
  try {
56671
- fs28.cpSync(src, dest, { recursive: true, force: true });
56685
+ fs27.cpSync(src, dest, { recursive: true, force: true });
56672
56686
  successes.push(file3);
56673
56687
  } catch (error93) {
56674
56688
  failures.push({ file: file3, error: error93.message });
@@ -56685,14 +56699,14 @@ async function handleRollbackCommand(directory, args) {
56685
56699
  ].join(`
56686
56700
  `);
56687
56701
  }
56688
- const existingLedgerPath = path51.join(swarmDir, "plan-ledger.jsonl");
56689
- if (fs28.existsSync(existingLedgerPath)) {
56690
- fs28.unlinkSync(existingLedgerPath);
56702
+ const existingLedgerPath = path50.join(swarmDir, "plan-ledger.jsonl");
56703
+ if (fs27.existsSync(existingLedgerPath)) {
56704
+ fs27.unlinkSync(existingLedgerPath);
56691
56705
  }
56692
56706
  try {
56693
- const planJsonPath = path51.join(swarmDir, "plan.json");
56694
- if (fs28.existsSync(planJsonPath)) {
56695
- const planRaw = fs28.readFileSync(planJsonPath, "utf-8");
56707
+ const planJsonPath = path50.join(swarmDir, "plan.json");
56708
+ if (fs27.existsSync(planJsonPath)) {
56709
+ const planRaw = fs27.readFileSync(planJsonPath, "utf-8");
56696
56710
  const plan = PlanSchema.parse(JSON.parse(planRaw));
56697
56711
  const planId = derivePlanId(plan);
56698
56712
  const planHash = computePlanHash(plan);
@@ -56719,7 +56733,7 @@ async function handleRollbackCommand(directory, args) {
56719
56733
  timestamp: new Date().toISOString()
56720
56734
  };
56721
56735
  try {
56722
- fs28.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
56736
+ fs27.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
56723
56737
  `);
56724
56738
  } catch (error93) {
56725
56739
  console.error("Failed to write rollback event:", error93 instanceof Error ? error93.message : String(error93));
@@ -56780,11 +56794,11 @@ Ensure this is a git repository with commit history.`;
56780
56794
  const report = reportLines.filter(Boolean).join(`
56781
56795
  `);
56782
56796
  try {
56783
- const fs29 = await import("fs/promises");
56784
- const path52 = await import("path");
56785
- const reportPath = path52.join(directory, ".swarm", "simulate-report.md");
56786
- await fs29.mkdir(path52.dirname(reportPath), { recursive: true });
56787
- await fs29.writeFile(reportPath, report, "utf-8");
56797
+ const fs28 = await import("fs/promises");
56798
+ const path51 = await import("path");
56799
+ const reportPath = path51.join(directory, ".swarm", "simulate-report.md");
56800
+ await fs28.mkdir(path51.dirname(reportPath), { recursive: true });
56801
+ await fs28.writeFile(reportPath, report, "utf-8");
56788
56802
  } catch (err) {
56789
56803
  const writeErr = err instanceof Error ? err.message : String(err);
56790
56804
  warn(`simulate: failed to write report to ${directory}/.swarm/simulate-report.md`, writeErr);
@@ -56806,15 +56820,15 @@ async function handleSpecifyCommand(_directory, args) {
56806
56820
  }
56807
56821
 
56808
56822
  // src/turbo/lean/state.ts
56809
- import * as fs29 from "fs";
56810
- import * as path52 from "path";
56823
+ import * as fs28 from "fs";
56824
+ import * as path51 from "path";
56811
56825
  function nowISO2() {
56812
56826
  return new Date().toISOString();
56813
56827
  }
56814
56828
  function ensureSwarmDir2(directory) {
56815
- const swarmDir = path52.resolve(directory, ".swarm");
56816
- if (!fs29.existsSync(swarmDir)) {
56817
- fs29.mkdirSync(swarmDir, { recursive: true });
56829
+ const swarmDir = path51.resolve(directory, ".swarm");
56830
+ if (!fs28.existsSync(swarmDir)) {
56831
+ fs28.mkdirSync(swarmDir, { recursive: true });
56818
56832
  }
56819
56833
  return swarmDir;
56820
56834
  }
@@ -56856,17 +56870,17 @@ function markStateUnreadable2(directory, reason) {
56856
56870
  }
56857
56871
  function readPersisted2(directory) {
56858
56872
  try {
56859
- const filePath = path52.join(directory, ".swarm", STATE_FILE2);
56860
- if (!fs29.existsSync(filePath)) {
56873
+ const filePath = path51.join(directory, ".swarm", STATE_FILE2);
56874
+ if (!fs28.existsSync(filePath)) {
56861
56875
  const seed = emptyPersisted2();
56862
56876
  try {
56863
56877
  ensureSwarmDir2(directory);
56864
- fs29.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
56878
+ fs28.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
56865
56879
  `, "utf-8");
56866
56880
  } catch {}
56867
56881
  return seed;
56868
56882
  }
56869
- const raw = fs29.readFileSync(filePath, "utf-8");
56883
+ const raw = fs28.readFileSync(filePath, "utf-8");
56870
56884
  const parsed = JSON.parse(raw);
56871
56885
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || parsed.version !== 1 || !parsed.sessions || typeof parsed.sessions !== "object" || Array.isArray(parsed.sessions)) {
56872
56886
  markStateUnreadable2(directory, `malformed shape (version=${parsed?.version}, sessions type=${Array.isArray(parsed?.sessions) ? "array" : typeof parsed?.sessions})`);
@@ -56892,7 +56906,7 @@ function writePersisted2(directory, persisted) {
56892
56906
  let payload;
56893
56907
  try {
56894
56908
  ensureSwarmDir2(directory);
56895
- filePath = path52.join(directory, ".swarm", STATE_FILE2);
56909
+ filePath = path51.join(directory, ".swarm", STATE_FILE2);
56896
56910
  tmpPath = `${filePath}.tmp.${Date.now()}`;
56897
56911
  persisted.updatedAt = nowISO2();
56898
56912
  payload = `${JSON.stringify(persisted, null, 2)}
@@ -56903,14 +56917,14 @@ function writePersisted2(directory, persisted) {
56903
56917
  throw new Error(`Lean Turbo state persistence prepare failed: ${msg}`);
56904
56918
  }
56905
56919
  try {
56906
- fs29.writeFileSync(tmpPath, payload, "utf-8");
56907
- fs29.renameSync(tmpPath, filePath);
56920
+ fs28.writeFileSync(tmpPath, payload, "utf-8");
56921
+ fs28.renameSync(tmpPath, filePath);
56908
56922
  } catch (error93) {
56909
56923
  const msg = error93 instanceof Error ? error93.message : String(error93);
56910
56924
  error(`[turbo/lean/state] Failed to persist ${STATE_FILE2} atomically: ${msg}`);
56911
56925
  try {
56912
- if (fs29.existsSync(tmpPath)) {
56913
- fs29.unlinkSync(tmpPath);
56926
+ if (fs28.existsSync(tmpPath)) {
56927
+ fs28.unlinkSync(tmpPath);
56914
56928
  }
56915
56929
  } catch {}
56916
56930
  throw new Error(`Lean Turbo state persistence failed: ${msg}`);
@@ -57019,10 +57033,10 @@ var init_context_budget_service = __esm(() => {
57019
57033
 
57020
57034
  // src/services/status-service.ts
57021
57035
  import * as fsSync2 from "fs";
57022
- import * as path53 from "path";
57036
+ import * as path52 from "path";
57023
57037
  function readSpecStalenessSnapshot(directory) {
57024
57038
  try {
57025
- const p = path53.join(directory, ".swarm", "spec-staleness.json");
57039
+ const p = path52.join(directory, ".swarm", "spec-staleness.json");
57026
57040
  if (!fsSync2.existsSync(p))
57027
57041
  return { stale: false };
57028
57042
  const raw = fsSync2.readFileSync(p, "utf-8");
@@ -57547,8 +57561,8 @@ var init_write_retro2 = __esm(() => {
57547
57561
  });
57548
57562
 
57549
57563
  // src/commands/command-dispatch.ts
57550
- import fs30 from "fs";
57551
- import path54 from "path";
57564
+ import fs29 from "fs";
57565
+ import path53 from "path";
57552
57566
  function normalizeSwarmCommandInput(command, argumentText) {
57553
57567
  if (command !== "swarm" && !command.startsWith("swarm-")) {
57554
57568
  return { isSwarmCommand: false, tokens: [] };
@@ -57584,11 +57598,11 @@ ${similar.map((cmd) => ` - /swarm ${cmd}`).join(`
57584
57598
  `);
57585
57599
  }
57586
57600
  function maybeMarkFirstRun(directory) {
57587
- const sentinelPath = path54.join(directory, ".swarm", ".first-run-complete");
57601
+ const sentinelPath = path53.join(directory, ".swarm", ".first-run-complete");
57588
57602
  try {
57589
- const swarmDir = path54.join(directory, ".swarm");
57590
- fs30.mkdirSync(swarmDir, { recursive: true });
57591
- fs30.writeFileSync(sentinelPath, `first-run-complete: ${new Date().toISOString()}
57603
+ const swarmDir = path53.join(directory, ".swarm");
57604
+ fs29.mkdirSync(swarmDir, { recursive: true });
57605
+ fs29.writeFileSync(sentinelPath, `first-run-complete: ${new Date().toISOString()}
57592
57606
  `, { flag: "wx" });
57593
57607
  return true;
57594
57608
  } catch {
@@ -58323,24 +58337,24 @@ function validateAliases() {
58323
58337
  }
58324
58338
  aliasTargets.get(target).push(name);
58325
58339
  const visited = new Set;
58326
- const path55 = [];
58340
+ const path54 = [];
58327
58341
  let current = target;
58328
58342
  while (current) {
58329
58343
  const currentEntry = COMMAND_REGISTRY[current];
58330
58344
  if (!currentEntry)
58331
58345
  break;
58332
58346
  if (visited.has(current)) {
58333
- const cycleStart = path55.indexOf(current);
58347
+ const cycleStart = path54.indexOf(current);
58334
58348
  const fullChain = [
58335
58349
  name,
58336
- ...path55.slice(0, cycleStart > 0 ? cycleStart : path55.length),
58350
+ ...path54.slice(0, cycleStart > 0 ? cycleStart : path54.length),
58337
58351
  current
58338
58352
  ].join(" \u2192 ");
58339
58353
  errors5.push(`Circular alias detected: ${fullChain}`);
58340
58354
  break;
58341
58355
  }
58342
58356
  visited.add(current);
58343
- path55.push(current);
58357
+ path54.push(current);
58344
58358
  current = currentEntry.aliasOf || "";
58345
58359
  }
58346
58360
  }
@@ -58951,68 +58965,68 @@ init_package();
58951
58965
  init_registry();
58952
58966
  init_cache_paths();
58953
58967
  init_constants();
58954
- import * as fs31 from "fs";
58968
+ import * as fs30 from "fs";
58955
58969
  import * as os8 from "os";
58956
- import * as path55 from "path";
58970
+ import * as path54 from "path";
58957
58971
  var { version: version5 } = package_default;
58958
58972
  var CONFIG_DIR = getPluginConfigDir();
58959
- var OPENCODE_CONFIG_PATH = path55.join(CONFIG_DIR, "opencode.json");
58960
- var PLUGIN_CONFIG_PATH = path55.join(CONFIG_DIR, "opencode-swarm.json");
58961
- var PROMPTS_DIR = path55.join(CONFIG_DIR, "opencode-swarm");
58973
+ var OPENCODE_CONFIG_PATH = path54.join(CONFIG_DIR, "opencode.json");
58974
+ var PLUGIN_CONFIG_PATH = path54.join(CONFIG_DIR, "opencode-swarm.json");
58975
+ var PROMPTS_DIR = path54.join(CONFIG_DIR, "opencode-swarm");
58962
58976
  var OPENCODE_PLUGIN_CACHE_PATHS = getPluginCachePaths();
58963
58977
  var OPENCODE_PLUGIN_LOCK_FILE_PATHS = getPluginLockFilePaths();
58964
58978
  function isSafeCachePath(p) {
58965
- const resolved = path55.resolve(p);
58966
- const home = path55.resolve(os8.homedir());
58979
+ const resolved = path54.resolve(p);
58980
+ const home = path54.resolve(os8.homedir());
58967
58981
  if (resolved === "/" || resolved === home || resolved.length <= home.length) {
58968
58982
  return false;
58969
58983
  }
58970
- const segments = resolved.split(path55.sep).filter((s) => s.length > 0);
58984
+ const segments = resolved.split(path54.sep).filter((s) => s.length > 0);
58971
58985
  if (segments.length < 4) {
58972
58986
  return false;
58973
58987
  }
58974
- const leaf = path55.basename(resolved);
58988
+ const leaf = path54.basename(resolved);
58975
58989
  if (leaf !== "opencode-swarm@latest" && leaf !== "opencode-swarm") {
58976
58990
  return false;
58977
58991
  }
58978
- const parent = path55.basename(path55.dirname(resolved));
58992
+ const parent = path54.basename(path54.dirname(resolved));
58979
58993
  if (parent !== "packages" && parent !== "node_modules") {
58980
58994
  return false;
58981
58995
  }
58982
- const grandparent = path55.basename(path55.dirname(path55.dirname(resolved)));
58996
+ const grandparent = path54.basename(path54.dirname(path54.dirname(resolved)));
58983
58997
  if (grandparent !== "opencode") {
58984
58998
  return false;
58985
58999
  }
58986
59000
  return true;
58987
59001
  }
58988
59002
  function isSafeLockFilePath(p) {
58989
- const resolved = path55.resolve(p);
58990
- const home = path55.resolve(os8.homedir());
59003
+ const resolved = path54.resolve(p);
59004
+ const home = path54.resolve(os8.homedir());
58991
59005
  if (resolved === "/" || resolved === home || resolved.length <= home.length) {
58992
59006
  return false;
58993
59007
  }
58994
- const segments = resolved.split(path55.sep).filter((s) => s.length > 0);
59008
+ const segments = resolved.split(path54.sep).filter((s) => s.length > 0);
58995
59009
  if (segments.length < 4) {
58996
59010
  return false;
58997
59011
  }
58998
- const leaf = path55.basename(resolved);
59012
+ const leaf = path54.basename(resolved);
58999
59013
  if (leaf !== "bun.lock" && leaf !== "bun.lockb" && leaf !== "package-lock.json") {
59000
59014
  return false;
59001
59015
  }
59002
- const parent = path55.basename(path55.dirname(resolved));
59016
+ const parent = path54.basename(path54.dirname(resolved));
59003
59017
  if (parent !== "opencode") {
59004
59018
  return false;
59005
59019
  }
59006
59020
  return true;
59007
59021
  }
59008
59022
  function ensureDir(dir) {
59009
- if (!fs31.existsSync(dir)) {
59010
- fs31.mkdirSync(dir, { recursive: true });
59023
+ if (!fs30.existsSync(dir)) {
59024
+ fs30.mkdirSync(dir, { recursive: true });
59011
59025
  }
59012
59026
  }
59013
59027
  function loadJson(filepath) {
59014
59028
  try {
59015
- const content = fs31.readFileSync(filepath, "utf-8");
59029
+ const content = fs30.readFileSync(filepath, "utf-8");
59016
59030
  const stripped = content.replace(/\\"|"(?:\\"|[^"])*"|(\/\/.*|\/\*[\s\S]*?\*\/)/g, (match, comment) => comment ? "" : match).replace(/,(\s*[}\]])/g, "$1");
59017
59031
  return JSON.parse(stripped);
59018
59032
  } catch {
@@ -59020,14 +59034,14 @@ function loadJson(filepath) {
59020
59034
  }
59021
59035
  }
59022
59036
  function saveJson(filepath, data) {
59023
- fs31.writeFileSync(filepath, `${JSON.stringify(data, null, 2)}
59037
+ fs30.writeFileSync(filepath, `${JSON.stringify(data, null, 2)}
59024
59038
  `, "utf-8");
59025
59039
  }
59026
59040
  function writeProjectConfigIfMissing(cwd) {
59027
59041
  try {
59028
- const opencodeDir = path55.join(cwd, ".opencode");
59029
- const projectConfigPath = path55.join(opencodeDir, "opencode-swarm.json");
59030
- if (fs31.existsSync(projectConfigPath)) {
59042
+ const opencodeDir = path54.join(cwd, ".opencode");
59043
+ const projectConfigPath = path54.join(opencodeDir, "opencode-swarm.json");
59044
+ if (fs30.existsSync(projectConfigPath)) {
59031
59045
  return;
59032
59046
  }
59033
59047
  ensureDir(opencodeDir);
@@ -59043,7 +59057,7 @@ async function install() {
59043
59057
  `);
59044
59058
  ensureDir(CONFIG_DIR);
59045
59059
  ensureDir(PROMPTS_DIR);
59046
- const LEGACY_CONFIG_PATH = path55.join(CONFIG_DIR, "config.json");
59060
+ const LEGACY_CONFIG_PATH = path54.join(CONFIG_DIR, "config.json");
59047
59061
  let opencodeConfig = loadJson(OPENCODE_CONFIG_PATH);
59048
59062
  if (!opencodeConfig) {
59049
59063
  const legacyConfig = loadJson(LEGACY_CONFIG_PATH);
@@ -59090,7 +59104,7 @@ async function install() {
59090
59104
  console.warn(`\u26A0 Could not clear opencode lock file \u2014 you may need to delete it manually:
59091
59105
  ${failed}`);
59092
59106
  }
59093
- if (!fs31.existsSync(PLUGIN_CONFIG_PATH)) {
59107
+ if (!fs30.existsSync(PLUGIN_CONFIG_PATH)) {
59094
59108
  const defaultConfig = {
59095
59109
  agents: { ...DEFAULT_AGENT_CONFIGS },
59096
59110
  max_iterations: 5
@@ -59169,14 +59183,14 @@ function evictPluginCaches() {
59169
59183
  const cleared = [];
59170
59184
  const failed = [];
59171
59185
  for (const cachePath of OPENCODE_PLUGIN_CACHE_PATHS) {
59172
- if (!fs31.existsSync(cachePath))
59186
+ if (!fs30.existsSync(cachePath))
59173
59187
  continue;
59174
59188
  if (!isSafeCachePath(cachePath)) {
59175
59189
  failed.push(`${cachePath} (refused: failed safety check)`);
59176
59190
  continue;
59177
59191
  }
59178
59192
  try {
59179
- fs31.rmSync(cachePath, { recursive: true, force: true });
59193
+ fs30.rmSync(cachePath, { recursive: true, force: true });
59180
59194
  cleared.push(cachePath);
59181
59195
  } catch (err) {
59182
59196
  failed.push(`${cachePath} (${err instanceof Error ? err.message : String(err)})`);
@@ -59188,14 +59202,14 @@ function evictLockFiles() {
59188
59202
  const cleared = [];
59189
59203
  const failed = [];
59190
59204
  for (const lockPath of OPENCODE_PLUGIN_LOCK_FILE_PATHS) {
59191
- if (!fs31.existsSync(lockPath))
59205
+ if (!fs30.existsSync(lockPath))
59192
59206
  continue;
59193
59207
  if (!isSafeLockFilePath(lockPath)) {
59194
59208
  failed.push(`${lockPath} (refused: failed safety check)`);
59195
59209
  continue;
59196
59210
  }
59197
59211
  try {
59198
- fs31.unlinkSync(lockPath);
59212
+ fs30.unlinkSync(lockPath);
59199
59213
  cleared.push(lockPath);
59200
59214
  } catch (err) {
59201
59215
  const code = err?.code;
@@ -59214,7 +59228,7 @@ async function uninstall() {
59214
59228
  `);
59215
59229
  const opencodeConfig = loadJson(OPENCODE_CONFIG_PATH);
59216
59230
  if (!opencodeConfig) {
59217
- if (fs31.existsSync(OPENCODE_CONFIG_PATH)) {
59231
+ if (fs30.existsSync(OPENCODE_CONFIG_PATH)) {
59218
59232
  console.log(`\u2717 Could not parse opencode config at: ${OPENCODE_CONFIG_PATH}`);
59219
59233
  return 1;
59220
59234
  } else {
@@ -59246,13 +59260,13 @@ async function uninstall() {
59246
59260
  console.log("\u2713 Re-enabled default OpenCode agents (explore, general)");
59247
59261
  if (process.argv.includes("--clean")) {
59248
59262
  let cleaned = false;
59249
- if (fs31.existsSync(PLUGIN_CONFIG_PATH)) {
59250
- fs31.unlinkSync(PLUGIN_CONFIG_PATH);
59263
+ if (fs30.existsSync(PLUGIN_CONFIG_PATH)) {
59264
+ fs30.unlinkSync(PLUGIN_CONFIG_PATH);
59251
59265
  console.log(`\u2713 Removed plugin config: ${PLUGIN_CONFIG_PATH}`);
59252
59266
  cleaned = true;
59253
59267
  }
59254
- if (fs31.existsSync(PROMPTS_DIR)) {
59255
- fs31.rmSync(PROMPTS_DIR, { recursive: true });
59268
+ if (fs30.existsSync(PROMPTS_DIR)) {
59269
+ fs30.rmSync(PROMPTS_DIR, { recursive: true });
59256
59270
  console.log(`\u2713 Removed custom prompts: ${PROMPTS_DIR}`);
59257
59271
  cleaned = true;
59258
59272
  }