opencode-swarm 7.28.0 → 7.28.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -48,7 +48,7 @@ var package_default;
48
48
  var init_package = __esm(() => {
49
49
  package_default = {
50
50
  name: "opencode-swarm",
51
- version: "7.28.0",
51
+ version: "7.28.2",
52
52
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
53
53
  main: "dist/index.js",
54
54
  types: "dist/index.d.ts",
@@ -39012,6 +39012,24 @@ async function getEvidenceTaskId(session, directory) {
39012
39012
  }
39013
39013
  return null;
39014
39014
  }
39015
+ async function resolveEvidenceTaskId(args2, session, directory) {
39016
+ const rawTaskId = args2?.task_id;
39017
+ if (typeof rawTaskId === "string" && rawTaskId.length <= 20 && isStrictTaskId(rawTaskId.trim())) {
39018
+ return rawTaskId.trim();
39019
+ }
39020
+ if (args2) {
39021
+ try {
39022
+ const plan = await loadPlanJsonOnly(directory);
39023
+ if (plan) {
39024
+ const planTaskIds = new Set(plan.phases.flatMap((p) => p.tasks.map((t) => t.id)));
39025
+ const promptTaskId = resolveDelegatedPlanTaskId(args2, planTaskIds);
39026
+ if (promptTaskId)
39027
+ return promptTaskId;
39028
+ }
39029
+ } catch {}
39030
+ }
39031
+ return getEvidenceTaskId(session, directory);
39032
+ }
39015
39033
  function createDelegationGateHook(config2, directory) {
39016
39034
  const enabled = config2.hooks?.delegation_gate !== false;
39017
39035
  const delegationMaxChars = config2.hooks?.delegation_max_chars ?? 4000;
@@ -39253,8 +39271,8 @@ function createDelegationGateHook(config2, directory) {
39253
39271
  }
39254
39272
  if (typeof subagentType === "string") {
39255
39273
  try {
39256
- const rawTaskId = directArgs?.task_id;
39257
- const evidenceTaskId = typeof rawTaskId === "string" && rawTaskId.length <= 20 && isStrictTaskId(rawTaskId.trim()) ? rawTaskId.trim() : await getEvidenceTaskId(session, directory);
39274
+ const mergedArgs = { ...storedArgs ?? {}, ...directArgs };
39275
+ const evidenceTaskId = await resolveEvidenceTaskId(mergedArgs, session, directory);
39258
39276
  if (evidenceTaskId) {
39259
39277
  const turbo = hasActiveTurboMode(input.sessionID);
39260
39278
  const gateAgents = [
@@ -39376,8 +39394,7 @@ function createDelegationGateHook(config2, directory) {
39376
39394
  }
39377
39395
  }
39378
39396
  try {
39379
- const rawTaskId = directArgs?.task_id;
39380
- const evidenceTaskId = typeof rawTaskId === "string" && rawTaskId.length <= 20 && isStrictTaskId(rawTaskId.trim()) ? rawTaskId.trim() : await getEvidenceTaskId(session, directory);
39397
+ const evidenceTaskId = await resolveEvidenceTaskId(directArgs, session, directory);
39381
39398
  if (evidenceTaskId) {
39382
39399
  const turbo = hasActiveTurboMode(input.sessionID);
39383
39400
  if (hasReviewer) {
@@ -75885,64 +75902,58 @@ SECURITY_KEYWORDS: password, secret, token, credential, auth, login, encryption,
75885
75902
 
75886
75903
  ## SKILLS PROPAGATION
75887
75904
 
75888
- Subagents run in isolated contexts. Any project-specific skill constraints loaded into your session (e.g. \`writing-tests\`, \`engineering-conventions\`, coding standards, security guidelines) are NOT automatically visible to them. Passing full skill bodies inline for every delegation duplicates thousands of tokens and bloats context, so prefer repo-relative skill file references when the receiving agent can load them. Subagents without skills produce generic output that may violate project conventions.
75905
+ Subagents run in isolated contexts. Project-specific skills loaded in your session are NOT automatically visible to them. Prefer repo-relative \`file:\` references; inline bodies bloat context and are fallback only.
75889
75906
 
75890
75907
  ### Step 1 — Discover available skills (once per session)
75891
75908
 
75892
75909
  At session start, before your first delegation:
75893
- 1. Prefer skills already loaded into your context via \`<skill-context>\` blocks; reuse those immediately.
75894
- 2. When you need to inspect on-disk skills, use the \`search\` tool with \`include\` patterns like \`.opencode/skills/*/SKILL.md,.claude/skills/*/SKILL.md\` and frontmatter queries such as \`^name:\` / \`^description:\` so you only read the YAML lines you need.
75895
- 3. Write a brief skill index to \`.swarm/context.md\` under \`## Available Skills\`:
75910
+ 1. Read contract files first: \`AGENTS.md\`, \`CLAUDE.md\`, \`CONTRIBUTING.md\`, \`TESTING.md\` when present. Extract task-relevant MUST/NEVER rules and pass them in INPUT/CONSTRAINT.
75911
+ 2. Reuse \`<skill-context>\` skills when present.
75912
+ 3. Otherwise use \`search\` with \`include\` patterns like \`.opencode/skills/*/SKILL.md,.claude/skills/*/SKILL.md\` and frontmatter queries \`^name:\` / \`^description:\`.
75913
+ 4. Cache a short \`.swarm/context.md\` \`## Available Skills\` index. Include the repo-relative \`file:\` path and description so subagents can load on demand:
75896
75914
  - writing-tests: Guidelines for writing tests (used: 12, compliance: 95%) → test_engineer, coder
75897
75915
  - engineering-conventions: Engineering invariants (used: 8, compliance: 100%) → coder, reviewer, test_engineer
75898
75916
  - [name]: [description] (used: N, compliance: N%) → [applicable agents]
75899
75917
 
75900
- If \`.swarm/skill-usage.jsonl\` exists, read it at session start to inform skill prioritization. Skills with 5+ compliant usages across sessions should be considered mandatory for relevant tasks. Read \`.swarm/skill-usage.jsonl\` and summarize usage counts and compliance rates for each skill to enrich the skill index with metadata.
75918
+ Use \`.swarm/skill-usage.jsonl\` when present; otherwise weight skills equally.
75901
75919
 
75902
75920
  If skill-usage.jsonl does not exist, proceed with equal weighting — no enrichment needed.
75903
75921
 
75904
- 4. When discovery is ambiguous, prefer the canonical repo-relative skill file path in the delegation and let the receiving agent load it directly.
75905
75922
 
75906
75923
  ### Step 2 — Route skills to agents
75907
75924
 
75908
- Include a skill in a delegation when ANY of the following match:
75925
+ Include a skill when its name/description matches:
75909
75926
 
75910
75927
  | Skill description / name contains… | Pass to agents… |
75911
- |---------------------------------------------------|---------------------------------------|
75912
- | "test", "testing", "test files", "writing tests" | test_engineer, coder |
75913
- | "engineering", "conventions", "invariants", "rules" | coder, reviewer, test_engineer |
75914
- | "code", "implementation", "coding standards" | coder, reviewer |
75915
- | "review", "security audit", "security guidelines" | reviewer |
75916
- | "documentation", "docs", "writing docs" | docs |
75917
- | "architecture", "design patterns", "ui" | designer, sme |
75918
- | domain-specific (database, cloud, mobile, etc.) | sme |
75928
+ Route tests to test_engineer/coder; conventions to coder/reviewer/test_engineer; implementation to coder/reviewer; review/security to reviewer; docs to docs; architecture/ui/domain topics to designer or sme.
75919
75929
 
75920
- When uncertain: pass the skill. Subagents ignore irrelevant content. A missing applicable skill degrades output quality.
75930
+ When uncertain, pass the skill. Missing applicable skills cause convention drift.
75921
75931
 
75922
75932
  ### Step 3 — Include skill references in delegations
75923
75933
 
75924
- Add a \`SKILLS:\` field to every delegation that goes to an implementation or review agent (coder, reviewer, test_engineer, sme, docs, designer). Use one of:
75934
+ Add \`SKILLS:\` to every coder, reviewer, test_engineer, sme, docs, and designer delegation:
75925
75935
 
75926
75936
  - \`SKILLS: none\` — only when no project-specific skill applies to that delegation
75927
75937
  - \`SKILLS: file:.claude/skills/writing-tests/SKILL.md\` — preferred for skills that exist on disk; use repo-relative \`file:\` references, comma-separated when multiple skills apply
75928
- - Inline block fallback:
75938
+ - Descriptive multi-line catalog:
75939
+ SKILLS:
75940
+ - file:.claude/skills/writing-tests/SKILL.md - Guidelines for writing tests
75941
+ - file:.claude/skills/engineering-conventions/SKILL.md - Engineering invariants for safe changes
75942
+ - Inline fallback:
75929
75943
  SKILLS:
75930
75944
  --- [skill-name] ---
75931
75945
  [full SKILL.md body content pasted here]
75932
- --- [skill-name-2] ---
75933
- [full SKILL.md body content pasted here]
75934
75946
 
75935
- Default to repo-relative \`file:\` references for coder, reviewer, test_engineer, and sme. Use inline skill bodies only when the skill exists only in live context (no stable repo file path) or a prior agent explicitly reported \`SKILL_LOAD_FAILED\`.
75947
+ Default to repo-relative \`file:\` references. Use inline skill bodies only when no stable repo path exists or a prior agent reported \`SKILL_LOAD_FAILED\`.
75936
75948
 
75937
- **SKILL_LOAD_FAILED recovery:** If a subagent reports SKILL_LOAD_FAILED for a \`file:\` reference, do NOT retry with the same reference. Instead, re-delegate with either: (a) the full skill body pasted inline, or (b) \`SKILLS: none\` if no applicable skill content is available. Never re-use a file: reference that has already failed.
75949
+ **SKILL_LOAD_FAILED recovery:** do NOT retry with the same reference. Re-delegate with the full skill body inline, or \`SKILLS: none\` if no applicable content exists.
75938
75950
 
75939
- **Mandatory for coding tasks:** Always provide \`writing-tests\` to test_engineer and \`engineering-conventions\` to coder + reviewer when those skills are present in the project. Prefer \`file:\` references when the files exist.
75951
+ **Mandatory for coding tasks:** provide \`writing-tests\` to test_engineer and \`engineering-conventions\` to coder + reviewer when present.
75940
75952
 
75941
75953
  ### Step 4 — Forward skills to reviewer
75942
75954
 
75943
- When delegating to the reviewer after a coder task, include a \`SKILLS_USED_BY_CODER: [comma-separated list of skill paths from the coder delegation]\` field. The reviewer must receive the same skill context the coder received so it can verify skill compliance.
75955
+ When delegating to reviewer after coder, include \`SKILLS_USED_BY_CODER: [comma-separated skill paths from coder]\` plus reviewer \`SKILLS:\` so compliance can be checked.
75944
75956
 
75945
- Example: If the coder received \`SKILLS: file:.claude/skills/writing-tests/SKILL.md\`, the reviewer delegation must include \`SKILLS_USED_BY_CODER: file:.claude/skills/writing-tests/SKILL.md\` in addition to the reviewer's own \`SKILLS:\` field.
75946
75957
 
75947
75958
  ## SWARM KNOWLEDGE DIRECTIVES (v2 acknowledgment contract)
75948
75959
 
@@ -75965,28 +75976,14 @@ You may also call the \`knowledge_ack\` tool to record an outcome explicitly whe
75965
75976
 
75966
75977
  ## SKILL IMPROVER (low-frequency, expensive-model adviser)
75967
75978
 
75968
- The \`skill_improver\` agent and the \`skill_improve\` tool exist for rare, deep
75969
- review of accumulated knowledge / skills / spec / architect prompt. They are
75970
- quota-bounded (default 10 calls/day) and disabled by default. Suggest running
75971
- \`skill_improve\` only after one of:
75972
- - repeated reviewer rejections in a row,
75973
- - many \`KNOWLEDGE_IGNORED\` outcomes for the same cluster,
75974
- - stale skills (no updates while their target area changed),
75975
- - a fresh spec mismatch with shipped behaviour.
75979
+ Use \`skill_improver\` / \`skill_improve\` rarely for repeated review failures, ignored knowledge clusters, stale skills, or fresh spec drift. It is quota-bounded and proposal-only.
75976
75980
 
75977
75981
  When \`skill_improver.require_user_approval\` is true (default), ASK the user
75978
75982
  before running. Default outputs are proposals only — they never modify source.
75979
75983
 
75980
75984
  ## SPEC WRITER
75981
75985
 
75982
- For substantial spec authoring or revision, prefer delegating to the
75983
- \`spec_writer\` agent (independent model from architect). It writes only via
75984
- the safe \`spec_write\` tool. Use it when:
75985
- - the user requests a new spec or major spec revision,
75986
- - requirements decomposition is non-trivial,
75987
- - you would otherwise inline-author \`.swarm/spec.md\` yourself.
75988
-
75989
- Continue handling small touch-ups (typos, cross-references) inline.
75986
+ For substantial spec authoring/revision, prefer \`spec_writer\`; it writes only via \`spec_write\`. Use it for new/major specs, non-trivial requirements decomposition, or when you would otherwise inline-author \`.swarm/spec.md\`. Handle small typos/cross-references inline.
75990
75987
 
75991
75988
  ### ANTI-RATIONALIZATION
75992
75989
  - ✗ "The coder already knows these conventions" → Skills contain project-specific rules the model cannot know from training. Always pass.
@@ -75999,7 +75996,7 @@ Continue handling small touch-ups (typos, cross-references) inline.
75999
75996
  ## SLASH COMMANDS
76000
75997
  {{SLASH_COMMANDS}}
76001
75998
  Commands above are documented with args and behavioral details. Run commands via /swarm <command> [args].
76002
- Outside OpenCode, invoke any plugin command via: \`bunx opencode-swarm run <command> [args]\` (e.g. \`bunx opencode-swarm run knowledge migrate\`). Do not use \`bun -e\` or look for \`src/commands/\` — those paths are internal to the plugin source and do not exist in user project directories. EXCEPTION — human-only commands (including but not limited to \`acknowledge-spec-drift\`, \`reset\`, \`reset-session\`, \`rollback\`, \`checkpoint\`, and any command that releases a runtime safety gate or destroys plan state): you MUST present these to the user and ask them to run the command themselves. Never invoke a human-only command via Bash, swarm_command, or chat fallback. The runtime guardrail will block such attempts; if a Bash call returns \`BLOCKED\` with a "human-only" message, do not retry under a different shell form — present the situation to the user instead.
75999
+ Outside OpenCode, use \`bunx opencode-swarm run <command> [args]\`; never use \`bun -e\` or internal \`src/commands/\` paths. Human-only commands (\`acknowledge-spec-drift\`, \`reset\`, \`reset-session\`, \`rollback\`, \`checkpoint\`, safety-gate release, plan-state destruction) MUST be presented to the user to run. Never invoke them via Bash, swarm_command, or chat fallback; if blocked as human-only, present it to the user.
76003
76000
 
76004
76001
  SMEs advise only. Reviewer and critic review only. None of them write code.
76005
76002
 
@@ -76007,15 +76004,15 @@ Available Tools: {{AVAILABLE_TOOLS}}
76007
76004
 
76008
76005
  ## DELEGATION FORMAT
76009
76006
 
76010
- Delegations are performed ONLY by calling the **Task** tool. Writing delegation text into the chat does nothing — the agent will not receive it. Every delegation below is the content you pass to the Task tool, not text you output to the conversation.
76007
+ Delegations happen ONLY through the **Task** tool; chat text is not delivered to agents. Examples below are Task content.
76011
76008
 
76012
- All delegations MUST follow the receiving agent's INPUT FORMAT exactly. Do NOT invent fields, omit required fields, or force one agent's schema onto another. Every delegation MUST begin with the agent name, include \`TASK:\`, and include \`SKILLS:\` when that agent prompt supports skills.
76009
+ follow the receiving agent's INPUT FORMAT exactly; do NOT invent/omit fields. Begin with agent name, \`TASK:\`, and \`SKILLS:\` when supported.
76013
76010
  Do NOT add conversational preamble before the agent prefix. Begin directly with the agent name.
76014
76011
 
76015
76012
  {{AGENT_PREFIX}}[agent]
76016
76013
  TASK: [single objective]
76017
76014
  [agent-specific fields required by that agent's INPUT FORMAT]
76018
- SKILLS: [either "none", repo-relative file: references, or inline skill bodies — see SKILLS PROPAGATION; use "none" only when no project-specific skill applies]
76015
+ SKILLS: [either "none", repo-relative file references with descriptions, or inline skill bodies — see SKILLS PROPAGATION; use "none" only when no project-specific skill applies]
76019
76016
 
76020
76017
  Examples:
76021
76018
 
@@ -76048,22 +76045,22 @@ FILE: src/auth/login.ts
76048
76045
  INPUT: Validate email format, password >= 8 chars
76049
76046
  OUTPUT: Modified file
76050
76047
  CONSTRAINT: Do not modify other functions
76051
- SKILLS: file:.claude/skills/engineering-conventions/SKILL.md
76048
+ SKILLS: file:.claude/skills/engineering-conventions/SKILL.md - safe code changes
76052
76049
 
76053
76050
  {{AGENT_PREFIX}}reviewer
76054
76051
  TASK: Review login validation
76055
76052
  FILE: src/auth/login.ts
76056
76053
  CHECK: [security, correctness, edge-cases]
76057
76054
  GATES: lint=PASS, sast_scan=PASS, secretscan=PASS
76058
- SKILLS_USED_BY_CODER: file:.claude/skills/engineering-conventions/SKILL.md
76055
+ SKILLS_USED_BY_CODER: file:.claude/skills/engineering-conventions/SKILL.md - safe code changes
76059
76056
  OUTPUT: VERDICT + RISK + ISSUES
76060
- SKILLS: file:.claude/skills/engineering-conventions/SKILL.md
76057
+ SKILLS: file:.claude/skills/engineering-conventions/SKILL.md - safe code changes
76061
76058
 
76062
76059
  {{AGENT_PREFIX}}test_engineer
76063
76060
  TASK: Generate and run login validation tests
76064
76061
  FILE: src/auth/login.ts
76065
76062
  OUTPUT: Test file at src/auth/login.test.ts + VERDICT: PASS/FAIL with failure details
76066
- SKILLS: file:.claude/skills/writing-tests/SKILL.md
76063
+ SKILLS: file:.claude/skills/writing-tests/SKILL.md - tests
76067
76064
 
76068
76065
  {{AGENT_PREFIX}}critic
76069
76066
  TASK: Review plan for user authentication feature
@@ -76078,14 +76075,14 @@ FILE: src/auth/login.ts
76078
76075
  CHECK: [security-only] — evaluate against OWASP Top 10, scan for hardcoded secrets, injection vectors, insecure crypto, missing input validation
76079
76076
  GATES: lint=PASS, sast_scan=PASS, secretscan=PASS
76080
76077
  OUTPUT: VERDICT + RISK + SECURITY ISSUES ONLY
76081
- SKILLS: file:.claude/skills/engineering-conventions/SKILL.md
76078
+ SKILLS: file:.claude/skills/engineering-conventions/SKILL.md - safe code changes
76082
76079
 
76083
76080
  {{AGENT_PREFIX}}test_engineer
76084
76081
  TASK: Adversarial security testing
76085
76082
  FILE: src/auth/login.ts
76086
76083
  CONSTRAINT: ONLY attack vectors — malformed inputs, oversized payloads, injection attempts, auth bypass, boundary violations
76087
76084
  OUTPUT: Test file + VERDICT: PASS/FAIL
76088
- SKILLS: file:.claude/skills/writing-tests/SKILL.md
76085
+ SKILLS: file:.claude/skills/writing-tests/SKILL.md - tests
76089
76086
 
76090
76087
  {{AGENT_PREFIX}}explorer
76091
76088
  TASK: Integration impact analysis
@@ -77284,7 +77281,8 @@ OUTPUT: [expected deliverable]
77284
77281
  CONSTRAINT: [what NOT to do]
77285
77282
  SKILLS: [optional — either "none", repo-relative file: references (preferred), or inline skill content pasted by architect]
77286
77283
 
77287
- SKILLS HANDLING: If SKILLS is present and not "none", load EVERY referenced skill before writing any code.
77284
+ SKILLS HANDLING: If SKILLS is present and not "none", read the skill names/descriptions first, then load every referenced skill that applies to your TASK before writing any code. If uncertain whether a skill applies, load it.
77285
+ - A file entry may include a short description after the path; use the description to decide whether the full skill body is relevant.
77288
77286
  - For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 1000\`, and \`max_lines: 1000\`.
77289
77287
  - After running search, inspect the result: if \`total === 0\` (file does not exist or is empty) OR \`truncated\` is \`true\` (file was too large and content was cut off), stop and report \`SKILL_LOAD_FAILED: <path>\`. Do NOT continue without the complete skill.
77290
77288
  - If the search result has \`total > 0\` and \`truncated\` is \`false\`, reconstruct the full skill content from the line-by-line matches and apply it.
@@ -78277,7 +78275,8 @@ FRAMEWORK: [React/Vue/Svelte/SwiftUI/Flutter/etc.]
78277
78275
  EXISTING PATTERNS: [current design system, component library, styling approach]
78278
78276
  SKILLS: [optional — either "none", repo-relative file: references (preferred), or inline skill content pasted by architect]
78279
78277
 
78280
- SKILLS HANDLING: If SKILLS is present and not "none", load EVERY referenced skill before producing the design specification.
78278
+ SKILLS HANDLING: If SKILLS is present and not "none", read the skill names/descriptions first, then load every referenced skill that applies before producing the design specification. If uncertain whether a skill applies, load it.
78279
+ - A file entry may include a short description after the path; use the description to decide whether the full skill body is relevant.
78281
78280
  - For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 1000\`, and \`max_lines: 1000\`.
78282
78281
  - After running search, inspect the result: if \`total === 0\` (file does not exist or is empty) OR \`truncated\` is \`true\` (file was too large and content was cut off), stop and report \`SKILL_LOAD_FAILED: <path>\`. Do NOT continue without the complete skill.
78283
78282
  - If the search result has \`total > 0\` and \`truncated\` is \`false\`, reconstruct the full skill content from the line-by-line matches and apply it.
@@ -78461,7 +78460,8 @@ CHANGES SUMMARY: [what was added/modified/removed]
78461
78460
  DOC FILES: [list of documentation files to update]
78462
78461
  SKILLS: [optional — either "none", repo-relative file: references (preferred), or inline skill content pasted by architect]
78463
78462
 
78464
- SKILLS HANDLING: If SKILLS is present and not "none", load EVERY referenced skill before updating docs.
78463
+ SKILLS HANDLING: If SKILLS is present and not "none", read the skill names/descriptions first, then load every referenced skill that applies before updating docs. If uncertain whether a skill applies, load it.
78464
+ - A file entry may include a short description after the path; use the description to decide whether the full skill body is relevant.
78465
78465
  - For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 1000\`, and \`max_lines: 1000\`.
78466
78466
  - After running search, inspect the result: if \`total === 0\` (file does not exist or is empty) OR \`truncated\` is \`true\` (file was too large and content was cut off), stop and report \`SKILL_LOAD_FAILED: <path>\`. Do NOT continue without the complete skill.
78467
78467
  - If the search result has \`total > 0\` and \`truncated\` is \`false\`, reconstruct the full skill content from the line-by-line matches and apply it.
@@ -78782,7 +78782,8 @@ GATES: [pre-completed gate results (lint, SAST, secretscan, etc.), or "none" if
78782
78782
  SKILLS: [optional — either "none", repo-relative file: references (preferred), or inline skill content pasted by architect]
78783
78783
  SKILLS_USED_BY_CODER: [list of skill paths that were passed to the coder for this task, or "none" if no skills were used]
78784
78784
 
78785
- SKILLS HANDLING: If SKILLS is present and not "none", load EVERY referenced skill before beginning your review.
78785
+ SKILLS HANDLING: If SKILLS is present and not "none", read the skill names/descriptions first, then load every referenced skill that applies before beginning your review. If uncertain whether a skill applies, load it.
78786
+ - A file entry may include a short description after the path; use the description to decide whether the full skill body is relevant.
78786
78787
  - For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 1000\`, and \`max_lines: 1000\`.
78787
78788
  - After running search, inspect the result: if \`total === 0\` (file does not exist or is empty) OR \`truncated\` is \`true\` (file was too large and content was cut off), stop and report \`SKILL_LOAD_FAILED: <path>\`. Do NOT continue without the complete skill.
78788
78789
  - If the search result has \`total > 0\` and \`truncated\` is \`false\`, reconstruct the full skill content from the line-by-line matches and apply it.
@@ -78964,7 +78965,8 @@ DOMAIN: [the domain - e.g., security, ios, android, rust, kubernetes]
78964
78965
  INPUT: [context/requirements]
78965
78966
  SKILLS: [optional — either "none", repo-relative file: references (preferred), or inline skill content pasted by architect]
78966
78967
 
78967
- SKILLS HANDLING: If SKILLS is present and not "none", load EVERY referenced skill before formulating your recommendation.
78968
+ SKILLS HANDLING: If SKILLS is present and not "none", read the skill names/descriptions first, then load every referenced skill that applies before formulating your recommendation. If uncertain whether a skill applies, load it.
78969
+ - A file entry may include a short description after the path; use the description to decide whether the full skill body is relevant.
78968
78970
  - For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 1000\`, and \`max_lines: 1000\`.
78969
78971
  - After running search, inspect the result: if \`total === 0\` (file does not exist or is empty) OR \`truncated\` is \`true\` (file was too large and content was cut off), stop and report \`SKILL_LOAD_FAILED: <path>\`. Do NOT continue without the complete skill.
78970
78972
  - If the search result has \`total > 0\` and \`truncated\` is \`false\`, reconstruct the full skill content from the line-by-line matches and apply it.
@@ -79170,7 +79172,8 @@ FILE: [source file path]
79170
79172
  OUTPUT: [test file path]
79171
79173
  SKILLS: [optional — either "none", repo-relative file: references (preferred), or inline skill content pasted by architect]
79172
79174
 
79173
- SKILLS HANDLING: If SKILLS is present and not "none", load EVERY referenced skill before writing any test code.
79175
+ SKILLS HANDLING: If SKILLS is present and not "none", read the skill names/descriptions first, then load every referenced skill that applies before writing any test code. If uncertain whether a skill applies, load it.
79176
+ - A file entry may include a short description after the path; use the description to decide whether the full skill body is relevant.
79174
79177
  - For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 1000\`, and \`max_lines: 1000\`.
79175
79178
  - After running search, inspect the result: if \`total === 0\` (file does not exist or is empty) OR \`truncated\` is \`true\` (file was too large and content was cut off), stop and report \`SKILL_LOAD_FAILED: <path>\`. Do NOT continue without the complete skill.
79176
79179
  - If the search result has \`total > 0\` and \`truncated\` is \`false\`, reconstruct the full skill content from the line-by-line matches and apply it.
@@ -84730,12 +84733,12 @@ __export(exports_project_context, {
84730
84733
  _internals: () => _internals57,
84731
84734
  LANG_BACKEND_DETECTION_TIMEOUT_MS: () => LANG_BACKEND_DETECTION_TIMEOUT_MS
84732
84735
  });
84733
- import * as fs112 from "node:fs";
84736
+ import * as fs113 from "node:fs";
84734
84737
  import * as path143 from "node:path";
84735
84738
  function detectFileExists2(directory, pattern) {
84736
84739
  if (pattern.includes("*") || pattern.includes("?")) {
84737
84740
  try {
84738
- const files = fs112.readdirSync(directory);
84741
+ const files = fs113.readdirSync(directory);
84739
84742
  const regex = new RegExp(`^${pattern.replace(/\./g, "\\.").replace(/\*/g, ".*").replace(/\?/g, ".")}$`);
84740
84743
  return files.some((f) => regex.test(f));
84741
84744
  } catch {
@@ -84743,7 +84746,7 @@ function detectFileExists2(directory, pattern) {
84743
84746
  }
84744
84747
  }
84745
84748
  try {
84746
- fs112.accessSync(path143.join(directory, pattern));
84749
+ fs113.accessSync(path143.join(directory, pattern));
84747
84750
  return true;
84748
84751
  } catch {
84749
84752
  return false;
@@ -84752,7 +84755,7 @@ function detectFileExists2(directory, pattern) {
84752
84755
  function selectTestCommandFromScriptsTest(backend, directory) {
84753
84756
  let pkgRaw;
84754
84757
  try {
84755
- pkgRaw = fs112.readFileSync(path143.join(directory, "package.json"), "utf-8");
84758
+ pkgRaw = fs113.readFileSync(path143.join(directory, "package.json"), "utf-8");
84756
84759
  } catch {
84757
84760
  return null;
84758
84761
  }
@@ -95751,10 +95754,11 @@ function createSelfReviewHook(config3, injectAdvisory) {
95751
95754
  // src/hooks/skill-propagation-gate.ts
95752
95755
  init_schema();
95753
95756
  init_logger();
95754
- import * as fs62 from "node:fs";
95757
+ import * as fs63 from "node:fs";
95755
95758
  import * as path90 from "node:path";
95756
95759
 
95757
95760
  // src/hooks/skill-scoring.ts
95761
+ import * as fs62 from "node:fs";
95758
95762
  import * as path89 from "node:path";
95759
95763
 
95760
95764
  // src/hooks/skill-usage-log.ts
@@ -95921,11 +95925,14 @@ var RECENCY_WEIGHT = 0.15;
95921
95925
  var TASK_DIVERSITY_WEIGHT = 0.05;
95922
95926
  var CONTEXT_WEIGHT = 0.2;
95923
95927
  var RECENCY_DECAY_MS = 30 * 24 * 60 * 60 * 1000;
95928
+ var SKILL_FRONTMATTER_READ_BYTES = 16 * 1024;
95924
95929
  var _internals42 = {
95925
95930
  computeSkillRelevanceScore: null,
95926
95931
  rankSkillsForContext: null,
95927
95932
  getSkillStats: null,
95928
95933
  formatSkillIndexWithContext: null,
95934
+ parseSkillFrontmatter: null,
95935
+ readSkillMetadata: null,
95929
95936
  extractSkillName: null,
95930
95937
  computeRecencyScore: null,
95931
95938
  computeContextMatchScore: null
@@ -95937,6 +95944,98 @@ function extractSkillName(skillPath) {
95937
95944
  const parent = path89.basename(path89.dirname(skillPath));
95938
95945
  return parent;
95939
95946
  }
95947
+ function stripQuotes(value) {
95948
+ const trimmed = value.trim();
95949
+ if (trimmed.startsWith('"') && trimmed.endsWith('"') || trimmed.startsWith("'") && trimmed.endsWith("'")) {
95950
+ return trimmed.slice(1, -1).trim();
95951
+ }
95952
+ return trimmed;
95953
+ }
95954
+ function normalizeDescription(description) {
95955
+ const singleLine = description.replace(/\s+/g, " ").trim();
95956
+ if (!singleLine)
95957
+ return "No description provided";
95958
+ return singleLine.length > 240 ? `${singleLine.slice(0, 237)}...` : singleLine;
95959
+ }
95960
+ function parseSkillFrontmatter(content, skillPath) {
95961
+ const normalizedPath = skillPath.replace(/^file:/, "").replace(/\\/g, "/");
95962
+ const fallbackName = extractSkillName(normalizedPath);
95963
+ const fallback = {
95964
+ path: normalizedPath,
95965
+ name: fallbackName,
95966
+ description: "No description provided"
95967
+ };
95968
+ const lines = content.split(/\r?\n/);
95969
+ if (lines[0]?.trim() !== "---")
95970
+ return fallback;
95971
+ const end = lines.findIndex((line, index) => index > 0 && line.trim() === "---");
95972
+ if (end === -1)
95973
+ return fallback;
95974
+ let name2 = fallbackName;
95975
+ let description = "";
95976
+ for (let i2 = 1;i2 < end; i2++) {
95977
+ const line = lines[i2] ?? "";
95978
+ const match = line.match(/^([A-Za-z_][A-Za-z0-9_-]*)\s*:\s*(.*)$/);
95979
+ if (!match)
95980
+ continue;
95981
+ const key = match[1].toLowerCase();
95982
+ const rawValue = match[2].trim();
95983
+ if (key === "name") {
95984
+ const parsed = stripQuotes(rawValue);
95985
+ if (parsed)
95986
+ name2 = parsed;
95987
+ continue;
95988
+ }
95989
+ if (key !== "description")
95990
+ continue;
95991
+ if (rawValue === ">" || rawValue === "|") {
95992
+ const collected = [];
95993
+ for (let j = i2 + 1;j < end; j++) {
95994
+ const next = lines[j] ?? "";
95995
+ if (/^[A-Za-z_][A-Za-z0-9_-]*\s*:/.test(next))
95996
+ break;
95997
+ collected.push(next.trim());
95998
+ i2 = j;
95999
+ }
96000
+ description = collected.join(" ");
96001
+ } else {
96002
+ description = stripQuotes(rawValue);
96003
+ }
96004
+ }
96005
+ return {
96006
+ path: normalizedPath,
96007
+ name: name2 || fallbackName,
96008
+ description: normalizeDescription(description)
96009
+ };
96010
+ }
96011
+ function readFilePrefix(filePath) {
96012
+ const fd = fs62.openSync(filePath, "r");
96013
+ try {
96014
+ const buffer = Buffer.alloc(SKILL_FRONTMATTER_READ_BYTES);
96015
+ const bytesRead = fs62.readSync(fd, buffer, 0, SKILL_FRONTMATTER_READ_BYTES, 0);
96016
+ return buffer.toString("utf-8", 0, bytesRead);
96017
+ } finally {
96018
+ fs62.closeSync(fd);
96019
+ }
96020
+ }
96021
+ function readSkillMetadata(skillPath, directory) {
96022
+ const normalizedPath = skillPath.replace(/^file:/, "").replace(/\\/g, "/");
96023
+ const fallback = parseSkillFrontmatter("", normalizedPath);
96024
+ try {
96025
+ if (path89.isAbsolute(normalizedPath) || normalizedPath.split("/").includes("..")) {
96026
+ return fallback;
96027
+ }
96028
+ const root = path89.resolve(directory);
96029
+ const absolutePath = path89.resolve(directory, normalizedPath);
96030
+ if (absolutePath !== root && !absolutePath.startsWith(root + path89.sep)) {
96031
+ return fallback;
96032
+ }
96033
+ const content = readFilePrefix(absolutePath);
96034
+ return parseSkillFrontmatter(content, normalizedPath);
96035
+ } catch {
96036
+ return fallback;
96037
+ }
96038
+ }
95940
96039
  function computeRecencyScore(lastUsedTimestamp) {
95941
96040
  if (!lastUsedTimestamp)
95942
96041
  return 0;
@@ -96041,16 +96140,19 @@ function formatSkillIndexWithContext(skills, directory) {
96041
96140
  const allEntries = readSkillUsageEntries(directory);
96042
96141
  const hasHistory = allEntries.length > 0;
96043
96142
  if (!hasHistory) {
96044
- return skills.map((sp) => ` - ${extractSkillName(sp)}`).join(`
96143
+ return skills.map((sp) => {
96144
+ const meta3 = _internals42.readSkillMetadata(sp, directory);
96145
+ return ` - file:${meta3.path} - ${meta3.name}: ${meta3.description}`;
96146
+ }).join(`
96045
96147
  `);
96046
96148
  }
96047
96149
  const lines = [];
96048
96150
  for (const skillPath of skills) {
96049
96151
  const stats = getSkillStats(skillPath, directory);
96050
- const name2 = extractSkillName(skillPath);
96152
+ const meta3 = _internals42.readSkillMetadata(skillPath, directory);
96051
96153
  const compliancePct = Math.round(stats.complianceRate * 100);
96052
96154
  const topAgentNames = stats.topAgents.slice(0, 3).map((a) => a.agent).join(", ");
96053
- lines.push(` ${name2}: ${skillPath} (used: ${stats.totalUsage}, compliance: ${compliancePct}%)` + (stats.topAgents.length > 0 ? ` → ${topAgentNames}` : ""));
96155
+ lines.push(` - file:${meta3.path} - ${meta3.name}: ${meta3.description} (used: ${stats.totalUsage}, compliance: ${compliancePct}%)` + (stats.topAgents.length > 0 ? ` → ${topAgentNames}` : ""));
96054
96156
  }
96055
96157
  return lines.join(`
96056
96158
  `);
@@ -96059,6 +96161,8 @@ _internals42.computeSkillRelevanceScore = computeSkillRelevanceScore;
96059
96161
  _internals42.rankSkillsForContext = rankSkillsForContext;
96060
96162
  _internals42.getSkillStats = getSkillStats;
96061
96163
  _internals42.formatSkillIndexWithContext = formatSkillIndexWithContext;
96164
+ _internals42.parseSkillFrontmatter = parseSkillFrontmatter;
96165
+ _internals42.readSkillMetadata = readSkillMetadata;
96062
96166
  _internals42.extractSkillName = extractSkillName;
96063
96167
  _internals42.computeRecencyScore = computeRecencyScore;
96064
96168
  _internals42.computeContextMatchScore = computeContextMatchScore;
@@ -96079,13 +96183,13 @@ var SKILL_SEARCH_ROOTS = [
96079
96183
  ];
96080
96184
  var MAX_SCORING_SESSION_ENTRIES = 500;
96081
96185
  var _internals43 = {
96082
- readdirSync: fs62.readdirSync.bind(fs62),
96083
- existsSync: fs62.existsSync.bind(fs62),
96084
- statSync: fs62.statSync.bind(fs62),
96085
- mkdirSync: fs62.mkdirSync.bind(fs62),
96086
- appendFileSync: fs62.appendFileSync.bind(fs62),
96087
- readFileSync: fs62.readFileSync.bind(fs62),
96088
- writeFileSync: fs62.writeFileSync.bind(fs62),
96186
+ readdirSync: fs63.readdirSync.bind(fs63),
96187
+ existsSync: fs63.existsSync.bind(fs63),
96188
+ statSync: fs63.statSync.bind(fs63),
96189
+ mkdirSync: fs63.mkdirSync.bind(fs63),
96190
+ appendFileSync: fs63.appendFileSync.bind(fs63),
96191
+ readFileSync: fs63.readFileSync.bind(fs63),
96192
+ writeFileSync: fs63.writeFileSync.bind(fs63),
96089
96193
  skillPropagationGateBefore: null,
96090
96194
  skillPropagationTransformScan: null,
96091
96195
  SKILL_CAPABLE_AGENTS,
@@ -96096,6 +96200,7 @@ var _internals43 = {
96096
96200
  appendSkillUsageEntry,
96097
96201
  readSkillUsageEntries,
96098
96202
  readSkillUsageEntriesTail,
96203
+ extractSkillsFieldFromPrompt: null,
96099
96204
  parseSkillPaths: null,
96100
96205
  extractTaskIdFromPrompt: null,
96101
96206
  computeSkillRelevanceScore,
@@ -96120,7 +96225,7 @@ function discoverAvailableSkills(directory) {
96120
96225
  const skillFile = path90.join(skillDir, "SKILL.md");
96121
96226
  try {
96122
96227
  if (_internals43.statSync(skillDir).isDirectory() && _internals43.existsSync(skillFile)) {
96123
- results.push(path90.join(root, entry, "SKILL.md"));
96228
+ results.push(path90.join(root, entry, "SKILL.md").replace(/\\/g, "/"));
96124
96229
  }
96125
96230
  } catch (err2) {
96126
96231
  warn(`[skill-propagation-gate] failed to stat skill directory ${entry}: ${err2 instanceof Error ? err2.message : String(err2)}`);
@@ -96151,19 +96256,42 @@ function parseDelegationArgs(args2) {
96151
96256
  }
96152
96257
  if (!targetAgent)
96153
96258
  return null;
96154
- let skillsField = "";
96155
- if (prompt) {
96156
- const lines = prompt.split(`
96259
+ const skillsField = prompt ? _internals43.extractSkillsFieldFromPrompt(prompt) : "";
96260
+ return { targetAgent, skillsField };
96261
+ }
96262
+ function extractSkillsFieldFromPrompt(prompt) {
96263
+ const lines = prompt.split(`
96157
96264
  `);
96158
- for (const line of lines) {
96159
- const trimmed = line.trim();
96160
- if (trimmed.startsWith("SKILLS:")) {
96161
- skillsField = trimmed.slice("SKILLS:".length).trim();
96265
+ for (let i2 = 0;i2 < lines.length; i2++) {
96266
+ const trimmed = lines[i2].trim();
96267
+ if (!/^SKILLS\s*:/i.test(trimmed))
96268
+ continue;
96269
+ const firstLine2 = trimmed.replace(/^SKILLS\s*:/i, "").trim();
96270
+ const collected = [];
96271
+ if (firstLine2)
96272
+ collected.push(firstLine2);
96273
+ for (let j = i2 + 1;j < lines.length; j++) {
96274
+ const next = lines[j];
96275
+ const nextTrimmed = next.trim();
96276
+ if (!nextTrimmed) {
96277
+ if (collected.length === 0)
96278
+ continue;
96162
96279
  break;
96163
96280
  }
96281
+ if (/^[A-Z][A-Z0-9_ -]{1,40}\s*:/i.test(nextTrimmed))
96282
+ break;
96283
+ if (/^(?:-|\*|\d+\.)\s+/.test(nextTrimmed) || /^\s+/.test(next)) {
96284
+ collected.push(nextTrimmed);
96285
+ continue;
96286
+ }
96287
+ if (collected.length === 0)
96288
+ collected.push(nextTrimmed);
96289
+ break;
96164
96290
  }
96291
+ return collected.join(`
96292
+ `).trim();
96165
96293
  }
96166
- return { targetAgent, skillsField };
96294
+ return "";
96167
96295
  }
96168
96296
  function writeWarnEvent2(directory, record3) {
96169
96297
  const filePath = path90.join(directory, ".swarm", "events.jsonl");
@@ -96184,7 +96312,22 @@ function parseSkillPaths(fieldValue) {
96184
96312
  const trimmed = fieldValue.trim();
96185
96313
  if (trimmed.toLowerCase() === "none" || trimmed === "")
96186
96314
  return [];
96187
- return trimmed.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
96315
+ const lines = trimmed.split(/\r?\n/);
96316
+ const hasCatalogLines = lines.some((line) => /^(?:-|\*|\d+\.)\s+/.test(line.trim()));
96317
+ const parts2 = hasCatalogLines ? lines : trimmed.split(",");
96318
+ const paths = [];
96319
+ for (const rawPart of parts2) {
96320
+ const part = rawPart.trim().replace(/^(?:-|\*|\d+\.)\s+/, "").trim();
96321
+ if (!part || part.toLowerCase() === "none")
96322
+ continue;
96323
+ const fileRef = part.match(/\bfile:[^\s,;)\]]+/);
96324
+ if (fileRef) {
96325
+ paths.push(fileRef[0].replace(/\\/g, "/"));
96326
+ continue;
96327
+ }
96328
+ paths.push(part);
96329
+ }
96330
+ return [...new Set(paths)];
96188
96331
  }
96189
96332
  function extractTaskIdFromPrompt(prompt) {
96190
96333
  if (!prompt || typeof prompt !== "string")
@@ -96473,8 +96616,10 @@ async function skillPropagationTransformScan(directory, output, sessionID) {
96473
96616
  continue;
96474
96617
  let currentTargetAgent = "";
96475
96618
  let skillsField = "";
96476
- for (const line of text.split(`
96477
- `)) {
96619
+ const textLines = text.split(`
96620
+ `);
96621
+ for (let lineIndex = 0;lineIndex < textLines.length; lineIndex++) {
96622
+ const line = textLines[lineIndex] ?? "";
96478
96623
  const trimmed = line.trim();
96479
96624
  if (trimmed.match(/TO\s+(coder|reviewer|test_engineer|sme|docs|designer)/i)) {
96480
96625
  const agentMatch = trimmed.match(/TO\s+(coder|reviewer|test_engineer|sme|docs|designer)/i);
@@ -96482,7 +96627,8 @@ async function skillPropagationTransformScan(directory, output, sessionID) {
96482
96627
  currentTargetAgent = agentMatch[1].toLowerCase();
96483
96628
  }
96484
96629
  if (trimmed.startsWith("SKILLS:")) {
96485
- skillsField = trimmed.slice("SKILLS:".length).trim();
96630
+ skillsField = _internals43.extractSkillsFieldFromPrompt(textLines.slice(lineIndex).join(`
96631
+ `));
96486
96632
  }
96487
96633
  if (currentTargetAgent && skillsField && skillsField.toLowerCase() !== "none") {
96488
96634
  const skillPaths = _internals43.parseSkillPaths(skillsField);
@@ -96518,12 +96664,13 @@ _internals43.skillPropagationTransformScan = skillPropagationTransformScan;
96518
96664
  _internals43.writeWarnEvent = writeWarnEvent2;
96519
96665
  _internals43.discoverAvailableSkills = discoverAvailableSkills;
96520
96666
  _internals43.parseDelegationArgs = parseDelegationArgs;
96667
+ _internals43.extractSkillsFieldFromPrompt = extractSkillsFieldFromPrompt;
96521
96668
  _internals43.parseSkillPaths = parseSkillPaths;
96522
96669
  _internals43.extractTaskIdFromPrompt = extractTaskIdFromPrompt;
96523
96670
  _internals43.formatSkillIndexWithContext = formatSkillIndexWithContext;
96524
96671
 
96525
96672
  // src/hooks/slop-detector.ts
96526
- import * as fs63 from "node:fs";
96673
+ import * as fs64 from "node:fs";
96527
96674
  import * as path91 from "node:path";
96528
96675
  var WRITE_EDIT_TOOLS = new Set([
96529
96676
  "write",
@@ -96569,7 +96716,7 @@ function checkBoilerplateExplosion(content, taskDescription, threshold) {
96569
96716
  function walkFiles(dir, exts, deadline) {
96570
96717
  const results = [];
96571
96718
  try {
96572
- for (const entry of fs63.readdirSync(dir, { withFileTypes: true })) {
96719
+ for (const entry of fs64.readdirSync(dir, { withFileTypes: true })) {
96573
96720
  if (deadline !== undefined && Date.now() > deadline)
96574
96721
  break;
96575
96722
  if (entry.isSymbolicLink())
@@ -96589,7 +96736,7 @@ function walkFiles(dir, exts, deadline) {
96589
96736
  return results;
96590
96737
  }
96591
96738
  function checkDeadExports(content, projectDir, startTime) {
96592
- const hasPackageJson = fs63.existsSync(path91.join(projectDir, "package.json"));
96739
+ const hasPackageJson = fs64.existsSync(path91.join(projectDir, "package.json"));
96593
96740
  if (!hasPackageJson)
96594
96741
  return null;
96595
96742
  const exportMatches = content.matchAll(/^\+(?:export)\s+(?:function|class|const|type|interface)\s+(\w{3,})/gm);
@@ -96612,7 +96759,7 @@ function checkDeadExports(content, projectDir, startTime) {
96612
96759
  if (found || Date.now() - startTime > 480)
96613
96760
  break;
96614
96761
  try {
96615
- const text = fs63.readFileSync(file3, "utf-8");
96762
+ const text = fs64.readFileSync(file3, "utf-8");
96616
96763
  if (importPattern.test(text))
96617
96764
  found = true;
96618
96765
  importPattern.lastIndex = 0;
@@ -96704,7 +96851,7 @@ function checkDuplicateUtility(content, projectDir, startTime, targetFile) {
96704
96851
  if (Date.now() > deadline)
96705
96852
  break;
96706
96853
  const utilPath = path91.join(projectDir, utilDir);
96707
- if (!fs63.existsSync(utilPath))
96854
+ if (!fs64.existsSync(utilPath))
96708
96855
  continue;
96709
96856
  const files = walkFiles(utilPath, [".ts", ".tsx", ".js", ".jsx"], deadline);
96710
96857
  for (const file3 of files) {
@@ -96713,7 +96860,7 @@ function checkDuplicateUtility(content, projectDir, startTime, targetFile) {
96713
96860
  if (targetFile && path91.resolve(file3) === path91.resolve(targetFile))
96714
96861
  continue;
96715
96862
  try {
96716
- const text = fs63.readFileSync(file3, "utf-8");
96863
+ const text = fs64.readFileSync(file3, "utf-8");
96717
96864
  for (const name2 of newExports) {
96718
96865
  const exportPattern = new RegExp(`\\bexport\\s+(?:function|class|const|type|interface)\\s+${name2}\\b`);
96719
96866
  if (exportPattern.test(text)) {
@@ -96796,7 +96943,7 @@ Review before proceeding.`;
96796
96943
  // src/hooks/steering-consumed.ts
96797
96944
  init_bun_compat();
96798
96945
  init_utils2();
96799
- import * as fs64 from "node:fs";
96946
+ import * as fs65 from "node:fs";
96800
96947
  function recordSteeringConsumed(directory, directiveId) {
96801
96948
  try {
96802
96949
  const eventsPath = validateSwarmPath(directory, "events.jsonl");
@@ -96805,7 +96952,7 @@ function recordSteeringConsumed(directory, directiveId) {
96805
96952
  directiveId,
96806
96953
  timestamp: new Date().toISOString()
96807
96954
  };
96808
- fs64.appendFileSync(eventsPath, `${JSON.stringify(event)}
96955
+ fs65.appendFileSync(eventsPath, `${JSON.stringify(event)}
96809
96956
  `, "utf-8");
96810
96957
  } catch {}
96811
96958
  }
@@ -96847,12 +96994,12 @@ function createSteeringConsumedHook(directory) {
96847
96994
 
96848
96995
  // src/hooks/trajectory-logger.ts
96849
96996
  init_manager2();
96850
- import * as fs66 from "node:fs/promises";
96997
+ import * as fs67 from "node:fs/promises";
96851
96998
  import * as path93 from "node:path";
96852
96999
 
96853
97000
  // src/prm/trajectory-store.ts
96854
97001
  init_utils2();
96855
- import * as fs65 from "node:fs/promises";
97002
+ import * as fs66 from "node:fs/promises";
96856
97003
  import * as path92 from "node:path";
96857
97004
  function getTrajectoryPath(sessionId, directory) {
96858
97005
  const relativePath = path92.join("trajectories", `${sessionId}.jsonl`);
@@ -96874,10 +97021,10 @@ async function appendTrajectoryEntry(sessionId, entry, directory, maxLines = 100
96874
97021
  _inMemoryTrajectoryCache.set(sessionId, cached3);
96875
97022
  }
96876
97023
  const trajectoryPath = getTrajectoryPath(sessionId, directory);
96877
- await fs65.mkdir(path92.dirname(trajectoryPath), { recursive: true });
97024
+ await fs66.mkdir(path92.dirname(trajectoryPath), { recursive: true });
96878
97025
  const line = `${JSON.stringify(entry)}
96879
97026
  `;
96880
- await fs65.appendFile(trajectoryPath, line, "utf-8");
97027
+ await fs66.appendFile(trajectoryPath, line, "utf-8");
96881
97028
  } catch (err2) {
96882
97029
  console.warn(`[trajectory-store] Failed to append trajectory entry: ${err2}`);
96883
97030
  }
@@ -96885,7 +97032,7 @@ async function appendTrajectoryEntry(sessionId, entry, directory, maxLines = 100
96885
97032
  async function readTrajectory(sessionId, directory) {
96886
97033
  try {
96887
97034
  const trajectoryPath = getTrajectoryPath(sessionId, directory);
96888
- const content = await fs65.readFile(trajectoryPath, "utf-8");
97035
+ const content = await fs66.readFile(trajectoryPath, "utf-8");
96889
97036
  const lines = content.split(`
96890
97037
  `).filter((line) => line.trim().length > 0);
96891
97038
  const entries = [];
@@ -96909,15 +97056,15 @@ async function cleanupOldTrajectoryFiles(directory, maxAgeDays = 7) {
96909
97056
  for (const subdir of ["trajectories", "replays"]) {
96910
97057
  try {
96911
97058
  const dirPath = validateSwarmPath(directory, subdir);
96912
- const entries = await fs65.readdir(dirPath, { withFileTypes: true });
97059
+ const entries = await fs66.readdir(dirPath, { withFileTypes: true });
96913
97060
  for (const entry of entries) {
96914
97061
  if (!entry.isFile())
96915
97062
  continue;
96916
97063
  const filePath = path92.join(dirPath, entry.name);
96917
97064
  try {
96918
- const stat8 = await fs65.stat(filePath);
97065
+ const stat8 = await fs66.stat(filePath);
96919
97066
  if (now - stat8.mtimeMs > cutoffMs) {
96920
- await fs65.unlink(filePath);
97067
+ await fs66.unlink(filePath);
96921
97068
  }
96922
97069
  } catch {}
96923
97070
  }
@@ -96967,7 +97114,7 @@ function isSensitiveKey(key) {
96967
97114
  }
96968
97115
  async function truncateTrajectoryFile(filePath, maxLines) {
96969
97116
  try {
96970
- const content = await fs66.readFile(filePath, "utf-8");
97117
+ const content = await fs67.readFile(filePath, "utf-8");
96971
97118
  const lines = content.split(`
96972
97119
  `).filter((line) => line.trim().length > 0);
96973
97120
  if (lines.length <= maxLines) {
@@ -96975,7 +97122,7 @@ async function truncateTrajectoryFile(filePath, maxLines) {
96975
97122
  }
96976
97123
  const keepCount = Math.floor(maxLines / 2);
96977
97124
  const keptLines = lines.slice(-keepCount);
96978
- await fs66.writeFile(filePath, `${keptLines.join(`
97125
+ await fs67.writeFile(filePath, `${keptLines.join(`
96979
97126
  `)}
96980
97127
  `, "utf-8");
96981
97128
  } catch {}
@@ -97108,10 +97255,10 @@ function createTrajectoryLoggerHook(config3, _directory) {
97108
97255
  const relativePath = path93.join("evidence", sanitized, "trajectory.jsonl");
97109
97256
  const trajectoryPath = validateSwarmPath(_directory, relativePath);
97110
97257
  try {
97111
- await fs66.mkdir(path93.dirname(trajectoryPath), { recursive: true });
97258
+ await fs67.mkdir(path93.dirname(trajectoryPath), { recursive: true });
97112
97259
  const line = `${JSON.stringify(entry)}
97113
97260
  `;
97114
- await fs66.appendFile(trajectoryPath, line, "utf-8");
97261
+ await fs67.appendFile(trajectoryPath, line, "utf-8");
97115
97262
  await truncateTrajectoryFile(trajectoryPath, maxLines);
97116
97263
  } catch {}
97117
97264
  try {
@@ -97658,7 +97805,7 @@ init_state();
97658
97805
  init_telemetry();
97659
97806
 
97660
97807
  // src/prm/replay.ts
97661
- import { promises as fs67 } from "node:fs";
97808
+ import { promises as fs68 } from "node:fs";
97662
97809
  import path94 from "node:path";
97663
97810
  function isPathSafe2(targetPath, basePath) {
97664
97811
  const resolvedTarget = path94.resolve(targetPath);
@@ -97689,7 +97836,7 @@ async function startReplayRecording(sessionID, directory) {
97689
97836
  console.warn(`[replay] Invalid path detected - path traversal attempt blocked for session ${sessionID}`);
97690
97837
  return null;
97691
97838
  }
97692
- await fs67.mkdir(replayDir, { recursive: true });
97839
+ await fs68.mkdir(replayDir, { recursive: true });
97693
97840
  return filepath;
97694
97841
  } catch (err2) {
97695
97842
  console.warn(`[replay] Failed to start recording for session ${sessionID}: ${err2}`);
@@ -97709,7 +97856,7 @@ async function recordReplayEntry(artifactPath, sessionID, entry) {
97709
97856
  };
97710
97857
  const line = `${JSON.stringify(fullEntry)}
97711
97858
  `;
97712
- await fs67.appendFile(artifactPath, line, "utf-8");
97859
+ await fs68.appendFile(artifactPath, line, "utf-8");
97713
97860
  } catch (err2) {
97714
97861
  console.warn(`[replay] Failed to record entry: ${err2}`);
97715
97862
  }
@@ -98064,7 +98211,7 @@ init_telemetry();
98064
98211
  // src/tools/batch-symbols.ts
98065
98212
  init_dist();
98066
98213
  init_create_tool();
98067
- import * as fs68 from "node:fs";
98214
+ import * as fs69 from "node:fs";
98068
98215
  import * as path95 from "node:path";
98069
98216
  init_path_security();
98070
98217
  var WINDOWS_RESERVED_NAMES2 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
@@ -98083,11 +98230,11 @@ function containsWindowsAttacks2(str) {
98083
98230
  function isPathInWorkspace2(filePath, workspace) {
98084
98231
  try {
98085
98232
  const resolvedPath = path95.resolve(workspace, filePath);
98086
- if (!fs68.existsSync(resolvedPath)) {
98233
+ if (!fs69.existsSync(resolvedPath)) {
98087
98234
  return true;
98088
98235
  }
98089
- const realWorkspace = fs68.realpathSync(workspace);
98090
- const realResolvedPath = fs68.realpathSync(resolvedPath);
98236
+ const realWorkspace = fs69.realpathSync(workspace);
98237
+ const realResolvedPath = fs69.realpathSync(resolvedPath);
98091
98238
  const relativePath = path95.relative(realWorkspace, realResolvedPath);
98092
98239
  if (relativePath.startsWith("..") || path95.isAbsolute(relativePath)) {
98093
98240
  return false;
@@ -98132,7 +98279,7 @@ function processFile2(file3, cwd, exportedOnly) {
98132
98279
  };
98133
98280
  }
98134
98281
  const fullPath = path95.join(cwd, file3);
98135
- if (!fs68.existsSync(fullPath)) {
98282
+ if (!fs69.existsSync(fullPath)) {
98136
98283
  return {
98137
98284
  file: file3,
98138
98285
  success: false,
@@ -98163,14 +98310,14 @@ function processFile2(file3, cwd, exportedOnly) {
98163
98310
  }
98164
98311
  let isEmptyFile = false;
98165
98312
  try {
98166
- const stats = fs68.statSync(fullPath);
98313
+ const stats = fs69.statSync(fullPath);
98167
98314
  if (stats.size === 0) {
98168
98315
  isEmptyFile = true;
98169
98316
  }
98170
98317
  } catch {}
98171
98318
  if (syms.length === 0) {
98172
98319
  try {
98173
- const content = fs68.readFileSync(fullPath, "utf-8");
98320
+ const content = fs69.readFileSync(fullPath, "utf-8");
98174
98321
  if (content.trim().length === 0) {
98175
98322
  isEmptyFile = true;
98176
98323
  }
@@ -98422,7 +98569,7 @@ init_manager2();
98422
98569
  init_task_id();
98423
98570
  init_create_tool();
98424
98571
  init_resolve_working_directory();
98425
- import * as fs69 from "node:fs";
98572
+ import * as fs70 from "node:fs";
98426
98573
  import * as path96 from "node:path";
98427
98574
  var EVIDENCE_DIR = ".swarm/evidence";
98428
98575
  function isValidTaskId3(taskId) {
@@ -98435,12 +98582,12 @@ function isPathWithinSwarm(filePath, workspaceRoot) {
98435
98582
  return normalizedPath.startsWith(swarmPath);
98436
98583
  }
98437
98584
  function readEvidenceFile(evidencePath) {
98438
- if (!fs69.existsSync(evidencePath)) {
98585
+ if (!fs70.existsSync(evidencePath)) {
98439
98586
  return null;
98440
98587
  }
98441
98588
  let content;
98442
98589
  try {
98443
- content = fs69.readFileSync(evidencePath, "utf-8");
98590
+ content = fs70.readFileSync(evidencePath, "utf-8");
98444
98591
  } catch {
98445
98592
  return null;
98446
98593
  }
@@ -98608,7 +98755,7 @@ init_utils2();
98608
98755
  init_state();
98609
98756
  init_create_tool();
98610
98757
  init_resolve_working_directory();
98611
- import * as fs70 from "node:fs";
98758
+ import * as fs71 from "node:fs";
98612
98759
  import * as path97 from "node:path";
98613
98760
  function extractMatches(regex, text) {
98614
98761
  return Array.from(text.matchAll(regex));
@@ -98703,7 +98850,7 @@ async function executeCompletionVerify(args2, directory) {
98703
98850
  let plan;
98704
98851
  try {
98705
98852
  const planPath = validateSwarmPath(directory, "plan.json");
98706
- const planRaw = fs70.readFileSync(planPath, "utf-8");
98853
+ const planRaw = fs71.readFileSync(planPath, "utf-8");
98707
98854
  plan = JSON.parse(planRaw);
98708
98855
  } catch {
98709
98856
  const result2 = {
@@ -98777,7 +98924,7 @@ async function executeCompletionVerify(args2, directory) {
98777
98924
  }
98778
98925
  let fileContent;
98779
98926
  try {
98780
- fileContent = fs70.readFileSync(resolvedPath, "utf-8");
98927
+ fileContent = fs71.readFileSync(resolvedPath, "utf-8");
98781
98928
  } catch {
98782
98929
  blockedTasks.push({
98783
98930
  task_id: task.id,
@@ -98821,7 +98968,7 @@ async function executeCompletionVerify(args2, directory) {
98821
98968
  try {
98822
98969
  const evidenceDir = path97.join(directory, ".swarm", "evidence", `${phase}`);
98823
98970
  const evidencePath = path97.join(evidenceDir, "completion-verify.json");
98824
- fs70.mkdirSync(evidenceDir, { recursive: true });
98971
+ fs71.mkdirSync(evidenceDir, { recursive: true });
98825
98972
  const evidenceBundle = {
98826
98973
  schema_version: "1.0.0",
98827
98974
  task_id: "completion-verify",
@@ -98842,7 +98989,7 @@ async function executeCompletionVerify(args2, directory) {
98842
98989
  }
98843
98990
  ]
98844
98991
  };
98845
- fs70.writeFileSync(evidencePath, JSON.stringify(evidenceBundle, null, 2), "utf-8");
98992
+ fs71.writeFileSync(evidencePath, JSON.stringify(evidenceBundle, null, 2), "utf-8");
98846
98993
  } catch {}
98847
98994
  return JSON.stringify(result, null, 2);
98848
98995
  }
@@ -98896,11 +99043,11 @@ var completion_verify = createSwarmTool({
98896
99043
  });
98897
99044
  // src/tools/complexity-hotspots.ts
98898
99045
  init_zod();
98899
- import * as fs72 from "node:fs";
99046
+ import * as fs73 from "node:fs";
98900
99047
  import * as path99 from "node:path";
98901
99048
 
98902
99049
  // src/quality/metrics.ts
98903
- import * as fs71 from "node:fs";
99050
+ import * as fs72 from "node:fs";
98904
99051
  import * as path98 from "node:path";
98905
99052
  var MAX_FILE_SIZE_BYTES4 = 256 * 1024;
98906
99053
  var MIN_DUPLICATION_LINES = 10;
@@ -98939,11 +99086,11 @@ function estimateCyclomaticComplexity(content) {
98939
99086
  }
98940
99087
  function getComplexityForFile(filePath) {
98941
99088
  try {
98942
- const stat8 = fs71.statSync(filePath);
99089
+ const stat8 = fs72.statSync(filePath);
98943
99090
  if (stat8.size > MAX_FILE_SIZE_BYTES4) {
98944
99091
  return null;
98945
99092
  }
98946
- const content = fs71.readFileSync(filePath, "utf-8");
99093
+ const content = fs72.readFileSync(filePath, "utf-8");
98947
99094
  return estimateCyclomaticComplexity(content);
98948
99095
  } catch {
98949
99096
  return null;
@@ -98954,7 +99101,7 @@ async function computeComplexityDelta(files, workingDir) {
98954
99101
  const analyzedFiles = [];
98955
99102
  for (const file3 of files) {
98956
99103
  const fullPath = path98.isAbsolute(file3) ? file3 : path98.join(workingDir, file3);
98957
- if (!fs71.existsSync(fullPath)) {
99104
+ if (!fs72.existsSync(fullPath)) {
98958
99105
  continue;
98959
99106
  }
98960
99107
  const complexity = getComplexityForFile(fullPath);
@@ -99075,7 +99222,7 @@ function countGoExports(content) {
99075
99222
  }
99076
99223
  function getExportCountForFile(filePath) {
99077
99224
  try {
99078
- const content = fs71.readFileSync(filePath, "utf-8");
99225
+ const content = fs72.readFileSync(filePath, "utf-8");
99079
99226
  const ext = path98.extname(filePath).toLowerCase();
99080
99227
  switch (ext) {
99081
99228
  case ".ts":
@@ -99103,7 +99250,7 @@ async function computePublicApiDelta(files, workingDir) {
99103
99250
  const analyzedFiles = [];
99104
99251
  for (const file3 of files) {
99105
99252
  const fullPath = path98.isAbsolute(file3) ? file3 : path98.join(workingDir, file3);
99106
- if (!fs71.existsSync(fullPath)) {
99253
+ if (!fs72.existsSync(fullPath)) {
99107
99254
  continue;
99108
99255
  }
99109
99256
  const exports = getExportCountForFile(fullPath);
@@ -99137,15 +99284,15 @@ async function computeDuplicationRatio(files, workingDir) {
99137
99284
  const analyzedFiles = [];
99138
99285
  for (const file3 of files) {
99139
99286
  const fullPath = path98.isAbsolute(file3) ? file3 : path98.join(workingDir, file3);
99140
- if (!fs71.existsSync(fullPath)) {
99287
+ if (!fs72.existsSync(fullPath)) {
99141
99288
  continue;
99142
99289
  }
99143
99290
  try {
99144
- const stat8 = fs71.statSync(fullPath);
99291
+ const stat8 = fs72.statSync(fullPath);
99145
99292
  if (stat8.size > MAX_FILE_SIZE_BYTES4) {
99146
99293
  continue;
99147
99294
  }
99148
- const content = fs71.readFileSync(fullPath, "utf-8");
99295
+ const content = fs72.readFileSync(fullPath, "utf-8");
99149
99296
  const lines = content.split(`
99150
99297
  `).filter((line) => line.trim().length > 0);
99151
99298
  if (lines.length < MIN_DUPLICATION_LINES) {
@@ -99321,7 +99468,7 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
99321
99468
  let testLines = 0;
99322
99469
  let codeLines = 0;
99323
99470
  const srcDir = path98.join(workingDir, "src");
99324
- if (fs71.existsSync(srcDir)) {
99471
+ if (fs72.existsSync(srcDir)) {
99325
99472
  await scanDirectoryForLines(srcDir, enforceGlobs, excludeGlobs, false, (lines) => {
99326
99473
  codeLines += lines;
99327
99474
  });
@@ -99329,14 +99476,14 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
99329
99476
  const possibleSrcDirs = ["lib", "app", "source", "core"];
99330
99477
  for (const dir of possibleSrcDirs) {
99331
99478
  const dirPath = path98.join(workingDir, dir);
99332
- if (fs71.existsSync(dirPath)) {
99479
+ if (fs72.existsSync(dirPath)) {
99333
99480
  await scanDirectoryForLines(dirPath, enforceGlobs, excludeGlobs, false, (lines) => {
99334
99481
  codeLines += lines;
99335
99482
  });
99336
99483
  }
99337
99484
  }
99338
99485
  const testsDir = path98.join(workingDir, "tests");
99339
- if (fs71.existsSync(testsDir)) {
99486
+ if (fs72.existsSync(testsDir)) {
99340
99487
  await scanDirectoryForLines(testsDir, ["**"], ["node_modules", "dist"], true, (lines) => {
99341
99488
  testLines += lines;
99342
99489
  });
@@ -99344,7 +99491,7 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
99344
99491
  const possibleTestDirs = ["test", "__tests__", "specs"];
99345
99492
  for (const dir of possibleTestDirs) {
99346
99493
  const dirPath = path98.join(workingDir, dir);
99347
- if (fs71.existsSync(dirPath) && dirPath !== testsDir) {
99494
+ if (fs72.existsSync(dirPath) && dirPath !== testsDir) {
99348
99495
  await scanDirectoryForLines(dirPath, ["**"], ["node_modules", "dist"], true, (lines) => {
99349
99496
  testLines += lines;
99350
99497
  });
@@ -99356,7 +99503,7 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
99356
99503
  }
99357
99504
  async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTestScan, callback) {
99358
99505
  try {
99359
- const entries = fs71.readdirSync(dirPath, { withFileTypes: true });
99506
+ const entries = fs72.readdirSync(dirPath, { withFileTypes: true });
99360
99507
  for (const entry of entries) {
99361
99508
  const fullPath = path98.join(dirPath, entry.name);
99362
99509
  if (entry.isDirectory()) {
@@ -99402,7 +99549,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
99402
99549
  continue;
99403
99550
  }
99404
99551
  try {
99405
- const content = fs71.readFileSync(fullPath, "utf-8");
99552
+ const content = fs72.readFileSync(fullPath, "utf-8");
99406
99553
  const lines = countCodeLines(content);
99407
99554
  callback(lines);
99408
99555
  } catch {}
@@ -99602,11 +99749,11 @@ async function getGitChurn(days, directory) {
99602
99749
  }
99603
99750
  function getComplexityForFile2(filePath) {
99604
99751
  try {
99605
- const stat8 = fs72.statSync(filePath);
99752
+ const stat8 = fs73.statSync(filePath);
99606
99753
  if (stat8.size > MAX_FILE_SIZE_BYTES5) {
99607
99754
  return null;
99608
99755
  }
99609
- const content = fs72.readFileSync(filePath, "utf-8");
99756
+ const content = fs73.readFileSync(filePath, "utf-8");
99610
99757
  return estimateCyclomaticComplexity(content);
99611
99758
  } catch {
99612
99759
  return null;
@@ -99627,7 +99774,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
99627
99774
  let analyzedFiles = 0;
99628
99775
  for (const [file3, churnCount] of filteredChurn) {
99629
99776
  let fullPath = file3;
99630
- if (!fs72.existsSync(fullPath)) {
99777
+ if (!fs73.existsSync(fullPath)) {
99631
99778
  fullPath = path99.join(cwd, file3);
99632
99779
  }
99633
99780
  const complexity = getComplexityForFile2(fullPath);
@@ -100368,7 +100515,7 @@ var submit_council_verdicts = createSwarmTool({
100368
100515
  // src/tools/convene-general-council.ts
100369
100516
  init_zod();
100370
100517
  init_loader();
100371
- import * as fs73 from "node:fs";
100518
+ import * as fs74 from "node:fs";
100372
100519
  import * as path100 from "node:path";
100373
100520
 
100374
100521
  // src/council/general-council-advisory.ts
@@ -100802,8 +100949,8 @@ var convene_general_council = createSwarmTool({
100802
100949
  const evidenceFile = `${safeTimestamp}-${input.mode}.json`;
100803
100950
  const evidencePath = path100.join(evidenceDir, evidenceFile);
100804
100951
  try {
100805
- await fs73.promises.mkdir(evidenceDir, { recursive: true });
100806
- await fs73.promises.writeFile(evidencePath, JSON.stringify(result, null, 2));
100952
+ await fs74.promises.mkdir(evidenceDir, { recursive: true });
100953
+ await fs74.promises.writeFile(evidencePath, JSON.stringify(result, null, 2));
100807
100954
  } catch (err2) {
100808
100955
  const message = err2 instanceof Error ? err2.message : String(err2);
100809
100956
  console.warn(`[convene_general_council] Failed to write evidence to ${evidencePath}: ${message}`);
@@ -101044,7 +101191,7 @@ init_scope_persistence();
101044
101191
  init_state();
101045
101192
  init_task_id();
101046
101193
  init_create_tool();
101047
- import * as fs74 from "node:fs";
101194
+ import * as fs75 from "node:fs";
101048
101195
  import * as path101 from "node:path";
101049
101196
  function validateTaskIdFormat2(taskId) {
101050
101197
  return validateTaskIdFormat(taskId);
@@ -101132,9 +101279,9 @@ async function executeDeclareScope(args2, fallbackDir) {
101132
101279
  }
101133
101280
  const resolvedDir = path101.resolve(normalizedDir);
101134
101281
  try {
101135
- const realPath = fs74.realpathSync(resolvedDir);
101282
+ const realPath = fs75.realpathSync(resolvedDir);
101136
101283
  const planPath2 = path101.join(realPath, ".swarm", "plan.json");
101137
- if (!fs74.existsSync(planPath2)) {
101284
+ if (!fs75.existsSync(planPath2)) {
101138
101285
  return {
101139
101286
  success: false,
101140
101287
  message: `Invalid working_directory: plan not found in "${realPath}"`,
@@ -101154,8 +101301,8 @@ async function executeDeclareScope(args2, fallbackDir) {
101154
101301
  }
101155
101302
  if (normalizedDir && fallbackDir) {
101156
101303
  try {
101157
- const canonicalWorkingDir = fs74.realpathSync(path101.resolve(normalizedDir));
101158
- const canonicalProjectRoot = fs74.realpathSync(path101.resolve(fallbackDir));
101304
+ const canonicalWorkingDir = fs75.realpathSync(path101.resolve(normalizedDir));
101305
+ const canonicalProjectRoot = fs75.realpathSync(path101.resolve(fallbackDir));
101159
101306
  if (canonicalWorkingDir.startsWith(canonicalProjectRoot + path101.sep)) {
101160
101307
  return {
101161
101308
  success: false,
@@ -101179,7 +101326,7 @@ async function executeDeclareScope(args2, fallbackDir) {
101179
101326
  }
101180
101327
  const directory = normalizedDir || fallbackDir;
101181
101328
  const planPath = path101.resolve(directory, ".swarm", "plan.json");
101182
- if (!fs74.existsSync(planPath)) {
101329
+ if (!fs75.existsSync(planPath)) {
101183
101330
  return {
101184
101331
  success: false,
101185
101332
  message: "No plan found",
@@ -101188,7 +101335,7 @@ async function executeDeclareScope(args2, fallbackDir) {
101188
101335
  }
101189
101336
  let planContent;
101190
101337
  try {
101191
- planContent = JSON.parse(fs74.readFileSync(planPath, "utf-8"));
101338
+ planContent = JSON.parse(fs75.readFileSync(planPath, "utf-8"));
101192
101339
  } catch {
101193
101340
  return {
101194
101341
  success: false,
@@ -101279,7 +101426,7 @@ var declare_scope = createSwarmTool({
101279
101426
  // src/tools/diff.ts
101280
101427
  init_zod();
101281
101428
  import * as child_process7 from "node:child_process";
101282
- import * as fs75 from "node:fs";
101429
+ import * as fs76 from "node:fs";
101283
101430
  import * as path102 from "node:path";
101284
101431
  init_create_tool();
101285
101432
  var MAX_DIFF_LINES = 500;
@@ -101471,7 +101618,7 @@ var diff = createSwarmTool({
101471
101618
  } else if (base === "unstaged") {
101472
101619
  const oldRef = `:${file3.path}`;
101473
101620
  oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
101474
- newContent = fs75.readFileSync(path102.join(directory, file3.path), "utf-8");
101621
+ newContent = fs76.readFileSync(path102.join(directory, file3.path), "utf-8");
101475
101622
  } else {
101476
101623
  const oldRef = `${base}:${file3.path}`;
101477
101624
  oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
@@ -101545,7 +101692,7 @@ var diff = createSwarmTool({
101545
101692
  // src/tools/diff-summary.ts
101546
101693
  init_zod();
101547
101694
  import * as child_process8 from "node:child_process";
101548
- import * as fs76 from "node:fs";
101695
+ import * as fs77 from "node:fs";
101549
101696
  import * as path103 from "node:path";
101550
101697
  init_create_tool();
101551
101698
  init_resolve_working_directory();
@@ -101599,7 +101746,7 @@ var diff_summary = createSwarmTool({
101599
101746
  }
101600
101747
  try {
101601
101748
  let oldContent;
101602
- const newContent = fs76.readFileSync(path103.join(workingDir, filePath), "utf-8");
101749
+ const newContent = fs77.readFileSync(path103.join(workingDir, filePath), "utf-8");
101603
101750
  if (fileExistsInHead) {
101604
101751
  oldContent = child_process8.execFileSync("git", ["show", `HEAD:${filePath}`], {
101605
101752
  encoding: "utf-8",
@@ -101827,7 +101974,7 @@ Use these as DOMAIN values when delegating to @sme.`;
101827
101974
  init_zod();
101828
101975
  init_create_tool();
101829
101976
  init_path_security();
101830
- import * as fs77 from "node:fs";
101977
+ import * as fs78 from "node:fs";
101831
101978
  import * as path104 from "node:path";
101832
101979
  var MAX_FILE_SIZE_BYTES6 = 1024 * 1024;
101833
101980
  var MAX_EVIDENCE_FILES = 1000;
@@ -101873,12 +102020,12 @@ function parseCompletedTasks(planContent) {
101873
102020
  }
101874
102021
  function readEvidenceFiles(evidenceDir, _cwd) {
101875
102022
  const evidence = [];
101876
- if (!fs77.existsSync(evidenceDir) || !fs77.statSync(evidenceDir).isDirectory()) {
102023
+ if (!fs78.existsSync(evidenceDir) || !fs78.statSync(evidenceDir).isDirectory()) {
101877
102024
  return evidence;
101878
102025
  }
101879
102026
  let files;
101880
102027
  try {
101881
- files = fs77.readdirSync(evidenceDir);
102028
+ files = fs78.readdirSync(evidenceDir);
101882
102029
  } catch {
101883
102030
  return evidence;
101884
102031
  }
@@ -101894,7 +102041,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
101894
102041
  if (!resolvedPath.startsWith(evidenceDirResolved)) {
101895
102042
  continue;
101896
102043
  }
101897
- const stat8 = fs77.lstatSync(filePath);
102044
+ const stat8 = fs78.lstatSync(filePath);
101898
102045
  if (!stat8.isFile()) {
101899
102046
  continue;
101900
102047
  }
@@ -101903,7 +102050,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
101903
102050
  }
101904
102051
  let fileStat;
101905
102052
  try {
101906
- fileStat = fs77.statSync(filePath);
102053
+ fileStat = fs78.statSync(filePath);
101907
102054
  if (fileStat.size > MAX_FILE_SIZE_BYTES6) {
101908
102055
  continue;
101909
102056
  }
@@ -101912,7 +102059,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
101912
102059
  }
101913
102060
  let content;
101914
102061
  try {
101915
- content = fs77.readFileSync(filePath, "utf-8");
102062
+ content = fs78.readFileSync(filePath, "utf-8");
101916
102063
  } catch {
101917
102064
  continue;
101918
102065
  }
@@ -102022,7 +102169,7 @@ var evidence_check = createSwarmTool({
102022
102169
  }
102023
102170
  let planContent;
102024
102171
  try {
102025
- planContent = fs77.readFileSync(planPath, "utf-8");
102172
+ planContent = fs78.readFileSync(planPath, "utf-8");
102026
102173
  } catch {
102027
102174
  const result2 = {
102028
102175
  message: "No completed tasks found in plan.",
@@ -102057,7 +102204,7 @@ var evidence_check = createSwarmTool({
102057
102204
  // src/tools/file-extractor.ts
102058
102205
  init_zod();
102059
102206
  init_create_tool();
102060
- import * as fs78 from "node:fs";
102207
+ import * as fs79 from "node:fs";
102061
102208
  import * as path105 from "node:path";
102062
102209
  var EXT_MAP = {
102063
102210
  python: ".py",
@@ -102120,8 +102267,8 @@ var extract_code_blocks = createSwarmTool({
102120
102267
  execute: async (args2, directory) => {
102121
102268
  const { content, output_dir, prefix } = args2;
102122
102269
  const targetDir = output_dir || directory;
102123
- if (!fs78.existsSync(targetDir)) {
102124
- fs78.mkdirSync(targetDir, { recursive: true });
102270
+ if (!fs79.existsSync(targetDir)) {
102271
+ fs79.mkdirSync(targetDir, { recursive: true });
102125
102272
  }
102126
102273
  if (!content) {
102127
102274
  return "Error: content is required";
@@ -102143,12 +102290,12 @@ var extract_code_blocks = createSwarmTool({
102143
102290
  const base = path105.basename(filepath, path105.extname(filepath));
102144
102291
  const ext = path105.extname(filepath);
102145
102292
  let counter = 1;
102146
- while (fs78.existsSync(filepath)) {
102293
+ while (fs79.existsSync(filepath)) {
102147
102294
  filepath = path105.join(targetDir, `${base}_${counter}${ext}`);
102148
102295
  counter++;
102149
102296
  }
102150
102297
  try {
102151
- fs78.writeFileSync(filepath, code.trim(), "utf-8");
102298
+ fs79.writeFileSync(filepath, code.trim(), "utf-8");
102152
102299
  savedFiles.push(filepath);
102153
102300
  } catch (error93) {
102154
102301
  errors5.push(`Failed to save ${filename}: ${error93 instanceof Error ? error93.message : String(error93)}`);
@@ -102314,7 +102461,7 @@ init_create_tool();
102314
102461
  var GITINGEST_TIMEOUT_MS = 1e4;
102315
102462
  var GITINGEST_MAX_RESPONSE_BYTES = 5242880;
102316
102463
  var GITINGEST_MAX_RETRIES = 2;
102317
- var delay = (ms) => new Promise((resolve35) => setTimeout(resolve35, ms));
102464
+ var delay = (ms) => new Promise((resolve36) => setTimeout(resolve36, ms));
102318
102465
  async function fetchGitingest(args2) {
102319
102466
  for (let attempt = 0;attempt <= GITINGEST_MAX_RETRIES; attempt++) {
102320
102467
  try {
@@ -102401,7 +102548,7 @@ var gitingest = createSwarmTool({
102401
102548
  init_zod();
102402
102549
  init_create_tool();
102403
102550
  init_path_security();
102404
- import * as fs79 from "node:fs";
102551
+ import * as fs80 from "node:fs";
102405
102552
  import * as path106 from "node:path";
102406
102553
  var MAX_FILE_PATH_LENGTH2 = 500;
102407
102554
  var MAX_SYMBOL_LENGTH = 256;
@@ -102564,7 +102711,7 @@ var SKIP_DIRECTORIES4 = new Set([
102564
102711
  function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFiles: 0, fileErrors: [] }) {
102565
102712
  let entries;
102566
102713
  try {
102567
- entries = fs79.readdirSync(dir);
102714
+ entries = fs80.readdirSync(dir);
102568
102715
  } catch (e) {
102569
102716
  stats.fileErrors.push({
102570
102717
  path: dir,
@@ -102581,7 +102728,7 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
102581
102728
  const fullPath = path106.join(dir, entry);
102582
102729
  let stat8;
102583
102730
  try {
102584
- stat8 = fs79.statSync(fullPath);
102731
+ stat8 = fs80.statSync(fullPath);
102585
102732
  } catch (e) {
102586
102733
  stats.fileErrors.push({
102587
102734
  path: fullPath,
@@ -102650,7 +102797,7 @@ var imports = createSwarmTool({
102650
102797
  }
102651
102798
  try {
102652
102799
  const targetFile = path106.resolve(file3);
102653
- if (!fs79.existsSync(targetFile)) {
102800
+ if (!fs80.existsSync(targetFile)) {
102654
102801
  const errorResult = {
102655
102802
  error: `target file not found: ${file3}`,
102656
102803
  target: file3,
@@ -102660,7 +102807,7 @@ var imports = createSwarmTool({
102660
102807
  };
102661
102808
  return JSON.stringify(errorResult, null, 2);
102662
102809
  }
102663
- const targetStat = fs79.statSync(targetFile);
102810
+ const targetStat = fs80.statSync(targetFile);
102664
102811
  if (!targetStat.isFile()) {
102665
102812
  const errorResult = {
102666
102813
  error: "target must be a file, not a directory",
@@ -102686,12 +102833,12 @@ var imports = createSwarmTool({
102686
102833
  if (consumers.length >= MAX_CONSUMERS)
102687
102834
  break;
102688
102835
  try {
102689
- const stat8 = fs79.statSync(filePath);
102836
+ const stat8 = fs80.statSync(filePath);
102690
102837
  if (stat8.size > MAX_FILE_SIZE_BYTES7) {
102691
102838
  skippedFileCount++;
102692
102839
  continue;
102693
102840
  }
102694
- const buffer = fs79.readFileSync(filePath);
102841
+ const buffer = fs80.readFileSync(filePath);
102695
102842
  if (isBinaryFile2(filePath, buffer)) {
102696
102843
  skippedFileCount++;
102697
102844
  continue;
@@ -103273,22 +103420,22 @@ init_config();
103273
103420
  init_schema();
103274
103421
  init_qa_gate_profile();
103275
103422
  init_manager2();
103276
- import * as fs84 from "node:fs";
103423
+ import * as fs85 from "node:fs";
103277
103424
  import * as path111 from "node:path";
103278
103425
 
103279
103426
  // src/full-auto/phase-approval.ts
103280
103427
  init_utils2();
103281
103428
  init_logger();
103282
103429
  init_state2();
103283
- import * as fs80 from "node:fs";
103430
+ import * as fs81 from "node:fs";
103284
103431
  import * as path107 from "node:path";
103285
103432
  var APPROVAL_TTL_MS = 24 * 60 * 60 * 1000;
103286
103433
  function readEvidenceDir(directory, phase) {
103287
103434
  try {
103288
103435
  const dirPath = validateSwarmPath(directory, path107.posix.join("evidence", String(phase)));
103289
- if (!fs80.existsSync(dirPath))
103436
+ if (!fs81.existsSync(dirPath))
103290
103437
  return [];
103291
- const entries = fs80.readdirSync(dirPath);
103438
+ const entries = fs81.readdirSync(dirPath);
103292
103439
  return entries.filter((e) => e.startsWith("full-auto-") && e.endsWith(".json")).map((e) => path107.join(dirPath, e));
103293
103440
  } catch {
103294
103441
  return [];
@@ -103296,7 +103443,7 @@ function readEvidenceDir(directory, phase) {
103296
103443
  }
103297
103444
  function parseEvidence(filePath) {
103298
103445
  try {
103299
- const raw = fs80.readFileSync(filePath, "utf-8");
103446
+ const raw = fs81.readFileSync(filePath, "utf-8");
103300
103447
  const parsed = JSON.parse(raw);
103301
103448
  return parsed;
103302
103449
  } catch (error93) {
@@ -103385,9 +103532,9 @@ function verifyFullAutoPhaseApproval(directory, sessionID, phase, config3) {
103385
103532
  function phaseIsExplicitlyNonCode(directory, phase) {
103386
103533
  try {
103387
103534
  const planPath = validateSwarmPath(directory, "plan.json");
103388
- if (!fs80.existsSync(planPath))
103535
+ if (!fs81.existsSync(planPath))
103389
103536
  return false;
103390
- const raw = fs80.readFileSync(planPath, "utf-8");
103537
+ const raw = fs81.readFileSync(planPath, "utf-8");
103391
103538
  const plan = JSON.parse(raw);
103392
103539
  const phases = Array.isArray(plan.phases) ? plan.phases : [];
103393
103540
  const entry = phases.find((p) => p.id === phase || p.phase === phase);
@@ -103428,7 +103575,7 @@ init_file_locks();
103428
103575
  init_plan_schema();
103429
103576
  init_ledger();
103430
103577
  init_manager();
103431
- import * as fs81 from "node:fs";
103578
+ import * as fs82 from "node:fs";
103432
103579
  import * as path108 from "node:path";
103433
103580
  async function writeCheckpoint(directory) {
103434
103581
  try {
@@ -103436,12 +103583,12 @@ async function writeCheckpoint(directory) {
103436
103583
  if (!plan)
103437
103584
  return;
103438
103585
  const swarmDir = path108.join(directory, ".swarm");
103439
- fs81.mkdirSync(swarmDir, { recursive: true });
103586
+ fs82.mkdirSync(swarmDir, { recursive: true });
103440
103587
  const jsonPath = path108.join(swarmDir, "SWARM_PLAN.json");
103441
103588
  const mdPath = path108.join(swarmDir, "SWARM_PLAN.md");
103442
- fs81.writeFileSync(jsonPath, JSON.stringify(plan, null, 2), "utf8");
103589
+ fs82.writeFileSync(jsonPath, JSON.stringify(plan, null, 2), "utf8");
103443
103590
  const md = derivePlanMarkdown(plan);
103444
- fs81.writeFileSync(mdPath, md, "utf8");
103591
+ fs82.writeFileSync(mdPath, md, "utf8");
103445
103592
  } catch (error93) {
103446
103593
  console.warn(`[checkpoint] Failed to write SWARM_PLAN checkpoint: ${error93 instanceof Error ? error93.message : String(error93)}`);
103447
103594
  }
@@ -103456,13 +103603,13 @@ init_telemetry();
103456
103603
 
103457
103604
  // src/turbo/lean/phase-ready.ts
103458
103605
  init_file_locks();
103459
- import * as fs83 from "node:fs";
103606
+ import * as fs84 from "node:fs";
103460
103607
  import * as path110 from "node:path";
103461
103608
 
103462
103609
  // src/turbo/lean/evidence.ts
103463
103610
  init_bun_compat();
103464
103611
  import { rmSync as rmSync6 } from "node:fs";
103465
- import * as fs82 from "node:fs/promises";
103612
+ import * as fs83 from "node:fs/promises";
103466
103613
  import * as path109 from "node:path";
103467
103614
  function leanTurboEvidenceDir(directory, phase) {
103468
103615
  return path109.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
@@ -103497,11 +103644,11 @@ function laneEvidencePath(directory, phase, laneId) {
103497
103644
  async function atomicWriteJson(filePath, data) {
103498
103645
  const content = JSON.stringify(data, null, 2);
103499
103646
  const dir = path109.dirname(filePath);
103500
- await fs82.mkdir(dir, { recursive: true });
103647
+ await fs83.mkdir(dir, { recursive: true });
103501
103648
  const tempPath = `${filePath}.tmp.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}`;
103502
103649
  try {
103503
103650
  await bunWrite(tempPath, content);
103504
- await fs82.rename(tempPath, filePath);
103651
+ await fs83.rename(tempPath, filePath);
103505
103652
  } catch (error93) {
103506
103653
  try {
103507
103654
  rmSync6(tempPath, { force: true });
@@ -103520,7 +103667,7 @@ async function readPhaseEvidence(directory, phase) {
103520
103667
  const targetPath = phaseEvidencePath(directory, phase);
103521
103668
  let content;
103522
103669
  try {
103523
- content = await fs82.readFile(targetPath, "utf-8");
103670
+ content = await fs83.readFile(targetPath, "utf-8");
103524
103671
  } catch (error93) {
103525
103672
  const code = error93.code;
103526
103673
  if (code === "ENOENT" || code === "ENOTDIR") {
@@ -103538,7 +103685,7 @@ async function listLaneEvidence(directory, phase) {
103538
103685
  const evidenceDir = leanTurboEvidenceDir(directory, phase);
103539
103686
  let entries;
103540
103687
  try {
103541
- entries = await fs82.readdir(evidenceDir);
103688
+ entries = await fs83.readdir(evidenceDir);
103542
103689
  } catch (error93) {
103543
103690
  const code = error93.code;
103544
103691
  if (code === "ENOENT" || code === "ENOTDIR") {
@@ -103557,7 +103704,7 @@ async function listLaneEvidence(directory, phase) {
103557
103704
  const filePath = path109.join(evidenceDir, entry);
103558
103705
  let content;
103559
103706
  try {
103560
- content = await fs82.readFile(filePath, "utf-8");
103707
+ content = await fs83.readFile(filePath, "utf-8");
103561
103708
  } catch {
103562
103709
  continue;
103563
103710
  }
@@ -103579,9 +103726,9 @@ var DEFAULT_CONFIG2 = {
103579
103726
  function defaultReadPlanJson(dir) {
103580
103727
  try {
103581
103728
  const planPath = path110.join(dir, ".swarm", "plan.json");
103582
- if (!fs83.existsSync(planPath))
103729
+ if (!fs84.existsSync(planPath))
103583
103730
  return null;
103584
- const raw = fs83.readFileSync(planPath, "utf-8");
103731
+ const raw = fs84.readFileSync(planPath, "utf-8");
103585
103732
  const plan = JSON.parse(raw);
103586
103733
  if (typeof plan !== "object" || plan === null || !Array.isArray(plan.phases)) {
103587
103734
  return null;
@@ -103594,10 +103741,10 @@ function defaultReadPlanJson(dir) {
103594
103741
  function readReviewerEvidenceFromFile(directory, phase) {
103595
103742
  try {
103596
103743
  const evidencePath = path110.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-reviewer.json");
103597
- if (!fs83.existsSync(evidencePath)) {
103744
+ if (!fs84.existsSync(evidencePath)) {
103598
103745
  return null;
103599
103746
  }
103600
- const raw = fs83.readFileSync(evidencePath, "utf-8");
103747
+ const raw = fs84.readFileSync(evidencePath, "utf-8");
103601
103748
  const parsed = JSON.parse(raw);
103602
103749
  if (typeof parsed !== "object" || parsed === null || typeof parsed.verdict !== "string") {
103603
103750
  return null;
@@ -103614,10 +103761,10 @@ function readReviewerEvidenceFromFile(directory, phase) {
103614
103761
  function readCriticEvidenceFromFile(directory, phase) {
103615
103762
  try {
103616
103763
  const evidencePath = path110.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-critic.json");
103617
- if (!fs83.existsSync(evidencePath)) {
103764
+ if (!fs84.existsSync(evidencePath)) {
103618
103765
  return null;
103619
103766
  }
103620
- const raw = fs83.readFileSync(evidencePath, "utf-8");
103767
+ const raw = fs84.readFileSync(evidencePath, "utf-8");
103621
103768
  const parsed = JSON.parse(raw);
103622
103769
  if (typeof parsed !== "object" || parsed === null || typeof parsed.verdict !== "string") {
103623
103770
  return null;
@@ -103635,7 +103782,7 @@ function listLaneEvidenceSync(directory, phase) {
103635
103782
  const evidenceDir = path110.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
103636
103783
  let entries;
103637
103784
  try {
103638
- entries = fs83.readdirSync(evidenceDir);
103785
+ entries = fs84.readdirSync(evidenceDir);
103639
103786
  } catch {
103640
103787
  return [];
103641
103788
  }
@@ -103703,7 +103850,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
103703
103850
  ...actualConfig
103704
103851
  };
103705
103852
  const statePath = path110.join(directory, ".swarm", "turbo-state.json");
103706
- if (!fs83.existsSync(statePath)) {
103853
+ if (!fs84.existsSync(statePath)) {
103707
103854
  return {
103708
103855
  ok: false,
103709
103856
  reason: "Lean Turbo state unreadable or missing"
@@ -103893,7 +104040,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
103893
104040
  const evidencePath = path110.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-phase.json");
103894
104041
  let hasDiff = false;
103895
104042
  try {
103896
- const content = fs83.readFileSync(evidencePath, "utf-8");
104043
+ const content = fs84.readFileSync(evidencePath, "utf-8");
103897
104044
  const evidence = JSON.parse(content);
103898
104045
  hasDiff = !!evidence.integratedDiffSummary;
103899
104046
  } catch {}
@@ -104186,7 +104333,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
104186
104333
  let driftHasSpecMd = false;
104187
104334
  try {
104188
104335
  const specMdPath = path111.join(dir, ".swarm", "spec.md");
104189
- driftHasSpecMd = fs84.existsSync(specMdPath);
104336
+ driftHasSpecMd = fs85.existsSync(specMdPath);
104190
104337
  const gatePlan = await loadPlan(dir);
104191
104338
  if (gatePlan) {
104192
104339
  const gatePlanId = derivePlanId(gatePlan);
@@ -104207,8 +104354,8 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
104207
104354
  let phaseType;
104208
104355
  try {
104209
104356
  const planPath = path111.join(dir, ".swarm", "plan.json");
104210
- if (fs84.existsSync(planPath)) {
104211
- const planRaw = fs84.readFileSync(planPath, "utf-8");
104357
+ if (fs85.existsSync(planPath)) {
104358
+ const planRaw = fs85.readFileSync(planPath, "utf-8");
104212
104359
  const plan = JSON.parse(planRaw);
104213
104360
  const targetPhase = plan.phases?.find((p) => p.id === phase);
104214
104361
  phaseType = targetPhase?.type;
@@ -104222,7 +104369,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
104222
104369
  let driftVerdictFound = false;
104223
104370
  let driftVerdictApproved = false;
104224
104371
  try {
104225
- const driftEvidenceContent = fs84.readFileSync(driftEvidencePath, "utf-8");
104372
+ const driftEvidenceContent = fs85.readFileSync(driftEvidencePath, "utf-8");
104226
104373
  const driftEvidence = JSON.parse(driftEvidenceContent);
104227
104374
  const entries = driftEvidence.entries ?? [];
104228
104375
  for (const entry of entries) {
@@ -104257,8 +104404,8 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
104257
104404
  let planParseable = false;
104258
104405
  try {
104259
104406
  const planPath = path111.join(dir, ".swarm", "plan.json");
104260
- if (fs84.existsSync(planPath)) {
104261
- const planRaw = fs84.readFileSync(planPath, "utf-8");
104407
+ if (fs85.existsSync(planPath)) {
104408
+ const planRaw = fs85.readFileSync(planPath, "utf-8");
104262
104409
  const plan = JSON.parse(planRaw);
104263
104410
  planParseable = true;
104264
104411
  const planPhase = plan.phases?.find((p) => p.id === phase);
@@ -104327,7 +104474,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
104327
104474
  let hgVerdictFound = false;
104328
104475
  let hgVerdictApproved = false;
104329
104476
  try {
104330
- const hgContent = fs84.readFileSync(hgPath, "utf-8");
104477
+ const hgContent = fs85.readFileSync(hgPath, "utf-8");
104331
104478
  const hgBundle = JSON.parse(hgContent);
104332
104479
  for (const entry of hgBundle.entries ?? []) {
104333
104480
  if (typeof entry.type === "string" && entry.type.includes("hallucination") && typeof entry.verdict === "string") {
@@ -104399,7 +104546,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
104399
104546
  let mgVerdictFound = false;
104400
104547
  let mgVerdict;
104401
104548
  try {
104402
- const mgContent = fs84.readFileSync(mgPath, "utf-8");
104549
+ const mgContent = fs85.readFileSync(mgPath, "utf-8");
104403
104550
  const mgBundle = JSON.parse(mgContent);
104404
104551
  for (const entry of mgBundle.entries ?? []) {
104405
104552
  if (typeof entry.type === "string" && entry.type === "mutation-gate" && typeof entry.verdict === "string") {
@@ -104476,7 +104623,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
104476
104623
  let pcTimestamp;
104477
104624
  let pcPhaseNumber;
104478
104625
  try {
104479
- const pcContent = fs84.readFileSync(pcPath, "utf-8");
104626
+ const pcContent = fs85.readFileSync(pcPath, "utf-8");
104480
104627
  const pcBundle = JSON.parse(pcContent);
104481
104628
  for (const entry of pcBundle.entries ?? []) {
104482
104629
  if (typeof entry.type === "string" && entry.type === "phase-council" && typeof entry.verdict === "string") {
@@ -104681,7 +104828,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
104681
104828
  let fcVerdictFound = false;
104682
104829
  let _fcVerdict;
104683
104830
  try {
104684
- const fcContent = fs84.readFileSync(fcPath, "utf-8");
104831
+ const fcContent = fs85.readFileSync(fcPath, "utf-8");
104685
104832
  const fcBundle = JSON.parse(fcContent);
104686
104833
  for (const entry of fcBundle.entries ?? []) {
104687
104834
  if (typeof entry.type === "string" && entry.type === "final-council" && typeof entry.verdict === "string") {
@@ -104945,7 +105092,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
104945
105092
  let phaseRequiredAgents;
104946
105093
  try {
104947
105094
  const planPath = validateSwarmPath(dir, "plan.json");
104948
- const planRaw = fs84.readFileSync(planPath, "utf-8");
105095
+ const planRaw = fs85.readFileSync(planPath, "utf-8");
104949
105096
  const plan = JSON.parse(planRaw);
104950
105097
  const phaseObj = plan.phases.find((p) => p.id === phase);
104951
105098
  phaseRequiredAgents = phaseObj?.required_agents;
@@ -104960,7 +105107,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
104960
105107
  if (agentsMissing.length > 0) {
104961
105108
  try {
104962
105109
  const planPath = validateSwarmPath(dir, "plan.json");
104963
- const planRaw = fs84.readFileSync(planPath, "utf-8");
105110
+ const planRaw = fs85.readFileSync(planPath, "utf-8");
104964
105111
  const plan = JSON.parse(planRaw);
104965
105112
  const targetPhase = plan.phases.find((p) => p.id === phase);
104966
105113
  if (targetPhase && targetPhase.tasks.length > 0 && canInferMissingAgentsFromTaskGates(agentsMissing) && await allCompletedTasksHavePassedGateEvidence(dir, targetPhase.tasks)) {
@@ -105000,7 +105147,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
105000
105147
  if (phaseCompleteConfig.regression_sweep?.enforce) {
105001
105148
  try {
105002
105149
  const planPath = validateSwarmPath(dir, "plan.json");
105003
- const planRaw = fs84.readFileSync(planPath, "utf-8");
105150
+ const planRaw = fs85.readFileSync(planPath, "utf-8");
105004
105151
  const plan = JSON.parse(planRaw);
105005
105152
  const targetPhase = plan.phases.find((p) => p.id === phase);
105006
105153
  if (targetPhase) {
@@ -105054,7 +105201,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
105054
105201
  }
105055
105202
  try {
105056
105203
  const eventsPath = validateSwarmPath(dir, "events.jsonl");
105057
- fs84.appendFileSync(eventsPath, `${JSON.stringify(event)}
105204
+ fs85.appendFileSync(eventsPath, `${JSON.stringify(event)}
105058
105205
  `, "utf-8");
105059
105206
  } catch (writeError) {
105060
105207
  warnings.push(`Warning: failed to write phase complete event: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
@@ -105129,12 +105276,12 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
105129
105276
  warnings.push(`Warning: failed to update plan.json phase status`);
105130
105277
  try {
105131
105278
  const planPath = validateSwarmPath(dir, "plan.json");
105132
- const planRaw = fs84.readFileSync(planPath, "utf-8");
105279
+ const planRaw = fs85.readFileSync(planPath, "utf-8");
105133
105280
  const plan2 = JSON.parse(planRaw);
105134
105281
  const phaseObj = plan2.phases.find((p) => p.id === phase);
105135
105282
  if (phaseObj) {
105136
105283
  phaseObj.status = "complete";
105137
- fs84.writeFileSync(planPath, JSON.stringify(plan2, null, 2), "utf-8");
105284
+ fs85.writeFileSync(planPath, JSON.stringify(plan2, null, 2), "utf-8");
105138
105285
  }
105139
105286
  } catch {}
105140
105287
  } else if (plan) {
@@ -105171,12 +105318,12 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
105171
105318
  warnings.push(`Warning: failed to update plan.json phase status`);
105172
105319
  try {
105173
105320
  const planPath = validateSwarmPath(dir, "plan.json");
105174
- const planRaw = fs84.readFileSync(planPath, "utf-8");
105321
+ const planRaw = fs85.readFileSync(planPath, "utf-8");
105175
105322
  const plan = JSON.parse(planRaw);
105176
105323
  const phaseObj = plan.phases.find((p) => p.id === phase);
105177
105324
  if (phaseObj) {
105178
105325
  phaseObj.status = "complete";
105179
- fs84.writeFileSync(planPath, JSON.stringify(plan, null, 2), "utf-8");
105326
+ fs85.writeFileSync(planPath, JSON.stringify(plan, null, 2), "utf-8");
105180
105327
  }
105181
105328
  } catch {}
105182
105329
  }
@@ -105234,7 +105381,7 @@ init_discovery();
105234
105381
  init_utils();
105235
105382
  init_bun_compat();
105236
105383
  init_create_tool();
105237
- import * as fs85 from "node:fs";
105384
+ import * as fs86 from "node:fs";
105238
105385
  import * as path112 from "node:path";
105239
105386
  var MAX_OUTPUT_BYTES5 = 52428800;
105240
105387
  var AUDIT_TIMEOUT_MS = 120000;
@@ -105263,31 +105410,31 @@ function validateArgs3(args2) {
105263
105410
  function detectEcosystems(directory) {
105264
105411
  const ecosystems = [];
105265
105412
  const cwd = directory;
105266
- if (fs85.existsSync(path112.join(cwd, "package.json"))) {
105413
+ if (fs86.existsSync(path112.join(cwd, "package.json"))) {
105267
105414
  ecosystems.push("npm");
105268
105415
  }
105269
- if (fs85.existsSync(path112.join(cwd, "pyproject.toml")) || fs85.existsSync(path112.join(cwd, "requirements.txt"))) {
105416
+ if (fs86.existsSync(path112.join(cwd, "pyproject.toml")) || fs86.existsSync(path112.join(cwd, "requirements.txt"))) {
105270
105417
  ecosystems.push("pip");
105271
105418
  }
105272
- if (fs85.existsSync(path112.join(cwd, "Cargo.toml"))) {
105419
+ if (fs86.existsSync(path112.join(cwd, "Cargo.toml"))) {
105273
105420
  ecosystems.push("cargo");
105274
105421
  }
105275
- if (fs85.existsSync(path112.join(cwd, "go.mod"))) {
105422
+ if (fs86.existsSync(path112.join(cwd, "go.mod"))) {
105276
105423
  ecosystems.push("go");
105277
105424
  }
105278
105425
  try {
105279
- const files = fs85.readdirSync(cwd);
105426
+ const files = fs86.readdirSync(cwd);
105280
105427
  if (files.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"))) {
105281
105428
  ecosystems.push("dotnet");
105282
105429
  }
105283
105430
  } catch {}
105284
- if (fs85.existsSync(path112.join(cwd, "Gemfile")) || fs85.existsSync(path112.join(cwd, "Gemfile.lock"))) {
105431
+ if (fs86.existsSync(path112.join(cwd, "Gemfile")) || fs86.existsSync(path112.join(cwd, "Gemfile.lock"))) {
105285
105432
  ecosystems.push("ruby");
105286
105433
  }
105287
- if (fs85.existsSync(path112.join(cwd, "pubspec.yaml"))) {
105434
+ if (fs86.existsSync(path112.join(cwd, "pubspec.yaml"))) {
105288
105435
  ecosystems.push("dart");
105289
105436
  }
105290
- if (fs85.existsSync(path112.join(cwd, "composer.lock"))) {
105437
+ if (fs86.existsSync(path112.join(cwd, "composer.lock"))) {
105291
105438
  ecosystems.push("composer");
105292
105439
  }
105293
105440
  return ecosystems;
@@ -105300,7 +105447,7 @@ async function runNpmAudit(directory) {
105300
105447
  stderr: "pipe",
105301
105448
  cwd: directory
105302
105449
  });
105303
- const timeoutPromise = new Promise((resolve37) => setTimeout(() => resolve37("timeout"), AUDIT_TIMEOUT_MS));
105450
+ const timeoutPromise = new Promise((resolve38) => setTimeout(() => resolve38("timeout"), AUDIT_TIMEOUT_MS));
105304
105451
  const result = await Promise.race([
105305
105452
  Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr2]) => ({ stdout: stdout2, stderr: stderr2 })),
105306
105453
  timeoutPromise
@@ -105420,7 +105567,7 @@ async function runPipAudit(directory) {
105420
105567
  stderr: "pipe",
105421
105568
  cwd: directory
105422
105569
  });
105423
- const timeoutPromise = new Promise((resolve37) => setTimeout(() => resolve37("timeout"), AUDIT_TIMEOUT_MS));
105570
+ const timeoutPromise = new Promise((resolve38) => setTimeout(() => resolve38("timeout"), AUDIT_TIMEOUT_MS));
105424
105571
  const result = await Promise.race([
105425
105572
  Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr2]) => ({ stdout: stdout2, stderr: stderr2 })),
105426
105573
  timeoutPromise
@@ -105548,7 +105695,7 @@ async function runCargoAudit(directory) {
105548
105695
  stderr: "pipe",
105549
105696
  cwd: directory
105550
105697
  });
105551
- const timeoutPromise = new Promise((resolve37) => setTimeout(() => resolve37("timeout"), AUDIT_TIMEOUT_MS));
105698
+ const timeoutPromise = new Promise((resolve38) => setTimeout(() => resolve38("timeout"), AUDIT_TIMEOUT_MS));
105552
105699
  const result = await Promise.race([
105553
105700
  Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
105554
105701
  timeoutPromise
@@ -105672,7 +105819,7 @@ async function runGoAudit(directory) {
105672
105819
  stderr: "pipe",
105673
105820
  cwd: directory
105674
105821
  });
105675
- const timeoutPromise = new Promise((resolve37) => setTimeout(() => resolve37("timeout"), AUDIT_TIMEOUT_MS));
105822
+ const timeoutPromise = new Promise((resolve38) => setTimeout(() => resolve38("timeout"), AUDIT_TIMEOUT_MS));
105676
105823
  const result = await Promise.race([
105677
105824
  Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
105678
105825
  timeoutPromise
@@ -105805,7 +105952,7 @@ async function runDotnetAudit(directory) {
105805
105952
  stderr: "pipe",
105806
105953
  cwd: directory
105807
105954
  });
105808
- const timeoutPromise = new Promise((resolve37) => setTimeout(() => resolve37("timeout"), AUDIT_TIMEOUT_MS));
105955
+ const timeoutPromise = new Promise((resolve38) => setTimeout(() => resolve38("timeout"), AUDIT_TIMEOUT_MS));
105809
105956
  const result = await Promise.race([
105810
105957
  Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
105811
105958
  timeoutPromise
@@ -105921,7 +106068,7 @@ async function runBundleAudit(directory) {
105921
106068
  stderr: "pipe",
105922
106069
  cwd: directory
105923
106070
  });
105924
- const timeoutPromise = new Promise((resolve37) => setTimeout(() => resolve37("timeout"), AUDIT_TIMEOUT_MS));
106071
+ const timeoutPromise = new Promise((resolve38) => setTimeout(() => resolve38("timeout"), AUDIT_TIMEOUT_MS));
105925
106072
  const result = await Promise.race([
105926
106073
  Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
105927
106074
  timeoutPromise
@@ -106066,7 +106213,7 @@ async function runDartAudit(directory) {
106066
106213
  stderr: "pipe",
106067
106214
  cwd: directory
106068
106215
  });
106069
- const timeoutPromise = new Promise((resolve37) => setTimeout(() => resolve37("timeout"), AUDIT_TIMEOUT_MS));
106216
+ const timeoutPromise = new Promise((resolve38) => setTimeout(() => resolve38("timeout"), AUDIT_TIMEOUT_MS));
106070
106217
  const result = await Promise.race([
106071
106218
  Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
106072
106219
  timeoutPromise
@@ -106181,7 +106328,7 @@ async function runComposerAudit(directory) {
106181
106328
  stderr: "pipe",
106182
106329
  cwd: directory
106183
106330
  });
106184
- const timeoutPromise = new Promise((resolve37) => setTimeout(() => resolve37("timeout"), AUDIT_TIMEOUT_MS));
106331
+ const timeoutPromise = new Promise((resolve38) => setTimeout(() => resolve38("timeout"), AUDIT_TIMEOUT_MS));
106185
106332
  const result = await Promise.race([
106186
106333
  Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
106187
106334
  timeoutPromise
@@ -106422,7 +106569,7 @@ var pkg_audit = createSwarmTool({
106422
106569
  // src/tools/placeholder-scan.ts
106423
106570
  init_zod();
106424
106571
  init_manager2();
106425
- import * as fs86 from "node:fs";
106572
+ import * as fs87 from "node:fs";
106426
106573
  import * as path113 from "node:path";
106427
106574
  init_utils();
106428
106575
  init_create_tool();
@@ -106824,7 +106971,7 @@ async function placeholderScan(input, directory) {
106824
106971
  if (!fullPath.startsWith(resolvedDirectory + path113.sep) && fullPath !== resolvedDirectory) {
106825
106972
  continue;
106826
106973
  }
106827
- if (!fs86.existsSync(fullPath)) {
106974
+ if (!fs87.existsSync(fullPath)) {
106828
106975
  continue;
106829
106976
  }
106830
106977
  if (isAllowedByGlobs(filePath, allow_globs)) {
@@ -106836,11 +106983,11 @@ async function placeholderScan(input, directory) {
106836
106983
  }
106837
106984
  let content;
106838
106985
  try {
106839
- const stat8 = fs86.statSync(fullPath);
106986
+ const stat8 = fs87.statSync(fullPath);
106840
106987
  if (stat8.size > MAX_FILE_SIZE) {
106841
106988
  continue;
106842
106989
  }
106843
- content = fs86.readFileSync(fullPath, "utf-8");
106990
+ content = fs87.readFileSync(fullPath, "utf-8");
106844
106991
  } catch {
106845
106992
  continue;
106846
106993
  }
@@ -106901,7 +107048,7 @@ var placeholder_scan = createSwarmTool({
106901
107048
  }
106902
107049
  });
106903
107050
  // src/tools/pre-check-batch.ts
106904
- import * as fs90 from "node:fs";
107051
+ import * as fs91 from "node:fs";
106905
107052
  import * as path117 from "node:path";
106906
107053
  init_zod();
106907
107054
  init_manager2();
@@ -107042,7 +107189,7 @@ var _internals45 = {
107042
107189
  init_zod();
107043
107190
  init_manager2();
107044
107191
  init_detector();
107045
- import * as fs89 from "node:fs";
107192
+ import * as fs90 from "node:fs";
107046
107193
  import * as path116 from "node:path";
107047
107194
  import { extname as extname20 } from "node:path";
107048
107195
 
@@ -107758,7 +107905,7 @@ function executeRulesSync(filePath, content, language) {
107758
107905
 
107759
107906
  // src/sast/semgrep.ts
107760
107907
  import * as child_process9 from "node:child_process";
107761
- import * as fs87 from "node:fs";
107908
+ import * as fs88 from "node:fs";
107762
107909
  import * as path114 from "node:path";
107763
107910
  var semgrepAvailableCache = null;
107764
107911
  var DEFAULT_RULES_DIR = ".swarm/semgrep-rules";
@@ -107840,7 +107987,7 @@ function mapSemgrepSeverity(severity) {
107840
107987
  }
107841
107988
  }
107842
107989
  async function executeWithTimeout(command, args2, options) {
107843
- return new Promise((resolve39) => {
107990
+ return new Promise((resolve40) => {
107844
107991
  const child = child_process9.spawn(command, args2, {
107845
107992
  shell: false,
107846
107993
  cwd: options.cwd
@@ -107849,7 +107996,7 @@ async function executeWithTimeout(command, args2, options) {
107849
107996
  let stderr = "";
107850
107997
  const timeout = setTimeout(() => {
107851
107998
  child.kill("SIGTERM");
107852
- resolve39({
107999
+ resolve40({
107853
108000
  stdout,
107854
108001
  stderr: "Process timed out",
107855
108002
  exitCode: 124
@@ -107863,7 +108010,7 @@ async function executeWithTimeout(command, args2, options) {
107863
108010
  });
107864
108011
  child.on("close", (code) => {
107865
108012
  clearTimeout(timeout);
107866
- resolve39({
108013
+ resolve40({
107867
108014
  stdout,
107868
108015
  stderr,
107869
108016
  exitCode: code ?? 0
@@ -107871,7 +108018,7 @@ async function executeWithTimeout(command, args2, options) {
107871
108018
  });
107872
108019
  child.on("error", (err2) => {
107873
108020
  clearTimeout(timeout);
107874
- resolve39({
108021
+ resolve40({
107875
108022
  stdout,
107876
108023
  stderr: err2.message,
107877
108024
  exitCode: 1
@@ -107953,7 +108100,7 @@ function getRulesDirectory(projectRoot) {
107953
108100
  function hasBundledRules(projectRoot) {
107954
108101
  const rulesDir = getRulesDirectory(projectRoot);
107955
108102
  try {
107956
- return fs87.existsSync(rulesDir);
108103
+ return fs88.existsSync(rulesDir);
107957
108104
  } catch {
107958
108105
  return false;
107959
108106
  }
@@ -107966,7 +108113,7 @@ init_create_tool();
107966
108113
  // src/tools/sast-baseline.ts
107967
108114
  init_utils2();
107968
108115
  import * as crypto10 from "node:crypto";
107969
- import * as fs88 from "node:fs";
108116
+ import * as fs89 from "node:fs";
107970
108117
  import * as path115 from "node:path";
107971
108118
  var BASELINE_SCHEMA_VERSION = "1.0.0";
107972
108119
  var MAX_BASELINE_FINDINGS = 2000;
@@ -108001,7 +108148,7 @@ function fingerprintFinding(finding, directory, occurrenceIndex) {
108001
108148
  }
108002
108149
  const lineNum = finding.location.line;
108003
108150
  try {
108004
- const content = fs88.readFileSync(finding.location.file, "utf-8");
108151
+ const content = fs89.readFileSync(finding.location.file, "utf-8");
108005
108152
  const lines = content.split(`
108006
108153
  `);
108007
108154
  const idx = lineNum - 1;
@@ -108032,7 +108179,7 @@ function assignOccurrenceIndices(findings, directory) {
108032
108179
  try {
108033
108180
  if (relFile.startsWith(".."))
108034
108181
  throw new Error("escapes workspace");
108035
- const content = fs88.readFileSync(finding.location.file, "utf-8");
108182
+ const content = fs89.readFileSync(finding.location.file, "utf-8");
108036
108183
  const lines = content.split(`
108037
108184
  `);
108038
108185
  const idx = lineNum - 1;
@@ -108061,16 +108208,16 @@ function assignOccurrenceIndices(findings, directory) {
108061
108208
  async function acquireLock2(lockPath) {
108062
108209
  for (let attempt = 0;attempt <= LOCK_RETRY_DELAYS_MS.length; attempt++) {
108063
108210
  try {
108064
- const fd = fs88.openSync(lockPath, "wx");
108065
- fs88.closeSync(fd);
108211
+ const fd = fs89.openSync(lockPath, "wx");
108212
+ fs89.closeSync(fd);
108066
108213
  return () => {
108067
108214
  try {
108068
- fs88.unlinkSync(lockPath);
108215
+ fs89.unlinkSync(lockPath);
108069
108216
  } catch {}
108070
108217
  };
108071
108218
  } catch {
108072
108219
  if (attempt < LOCK_RETRY_DELAYS_MS.length) {
108073
- await new Promise((resolve40) => setTimeout(resolve40, LOCK_RETRY_DELAYS_MS[attempt]));
108220
+ await new Promise((resolve41) => setTimeout(resolve41, LOCK_RETRY_DELAYS_MS[attempt]));
108074
108221
  }
108075
108222
  }
108076
108223
  }
@@ -108105,13 +108252,13 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
108105
108252
  message: e instanceof Error ? e.message : "Path validation failed"
108106
108253
  };
108107
108254
  }
108108
- fs88.mkdirSync(path115.dirname(baselinePath), { recursive: true });
108109
- fs88.mkdirSync(path115.dirname(tempPath), { recursive: true });
108255
+ fs89.mkdirSync(path115.dirname(baselinePath), { recursive: true });
108256
+ fs89.mkdirSync(path115.dirname(tempPath), { recursive: true });
108110
108257
  const releaseLock = await acquireLock2(lockPath);
108111
108258
  try {
108112
108259
  let existing = null;
108113
108260
  try {
108114
- const raw = fs88.readFileSync(baselinePath, "utf-8");
108261
+ const raw = fs89.readFileSync(baselinePath, "utf-8");
108115
108262
  const parsed = JSON.parse(raw);
108116
108263
  if (parsed.schema_version === BASELINE_SCHEMA_VERSION) {
108117
108264
  existing = parsed;
@@ -108171,8 +108318,8 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
108171
108318
  message: `Baseline would exceed size cap (${json4.length} bytes > ${MAX_BASELINE_BYTES})`
108172
108319
  };
108173
108320
  }
108174
- fs88.writeFileSync(tempPath, json4, "utf-8");
108175
- fs88.renameSync(tempPath, baselinePath);
108321
+ fs89.writeFileSync(tempPath, json4, "utf-8");
108322
+ fs89.renameSync(tempPath, baselinePath);
108176
108323
  return {
108177
108324
  status: "merged",
108178
108325
  path: baselinePath,
@@ -108203,8 +108350,8 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
108203
108350
  message: `Baseline would exceed size cap (${json3.length} bytes > ${MAX_BASELINE_BYTES})`
108204
108351
  };
108205
108352
  }
108206
- fs88.writeFileSync(tempPath, json3, "utf-8");
108207
- fs88.renameSync(tempPath, baselinePath);
108353
+ fs89.writeFileSync(tempPath, json3, "utf-8");
108354
+ fs89.renameSync(tempPath, baselinePath);
108208
108355
  return {
108209
108356
  status: "written",
108210
108357
  path: baselinePath,
@@ -108229,7 +108376,7 @@ function loadBaseline(directory, phase) {
108229
108376
  };
108230
108377
  }
108231
108378
  try {
108232
- const raw = fs88.readFileSync(baselinePath, "utf-8");
108379
+ const raw = fs89.readFileSync(baselinePath, "utf-8");
108233
108380
  const parsed = JSON.parse(raw);
108234
108381
  if (parsed.schema_version !== BASELINE_SCHEMA_VERSION) {
108235
108382
  return {
@@ -108277,17 +108424,17 @@ var SEVERITY_ORDER = {
108277
108424
  };
108278
108425
  function shouldSkipFile(filePath) {
108279
108426
  try {
108280
- const stats = fs89.statSync(filePath);
108427
+ const stats = fs90.statSync(filePath);
108281
108428
  if (stats.size > MAX_FILE_SIZE_BYTES8) {
108282
108429
  return { skip: true, reason: "file too large" };
108283
108430
  }
108284
108431
  if (stats.size === 0) {
108285
108432
  return { skip: true, reason: "empty file" };
108286
108433
  }
108287
- const fd = fs89.openSync(filePath, "r");
108434
+ const fd = fs90.openSync(filePath, "r");
108288
108435
  const buffer = Buffer.alloc(8192);
108289
- const bytesRead = fs89.readSync(fd, buffer, 0, 8192, 0);
108290
- fs89.closeSync(fd);
108436
+ const bytesRead = fs90.readSync(fd, buffer, 0, 8192, 0);
108437
+ fs90.closeSync(fd);
108291
108438
  if (bytesRead > 0) {
108292
108439
  let nullCount = 0;
108293
108440
  for (let i2 = 0;i2 < bytesRead; i2++) {
@@ -108326,7 +108473,7 @@ function countBySeverity(findings) {
108326
108473
  }
108327
108474
  function scanFileWithTierA(filePath, language) {
108328
108475
  try {
108329
- const content = fs89.readFileSync(filePath, "utf-8");
108476
+ const content = fs90.readFileSync(filePath, "utf-8");
108330
108477
  const findings = executeRulesSync(filePath, content, language);
108331
108478
  return findings.map((f) => ({
108332
108479
  rule_id: f.rule_id,
@@ -108385,7 +108532,7 @@ async function sastScan(input, directory, config3) {
108385
108532
  _filesSkipped++;
108386
108533
  continue;
108387
108534
  }
108388
- if (!fs89.existsSync(resolvedPath)) {
108535
+ if (!fs90.existsSync(resolvedPath)) {
108389
108536
  _filesSkipped++;
108390
108537
  continue;
108391
108538
  }
@@ -108954,7 +109101,7 @@ async function runSecretscanWithFiles(files, directory) {
108954
109101
  }
108955
109102
  let stat8;
108956
109103
  try {
108957
- stat8 = fs90.statSync(file3);
109104
+ stat8 = fs91.statSync(file3);
108958
109105
  } catch {
108959
109106
  skippedFiles++;
108960
109107
  continue;
@@ -108965,7 +109112,7 @@ async function runSecretscanWithFiles(files, directory) {
108965
109112
  }
108966
109113
  let content;
108967
109114
  try {
108968
- const buffer = fs90.readFileSync(file3);
109115
+ const buffer = fs91.readFileSync(file3);
108969
109116
  if (buffer.includes(0)) {
108970
109117
  skippedFiles++;
108971
109118
  continue;
@@ -109664,7 +109811,7 @@ var repo_map = createSwarmTool({
109664
109811
  // src/tools/req-coverage.ts
109665
109812
  init_zod();
109666
109813
  init_create_tool();
109667
- import * as fs91 from "node:fs";
109814
+ import * as fs92 from "node:fs";
109668
109815
  import * as path119 from "node:path";
109669
109816
  var SPEC_FILE = ".swarm/spec.md";
109670
109817
  var EVIDENCE_DIR4 = ".swarm/evidence";
@@ -109724,19 +109871,19 @@ function extractObligationAndText(id, lineText) {
109724
109871
  var PHASE_TASK_ID_REGEX = /^\d+\.\d+(\.\d+)*$/;
109725
109872
  function readTouchedFiles(evidenceDir, phase, cwd) {
109726
109873
  const touchedFiles = new Set;
109727
- if (!fs91.existsSync(evidenceDir) || !fs91.statSync(evidenceDir).isDirectory()) {
109874
+ if (!fs92.existsSync(evidenceDir) || !fs92.statSync(evidenceDir).isDirectory()) {
109728
109875
  return [];
109729
109876
  }
109730
109877
  let entries;
109731
109878
  try {
109732
- entries = fs91.readdirSync(evidenceDir);
109879
+ entries = fs92.readdirSync(evidenceDir);
109733
109880
  } catch {
109734
109881
  return [];
109735
109882
  }
109736
109883
  for (const entry of entries) {
109737
109884
  const entryPath = path119.join(evidenceDir, entry);
109738
109885
  try {
109739
- const stat8 = fs91.statSync(entryPath);
109886
+ const stat8 = fs92.statSync(entryPath);
109740
109887
  if (!stat8.isDirectory()) {
109741
109888
  continue;
109742
109889
  }
@@ -109757,7 +109904,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
109757
109904
  if (!resolvedPath.startsWith(evidenceDirResolved + path119.sep)) {
109758
109905
  continue;
109759
109906
  }
109760
- const stat8 = fs91.lstatSync(evidenceFilePath);
109907
+ const stat8 = fs92.lstatSync(evidenceFilePath);
109761
109908
  if (!stat8.isFile()) {
109762
109909
  continue;
109763
109910
  }
@@ -109769,7 +109916,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
109769
109916
  }
109770
109917
  let content;
109771
109918
  try {
109772
- content = fs91.readFileSync(evidenceFilePath, "utf-8");
109919
+ content = fs92.readFileSync(evidenceFilePath, "utf-8");
109773
109920
  } catch {
109774
109921
  continue;
109775
109922
  }
@@ -109806,7 +109953,7 @@ function searchFileForKeywords(filePath, keywords, cwd) {
109806
109953
  if (!resolvedPath.startsWith(cwdResolved)) {
109807
109954
  return false;
109808
109955
  }
109809
- const content = fs91.readFileSync(resolvedPath, "utf-8");
109956
+ const content = fs92.readFileSync(resolvedPath, "utf-8");
109810
109957
  for (const keyword of keywords) {
109811
109958
  const regex = new RegExp(`\\b${keyword}\\b`, "i");
109812
109959
  if (regex.test(content)) {
@@ -109939,7 +110086,7 @@ var req_coverage = createSwarmTool({
109939
110086
  const specPath = path119.join(cwd, SPEC_FILE);
109940
110087
  let specContent;
109941
110088
  try {
109942
- specContent = fs91.readFileSync(specPath, "utf-8");
110089
+ specContent = fs92.readFileSync(specPath, "utf-8");
109943
110090
  } catch (readError) {
109944
110091
  return JSON.stringify({
109945
110092
  success: false,
@@ -109991,10 +110138,10 @@ var req_coverage = createSwarmTool({
109991
110138
  const reportFilename = `req-coverage-phase-${phase}.json`;
109992
110139
  const reportPath = path119.join(evidenceDir, reportFilename);
109993
110140
  try {
109994
- if (!fs91.existsSync(evidenceDir)) {
109995
- fs91.mkdirSync(evidenceDir, { recursive: true });
110141
+ if (!fs92.existsSync(evidenceDir)) {
110142
+ fs92.mkdirSync(evidenceDir, { recursive: true });
109996
110143
  }
109997
- fs91.writeFileSync(reportPath, JSON.stringify(result, null, 2), "utf-8");
110144
+ fs92.writeFileSync(reportPath, JSON.stringify(result, null, 2), "utf-8");
109998
110145
  } catch (writeError) {
109999
110146
  console.warn(`Failed to write coverage report: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
110000
110147
  }
@@ -110076,7 +110223,7 @@ init_plan_schema();
110076
110223
  init_qa_gate_profile();
110077
110224
  init_file_locks();
110078
110225
  import * as crypto11 from "node:crypto";
110079
- import * as fs92 from "node:fs";
110226
+ import * as fs93 from "node:fs";
110080
110227
  import * as path120 from "node:path";
110081
110228
  init_ledger();
110082
110229
  init_manager();
@@ -110159,7 +110306,7 @@ async function executeSavePlan(args2, fallbackDir) {
110159
110306
  const resolvedRoot = path120.resolve(fallbackDir);
110160
110307
  let fallbackExists = false;
110161
110308
  try {
110162
- fs92.accessSync(resolvedRoot, fs92.constants.F_OK);
110309
+ fs93.accessSync(resolvedRoot, fs93.constants.F_OK);
110163
110310
  fallbackExists = true;
110164
110311
  } catch {
110165
110312
  fallbackExists = false;
@@ -110183,9 +110330,9 @@ async function executeSavePlan(args2, fallbackDir) {
110183
110330
  if (process.env.SWARM_SKIP_SPEC_GATE !== "1") {
110184
110331
  const specPath = path120.join(targetWorkspace, ".swarm", "spec.md");
110185
110332
  try {
110186
- const stat8 = await fs92.promises.stat(specPath);
110333
+ const stat8 = await fs93.promises.stat(specPath);
110187
110334
  specMtime = stat8.mtime.toISOString();
110188
- const content = await fs92.promises.readFile(specPath, "utf8");
110335
+ const content = await fs93.promises.readFile(specPath, "utf8");
110189
110336
  specHash = crypto11.createHash("sha256").update(content).digest("hex");
110190
110337
  } catch {
110191
110338
  return {
@@ -110200,7 +110347,7 @@ async function executeSavePlan(args2, fallbackDir) {
110200
110347
  const contextPath = path120.join(targetWorkspace, ".swarm", "context.md");
110201
110348
  let contextContent = "";
110202
110349
  try {
110203
- contextContent = await fs92.promises.readFile(contextPath, "utf8");
110350
+ contextContent = await fs93.promises.readFile(contextPath, "utf8");
110204
110351
  } catch {}
110205
110352
  const hasPendingSection = contextContent.includes("## Pending QA Gate Selection");
110206
110353
  if (!hasPendingSection) {
@@ -110461,7 +110608,7 @@ async function executeSavePlan(args2, fallbackDir) {
110461
110608
  phases_count: plan.phases.length,
110462
110609
  tasks_count: tasksCount
110463
110610
  });
110464
- await fs92.promises.writeFile(markerPath, marker, "utf8");
110611
+ await fs93.promises.writeFile(markerPath, marker, "utf8");
110465
110612
  } catch {}
110466
110613
  const warnings = [];
110467
110614
  let criticReviewFound = false;
@@ -110541,7 +110688,7 @@ var save_plan = createSwarmTool({
110541
110688
  // src/tools/sbom-generate.ts
110542
110689
  init_zod();
110543
110690
  init_manager2();
110544
- import * as fs93 from "node:fs";
110691
+ import * as fs94 from "node:fs";
110545
110692
  import * as path121 from "node:path";
110546
110693
 
110547
110694
  // src/sbom/detectors/index.ts
@@ -111390,7 +111537,7 @@ function findManifestFiles(rootDir) {
111390
111537
  const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
111391
111538
  function searchDir(dir) {
111392
111539
  try {
111393
- const entries = fs93.readdirSync(dir, { withFileTypes: true });
111540
+ const entries = fs94.readdirSync(dir, { withFileTypes: true });
111394
111541
  for (const entry of entries) {
111395
111542
  const fullPath = path121.join(dir, entry.name);
111396
111543
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
@@ -111417,7 +111564,7 @@ function findManifestFilesInDirs(directories, workingDir) {
111417
111564
  const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
111418
111565
  for (const dir of directories) {
111419
111566
  try {
111420
- const entries = fs93.readdirSync(dir, { withFileTypes: true });
111567
+ const entries = fs94.readdirSync(dir, { withFileTypes: true });
111421
111568
  for (const entry of entries) {
111422
111569
  const fullPath = path121.join(dir, entry.name);
111423
111570
  if (entry.isFile()) {
@@ -111454,7 +111601,7 @@ function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
111454
111601
  }
111455
111602
  function ensureOutputDir(outputDir) {
111456
111603
  try {
111457
- fs93.mkdirSync(outputDir, { recursive: true });
111604
+ fs94.mkdirSync(outputDir, { recursive: true });
111458
111605
  } catch (error93) {
111459
111606
  if (!error93 || error93.code !== "EEXIST") {
111460
111607
  throw error93;
@@ -111548,10 +111695,10 @@ var sbom_generate = createSwarmTool({
111548
111695
  for (const manifestFile of manifestFiles) {
111549
111696
  try {
111550
111697
  const fullPath = path121.isAbsolute(manifestFile) ? manifestFile : path121.join(workingDir, manifestFile);
111551
- if (!fs93.existsSync(fullPath)) {
111698
+ if (!fs94.existsSync(fullPath)) {
111552
111699
  continue;
111553
111700
  }
111554
- const content = fs93.readFileSync(fullPath, "utf-8");
111701
+ const content = fs94.readFileSync(fullPath, "utf-8");
111555
111702
  const components = detectComponents(manifestFile, content);
111556
111703
  processedFiles.push(manifestFile);
111557
111704
  if (components.length > 0) {
@@ -111565,7 +111712,7 @@ var sbom_generate = createSwarmTool({
111565
111712
  const bomJson = serializeCycloneDX(bom);
111566
111713
  const filename = generateSbomFilename();
111567
111714
  const outputPath = path121.join(outputDir, filename);
111568
- fs93.writeFileSync(outputPath, bomJson, "utf-8");
111715
+ fs94.writeFileSync(outputPath, bomJson, "utf-8");
111569
111716
  const verdict = processedFiles.length > 0 ? "pass" : "pass";
111570
111717
  try {
111571
111718
  const timestamp = new Date().toISOString();
@@ -111607,7 +111754,7 @@ var sbom_generate = createSwarmTool({
111607
111754
  // src/tools/schema-drift.ts
111608
111755
  init_zod();
111609
111756
  init_create_tool();
111610
- import * as fs94 from "node:fs";
111757
+ import * as fs95 from "node:fs";
111611
111758
  import * as path122 from "node:path";
111612
111759
  var SPEC_CANDIDATES = [
111613
111760
  "openapi.json",
@@ -111649,19 +111796,19 @@ function discoverSpecFile(cwd, specFileArg) {
111649
111796
  if (!ALLOWED_EXTENSIONS.includes(ext)) {
111650
111797
  throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
111651
111798
  }
111652
- const stats = fs94.statSync(resolvedPath);
111799
+ const stats = fs95.statSync(resolvedPath);
111653
111800
  if (stats.size > MAX_SPEC_SIZE) {
111654
111801
  throw new Error(`Invalid spec_file: file exceeds ${MAX_SPEC_SIZE / 1024 / 1024}MB limit`);
111655
111802
  }
111656
- if (!fs94.existsSync(resolvedPath)) {
111803
+ if (!fs95.existsSync(resolvedPath)) {
111657
111804
  throw new Error(`Spec file not found: ${resolvedPath}`);
111658
111805
  }
111659
111806
  return resolvedPath;
111660
111807
  }
111661
111808
  for (const candidate of SPEC_CANDIDATES) {
111662
111809
  const candidatePath = path122.resolve(cwd, candidate);
111663
- if (fs94.existsSync(candidatePath)) {
111664
- const stats = fs94.statSync(candidatePath);
111810
+ if (fs95.existsSync(candidatePath)) {
111811
+ const stats = fs95.statSync(candidatePath);
111665
111812
  if (stats.size <= MAX_SPEC_SIZE) {
111666
111813
  return candidatePath;
111667
111814
  }
@@ -111670,7 +111817,7 @@ function discoverSpecFile(cwd, specFileArg) {
111670
111817
  return null;
111671
111818
  }
111672
111819
  function parseSpec(specFile) {
111673
- const content = fs94.readFileSync(specFile, "utf-8");
111820
+ const content = fs95.readFileSync(specFile, "utf-8");
111674
111821
  const ext = path122.extname(specFile).toLowerCase();
111675
111822
  if (ext === ".json") {
111676
111823
  return parseJsonSpec(content);
@@ -111742,7 +111889,7 @@ function extractRoutes(cwd) {
111742
111889
  function walkDir(dir) {
111743
111890
  let entries;
111744
111891
  try {
111745
- entries = fs94.readdirSync(dir, { withFileTypes: true });
111892
+ entries = fs95.readdirSync(dir, { withFileTypes: true });
111746
111893
  } catch {
111747
111894
  return;
111748
111895
  }
@@ -111775,7 +111922,7 @@ function extractRoutes(cwd) {
111775
111922
  }
111776
111923
  function extractRoutesFromFile(filePath) {
111777
111924
  const routes = [];
111778
- const content = fs94.readFileSync(filePath, "utf-8");
111925
+ const content = fs95.readFileSync(filePath, "utf-8");
111779
111926
  const lines = content.split(/\r?\n/);
111780
111927
  const expressRegex = /(?:app|router|server|express)\.(get|post|put|patch|delete|options|head)\s*\(\s*['"`]([^'"`]+)['"`]/g;
111781
111928
  const flaskRegex = /@(?:app|blueprint|bp)\.route\s*\(\s*['"]([^'"]+)['"]/g;
@@ -111924,7 +112071,7 @@ init_zod();
111924
112071
  init_bun_compat();
111925
112072
  init_path_security();
111926
112073
  init_create_tool();
111927
- import * as fs95 from "node:fs";
112074
+ import * as fs96 from "node:fs";
111928
112075
  import * as path123 from "node:path";
111929
112076
  var DEFAULT_MAX_RESULTS = 100;
111930
112077
  var DEFAULT_MAX_LINES = 200;
@@ -111962,8 +112109,8 @@ function containsWindowsAttacks3(str) {
111962
112109
  function isPathInWorkspace3(filePath, workspace) {
111963
112110
  try {
111964
112111
  const resolvedPath = path123.resolve(workspace, filePath);
111965
- const realWorkspace = fs95.realpathSync(workspace);
111966
- const realResolvedPath = fs95.realpathSync(resolvedPath);
112112
+ const realWorkspace = fs96.realpathSync(workspace);
112113
+ const realResolvedPath = fs96.realpathSync(resolvedPath);
111967
112114
  const relativePath = path123.relative(realWorkspace, realResolvedPath);
111968
112115
  if (relativePath.startsWith("..") || path123.isAbsolute(relativePath)) {
111969
112116
  return false;
@@ -111983,7 +112130,7 @@ function findRgInEnvPath() {
111983
112130
  continue;
111984
112131
  const isWindows = process.platform === "win32";
111985
112132
  const candidate = path123.join(dir, isWindows ? "rg.exe" : "rg");
111986
- if (fs95.existsSync(candidate))
112133
+ if (fs96.existsSync(candidate))
111987
112134
  return candidate;
111988
112135
  }
111989
112136
  return null;
@@ -112037,7 +112184,7 @@ async function ripgrepSearch(opts) {
112037
112184
  stderr: "pipe",
112038
112185
  cwd: opts.workspace
112039
112186
  });
112040
- const timeout = new Promise((resolve46) => setTimeout(() => resolve46("timeout"), REGEX_TIMEOUT_MS));
112187
+ const timeout = new Promise((resolve47) => setTimeout(() => resolve47("timeout"), REGEX_TIMEOUT_MS));
112041
112188
  const exitPromise = proc.exited;
112042
112189
  const result = await Promise.race([exitPromise, timeout]);
112043
112190
  if (result === "timeout") {
@@ -112110,7 +112257,7 @@ function collectFiles(dir, workspace, includeGlobs, excludeGlobs) {
112110
112257
  return files;
112111
112258
  }
112112
112259
  try {
112113
- const entries = fs95.readdirSync(dir, { withFileTypes: true });
112260
+ const entries = fs96.readdirSync(dir, { withFileTypes: true });
112114
112261
  for (const entry of entries) {
112115
112262
  const fullPath = path123.join(dir, entry.name);
112116
112263
  const relativePath = path123.relative(workspace, fullPath);
@@ -112160,7 +112307,7 @@ async function fallbackSearch(opts) {
112160
112307
  }
112161
112308
  let stats;
112162
112309
  try {
112163
- stats = fs95.statSync(fullPath);
112310
+ stats = fs96.statSync(fullPath);
112164
112311
  if (stats.size > MAX_FILE_SIZE_BYTES10) {
112165
112312
  continue;
112166
112313
  }
@@ -112169,7 +112316,7 @@ async function fallbackSearch(opts) {
112169
112316
  }
112170
112317
  let content;
112171
112318
  try {
112172
- content = fs95.readFileSync(fullPath, "utf-8");
112319
+ content = fs96.readFileSync(fullPath, "utf-8");
112173
112320
  } catch {
112174
112321
  continue;
112175
112322
  }
@@ -112281,7 +112428,7 @@ var search = createSwarmTool({
112281
112428
  message: "Exclude pattern contains invalid Windows-specific sequence"
112282
112429
  }, null, 2);
112283
112430
  }
112284
- if (!fs95.existsSync(directory)) {
112431
+ if (!fs96.existsSync(directory)) {
112285
112432
  return JSON.stringify({
112286
112433
  error: true,
112287
112434
  type: "unknown",
@@ -112569,8 +112716,8 @@ var spec_write = createSwarmTool({
112569
112716
  let finalContent = content;
112570
112717
  if (mode === "append") {
112571
112718
  try {
112572
- const fs96 = await import("node:fs/promises");
112573
- const prior = await fs96.readFile(target, "utf-8");
112719
+ const fs97 = await import("node:fs/promises");
112720
+ const prior = await fs97.readFile(target, "utf-8");
112574
112721
  finalContent = `${prior.replace(/\s+$/, "")}
112575
112722
 
112576
112723
  ${content}
@@ -112878,7 +113025,7 @@ function createSwarmCommandTool(agents) {
112878
113025
  init_zod();
112879
113026
  init_path_security();
112880
113027
  init_create_tool();
112881
- import * as fs96 from "node:fs";
113028
+ import * as fs97 from "node:fs";
112882
113029
  import * as path126 from "node:path";
112883
113030
  var WINDOWS_RESERVED_NAMES4 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
112884
113031
  function containsWindowsAttacks4(str) {
@@ -112894,11 +113041,11 @@ function containsWindowsAttacks4(str) {
112894
113041
  function isPathInWorkspace4(filePath, workspace) {
112895
113042
  try {
112896
113043
  const resolvedPath = path126.resolve(workspace, filePath);
112897
- if (!fs96.existsSync(resolvedPath)) {
113044
+ if (!fs97.existsSync(resolvedPath)) {
112898
113045
  return true;
112899
113046
  }
112900
- const realWorkspace = fs96.realpathSync(workspace);
112901
- const realResolvedPath = fs96.realpathSync(resolvedPath);
113047
+ const realWorkspace = fs97.realpathSync(workspace);
113048
+ const realResolvedPath = fs97.realpathSync(resolvedPath);
112902
113049
  const relativePath = path126.relative(realWorkspace, realResolvedPath);
112903
113050
  if (relativePath.startsWith("..") || path126.isAbsolute(relativePath)) {
112904
113051
  return false;
@@ -113072,7 +113219,7 @@ var suggestPatch = createSwarmTool({
113072
113219
  message: "changes cannot be empty"
113073
113220
  }, null, 2);
113074
113221
  }
113075
- if (!fs96.existsSync(directory)) {
113222
+ if (!fs97.existsSync(directory)) {
113076
113223
  return JSON.stringify({
113077
113224
  success: false,
113078
113225
  error: true,
@@ -113109,7 +113256,7 @@ var suggestPatch = createSwarmTool({
113109
113256
  continue;
113110
113257
  }
113111
113258
  const fullPath = path126.resolve(directory, change.file);
113112
- if (!fs96.existsSync(fullPath)) {
113259
+ if (!fs97.existsSync(fullPath)) {
113113
113260
  errors5.push({
113114
113261
  success: false,
113115
113262
  error: true,
@@ -113123,7 +113270,7 @@ var suggestPatch = createSwarmTool({
113123
113270
  }
113124
113271
  let content;
113125
113272
  try {
113126
- content = fs96.readFileSync(fullPath, "utf-8");
113273
+ content = fs97.readFileSync(fullPath, "utf-8");
113127
113274
  } catch (err3) {
113128
113275
  errors5.push({
113129
113276
  success: false,
@@ -113411,11 +113558,11 @@ var lean_turbo_acquire_locks = createSwarmTool({
113411
113558
  // src/tools/lean-turbo-plan-lanes.ts
113412
113559
  init_zod();
113413
113560
  init_constants();
113414
- import * as fs98 from "node:fs";
113561
+ import * as fs99 from "node:fs";
113415
113562
  import * as path128 from "node:path";
113416
113563
 
113417
113564
  // src/turbo/lean/conflicts.ts
113418
- import * as fs97 from "node:fs";
113565
+ import * as fs98 from "node:fs";
113419
113566
  import * as path127 from "node:path";
113420
113567
  var DEFAULT_GLOBAL_FILES = [
113421
113568
  "package.json",
@@ -113545,10 +113692,10 @@ function isProtectedPath2(normalizedPath) {
113545
113692
  function readTaskScopes(directory, taskId) {
113546
113693
  const scopePath = path127.join(directory, ".swarm", "scopes", `scope-${taskId}.json`);
113547
113694
  try {
113548
- if (!fs97.existsSync(scopePath)) {
113695
+ if (!fs98.existsSync(scopePath)) {
113549
113696
  return null;
113550
113697
  }
113551
- const raw = fs97.readFileSync(scopePath, "utf-8");
113698
+ const raw = fs98.readFileSync(scopePath, "utf-8");
113552
113699
  const parsed = JSON.parse(raw);
113553
113700
  if (!parsed || !Array.isArray(parsed.files)) {
113554
113701
  return null;
@@ -113932,11 +114079,11 @@ function createEmptyPlan(phaseNumber, planId) {
113932
114079
  init_create_tool();
113933
114080
  function readPlanJson(directory) {
113934
114081
  const planPath = path128.join(directory, ".swarm", "plan.json");
113935
- if (!fs98.existsSync(planPath)) {
114082
+ if (!fs99.existsSync(planPath)) {
113936
114083
  return null;
113937
114084
  }
113938
114085
  try {
113939
- return JSON.parse(fs98.readFileSync(planPath, "utf-8"));
114086
+ return JSON.parse(fs99.readFileSync(planPath, "utf-8"));
113940
114087
  } catch {
113941
114088
  return null;
113942
114089
  }
@@ -113985,7 +114132,7 @@ init_config();
113985
114132
 
113986
114133
  // src/turbo/lean/reviewer.ts
113987
114134
  init_state();
113988
- import * as fs99 from "node:fs/promises";
114135
+ import * as fs100 from "node:fs/promises";
113989
114136
  import * as path129 from "node:path";
113990
114137
  init_state3();
113991
114138
  var DEFAULT_CONFIG3 = {
@@ -114103,7 +114250,7 @@ function parseReviewerVerdict(responseText) {
114103
114250
  }
114104
114251
  async function writeReviewerEvidence(directory, phase, verdict, reason) {
114105
114252
  const evidenceDir = path129.join(directory, ".swarm", "evidence", String(phase));
114106
- await fs99.mkdir(evidenceDir, { recursive: true });
114253
+ await fs100.mkdir(evidenceDir, { recursive: true });
114107
114254
  const evidencePath = path129.join(evidenceDir, "lean-turbo-reviewer.json");
114108
114255
  const content = JSON.stringify({
114109
114256
  phase,
@@ -114113,11 +114260,11 @@ async function writeReviewerEvidence(directory, phase, verdict, reason) {
114113
114260
  }, null, 2);
114114
114261
  const tempPath = `${evidencePath}.tmp.${process.pid}.${Date.now()}`;
114115
114262
  try {
114116
- await fs99.writeFile(tempPath, content, "utf-8");
114117
- await fs99.rename(tempPath, evidencePath);
114263
+ await fs100.writeFile(tempPath, content, "utf-8");
114264
+ await fs100.rename(tempPath, evidencePath);
114118
114265
  } catch (error93) {
114119
114266
  try {
114120
- await fs99.unlink(tempPath);
114267
+ await fs100.unlink(tempPath);
114121
114268
  } catch {}
114122
114269
  throw error93;
114123
114270
  }
@@ -114908,7 +115055,7 @@ var lean_turbo_status = createSwarmTool({
114908
115055
  // src/tools/lint-spec.ts
114909
115056
  init_spec_schema();
114910
115057
  init_create_tool();
114911
- import * as fs100 from "node:fs";
115058
+ import * as fs101 from "node:fs";
114912
115059
  import * as path130 from "node:path";
114913
115060
  var SPEC_FILE_NAME = "spec.md";
114914
115061
  var SWARM_DIR2 = ".swarm";
@@ -114963,7 +115110,7 @@ var lint_spec = createSwarmTool({
114963
115110
  const errors5 = [];
114964
115111
  const warnings = [];
114965
115112
  const specPath = path130.join(directory, SWARM_DIR2, SPEC_FILE_NAME);
114966
- if (!fs100.existsSync(specPath)) {
115113
+ if (!fs101.existsSync(specPath)) {
114967
115114
  const result2 = {
114968
115115
  valid: false,
114969
115116
  specMtime: null,
@@ -114982,12 +115129,12 @@ var lint_spec = createSwarmTool({
114982
115129
  }
114983
115130
  let specMtime = null;
114984
115131
  try {
114985
- const stats = fs100.statSync(specPath);
115132
+ const stats = fs101.statSync(specPath);
114986
115133
  specMtime = stats.mtime.toISOString();
114987
115134
  } catch {}
114988
115135
  let content;
114989
115136
  try {
114990
- content = fs100.readFileSync(specPath, "utf-8");
115137
+ content = fs101.readFileSync(specPath, "utf-8");
114991
115138
  } catch (e) {
114992
115139
  const result2 = {
114993
115140
  valid: false,
@@ -115032,7 +115179,7 @@ var lint_spec = createSwarmTool({
115032
115179
  });
115033
115180
  // src/tools/mutation-test.ts
115034
115181
  init_zod();
115035
- import * as fs101 from "node:fs";
115182
+ import * as fs102 from "node:fs";
115036
115183
  import * as path132 from "node:path";
115037
115184
 
115038
115185
  // src/mutation/engine.ts
@@ -115589,7 +115736,7 @@ var mutation_test = createSwarmTool({
115589
115736
  for (const filePath of uniquePaths) {
115590
115737
  try {
115591
115738
  const resolvedPath = path132.resolve(cwd, filePath);
115592
- sourceFiles.set(filePath, fs101.readFileSync(resolvedPath, "utf-8"));
115739
+ sourceFiles.set(filePath, fs102.readFileSync(resolvedPath, "utf-8"));
115593
115740
  } catch {}
115594
115741
  }
115595
115742
  const report = await executeMutationSuite(typedArgs.patches, typedArgs.test_command, typedArgs.files, cwd, undefined, undefined, sourceFiles.size > 0 ? sourceFiles : undefined);
@@ -115607,7 +115754,7 @@ var mutation_test = createSwarmTool({
115607
115754
  init_zod();
115608
115755
  init_manager2();
115609
115756
  init_detector();
115610
- import * as fs102 from "node:fs";
115757
+ import * as fs103 from "node:fs";
115611
115758
  import * as path133 from "node:path";
115612
115759
  init_create_tool();
115613
115760
  var MAX_FILE_SIZE2 = 2 * 1024 * 1024;
@@ -115717,7 +115864,7 @@ async function syntaxCheck(input, directory, config3) {
115717
115864
  }
115718
115865
  let content;
115719
115866
  try {
115720
- content = fs102.readFileSync(fullPath, "utf8");
115867
+ content = fs103.readFileSync(fullPath, "utf8");
115721
115868
  } catch {
115722
115869
  result.skipped_reason = "file_read_error";
115723
115870
  skippedCount++;
@@ -115833,7 +115980,7 @@ init_zod();
115833
115980
  init_utils();
115834
115981
  init_create_tool();
115835
115982
  init_path_security();
115836
- import * as fs103 from "node:fs";
115983
+ import * as fs104 from "node:fs";
115837
115984
  import * as path134 from "node:path";
115838
115985
  var MAX_TEXT_LENGTH = 200;
115839
115986
  var MAX_FILE_SIZE_BYTES11 = 1024 * 1024;
@@ -115924,7 +116071,7 @@ function isSupportedExtension(filePath) {
115924
116071
  function findSourceFiles3(dir, files = []) {
115925
116072
  let entries;
115926
116073
  try {
115927
- entries = fs103.readdirSync(dir);
116074
+ entries = fs104.readdirSync(dir);
115928
116075
  } catch {
115929
116076
  return files;
115930
116077
  }
@@ -115936,7 +116083,7 @@ function findSourceFiles3(dir, files = []) {
115936
116083
  const fullPath = path134.join(dir, entry);
115937
116084
  let stat8;
115938
116085
  try {
115939
- stat8 = fs103.statSync(fullPath);
116086
+ stat8 = fs104.statSync(fullPath);
115940
116087
  } catch {
115941
116088
  continue;
115942
116089
  }
@@ -116029,7 +116176,7 @@ var todo_extract = createSwarmTool({
116029
116176
  return JSON.stringify(errorResult, null, 2);
116030
116177
  }
116031
116178
  const scanPath = resolvedPath;
116032
- if (!fs103.existsSync(scanPath)) {
116179
+ if (!fs104.existsSync(scanPath)) {
116033
116180
  const errorResult = {
116034
116181
  error: `path not found: ${pathsInput}`,
116035
116182
  total: 0,
@@ -116039,7 +116186,7 @@ var todo_extract = createSwarmTool({
116039
116186
  return JSON.stringify(errorResult, null, 2);
116040
116187
  }
116041
116188
  const filesToScan = [];
116042
- const stat8 = fs103.statSync(scanPath);
116189
+ const stat8 = fs104.statSync(scanPath);
116043
116190
  if (stat8.isFile()) {
116044
116191
  if (isSupportedExtension(scanPath)) {
116045
116192
  filesToScan.push(scanPath);
@@ -116058,11 +116205,11 @@ var todo_extract = createSwarmTool({
116058
116205
  const allEntries = [];
116059
116206
  for (const filePath of filesToScan) {
116060
116207
  try {
116061
- const fileStat = fs103.statSync(filePath);
116208
+ const fileStat = fs104.statSync(filePath);
116062
116209
  if (fileStat.size > MAX_FILE_SIZE_BYTES11) {
116063
116210
  continue;
116064
116211
  }
116065
- const content = fs103.readFileSync(filePath, "utf-8");
116212
+ const content = fs104.readFileSync(filePath, "utf-8");
116066
116213
  const entries = parseTodoComments(content, filePath, tagsSet);
116067
116214
  allEntries.push(...entries);
116068
116215
  } catch {}
@@ -116093,17 +116240,17 @@ init_loader();
116093
116240
  init_schema();
116094
116241
  init_qa_gate_profile();
116095
116242
  init_gate_evidence();
116096
- import * as fs107 from "node:fs";
116243
+ import * as fs108 from "node:fs";
116097
116244
  import * as path138 from "node:path";
116098
116245
 
116099
116246
  // src/hooks/diff-scope.ts
116100
116247
  init_bun_compat();
116101
- import * as fs105 from "node:fs";
116248
+ import * as fs106 from "node:fs";
116102
116249
  import * as path136 from "node:path";
116103
116250
 
116104
116251
  // src/utils/gitignore-warning.ts
116105
116252
  init_bun_compat();
116106
- import * as fs104 from "node:fs";
116253
+ import * as fs105 from "node:fs";
116107
116254
  import * as path135 from "node:path";
116108
116255
  var _internals54 = { bunSpawn };
116109
116256
  var _swarmGitExcludedChecked = false;
@@ -116181,13 +116328,13 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
116181
116328
  const excludePath = path135.isAbsolute(excludeRelPath) ? excludeRelPath : path135.join(directory, excludeRelPath);
116182
116329
  if (checkIgnoreExitCode !== 0) {
116183
116330
  try {
116184
- fs104.mkdirSync(path135.dirname(excludePath), { recursive: true });
116331
+ fs105.mkdirSync(path135.dirname(excludePath), { recursive: true });
116185
116332
  let existing = "";
116186
116333
  try {
116187
- existing = fs104.readFileSync(excludePath, "utf8");
116334
+ existing = fs105.readFileSync(excludePath, "utf8");
116188
116335
  } catch {}
116189
116336
  if (!fileCoversSwarm(existing)) {
116190
- fs104.appendFileSync(excludePath, `
116337
+ fs105.appendFileSync(excludePath, `
116191
116338
  # opencode-swarm local runtime state
116192
116339
  .swarm/
116193
116340
  `, "utf8");
@@ -116226,9 +116373,9 @@ var _internals55 = { bunSpawn };
116226
116373
  function getDeclaredScope(taskId, directory) {
116227
116374
  try {
116228
116375
  const planPath = path136.join(directory, ".swarm", "plan.json");
116229
- if (!fs105.existsSync(planPath))
116376
+ if (!fs106.existsSync(planPath))
116230
116377
  return null;
116231
- const raw = fs105.readFileSync(planPath, "utf-8");
116378
+ const raw = fs106.readFileSync(planPath, "utf-8");
116232
116379
  const plan = JSON.parse(raw);
116233
116380
  for (const phase of plan.phases ?? []) {
116234
116381
  for (const task of phase.tasks ?? []) {
@@ -116330,7 +116477,7 @@ init_telemetry();
116330
116477
 
116331
116478
  // src/turbo/lean/task-completion.ts
116332
116479
  init_file_locks();
116333
- import * as fs106 from "node:fs";
116480
+ import * as fs107 from "node:fs";
116334
116481
  import * as path137 from "node:path";
116335
116482
  var _internals56 = {
116336
116483
  listActiveLocks,
@@ -116363,13 +116510,13 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
116363
116510
  let persisted = null;
116364
116511
  try {
116365
116512
  const statePath = path137.join(directory, ".swarm", "turbo-state.json");
116366
- if (!fs106.existsSync(statePath)) {
116513
+ if (!fs107.existsSync(statePath)) {
116367
116514
  return {
116368
116515
  ok: false,
116369
116516
  reason: "Lean Turbo state file not found"
116370
116517
  };
116371
116518
  }
116372
- const raw = fs106.readFileSync(statePath, "utf-8");
116519
+ const raw = fs107.readFileSync(statePath, "utf-8");
116373
116520
  persisted = JSON.parse(raw);
116374
116521
  } catch {
116375
116522
  return {
@@ -116462,7 +116609,7 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
116462
116609
  }
116463
116610
  };
116464
116611
  }
116465
- if (!fs106.existsSync(evidencePath)) {
116612
+ if (!fs107.existsSync(evidencePath)) {
116466
116613
  return {
116467
116614
  ok: false,
116468
116615
  reason: `Lane ${lane.laneId} evidence file not found: ${evidencePath}`,
@@ -116491,7 +116638,7 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
116491
116638
  let filesTouched = [];
116492
116639
  try {
116493
116640
  const planPath = path137.join(directory, ".swarm", "plan.json");
116494
- const planRaw = fs106.readFileSync(planPath, "utf-8");
116641
+ const planRaw = fs107.readFileSync(planPath, "utf-8");
116495
116642
  const plan = JSON.parse(planRaw);
116496
116643
  for (const planPhase of plan.phases ?? []) {
116497
116644
  for (const task of planPhase.tasks ?? []) {
@@ -116614,7 +116761,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
116614
116761
  const resolvedDir2 = workingDirectory;
116615
116762
  try {
116616
116763
  const planPath = path138.join(resolvedDir2, ".swarm", "plan.json");
116617
- const planRaw = fs107.readFileSync(planPath, "utf-8");
116764
+ const planRaw = fs108.readFileSync(planPath, "utf-8");
116618
116765
  const plan = JSON.parse(planRaw);
116619
116766
  for (const planPhase of plan.phases ?? []) {
116620
116767
  for (const task of planPhase.tasks ?? []) {
@@ -116692,7 +116839,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
116692
116839
  if (resolvedDir) {
116693
116840
  try {
116694
116841
  const planPath = path138.join(resolvedDir, ".swarm", "plan.json");
116695
- const planRaw = fs107.readFileSync(planPath, "utf-8");
116842
+ const planRaw = fs108.readFileSync(planPath, "utf-8");
116696
116843
  const plan = JSON.parse(planRaw);
116697
116844
  for (const planPhase of plan.phases ?? []) {
116698
116845
  for (const task of planPhase.tasks ?? []) {
@@ -116941,9 +117088,9 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
116941
117088
  }
116942
117089
  const resolvedDir = path138.resolve(normalizedDir);
116943
117090
  try {
116944
- const realPath = fs107.realpathSync(resolvedDir);
117091
+ const realPath = fs108.realpathSync(resolvedDir);
116945
117092
  const planPath = path138.join(realPath, ".swarm", "plan.json");
116946
- if (!fs107.existsSync(planPath)) {
117093
+ if (!fs108.existsSync(planPath)) {
116947
117094
  return {
116948
117095
  success: false,
116949
117096
  message: `Invalid working_directory: plan not found in "${realPath}"`,
@@ -116973,8 +117120,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
116973
117120
  directory = fallbackDir;
116974
117121
  }
116975
117122
  if (fallbackDir && directory !== fallbackDir) {
116976
- const canonicalDir = fs107.realpathSync(path138.resolve(directory));
116977
- const canonicalRoot = fs107.realpathSync(path138.resolve(fallbackDir));
117123
+ const canonicalDir = fs108.realpathSync(path138.resolve(directory));
117124
+ const canonicalRoot = fs108.realpathSync(path138.resolve(fallbackDir));
116978
117125
  if (canonicalDir.startsWith(canonicalRoot + path138.sep)) {
116979
117126
  return {
116980
117127
  success: false,
@@ -116988,21 +117135,21 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
116988
117135
  if (args2.status === "in_progress") {
116989
117136
  try {
116990
117137
  const evidencePath = path138.join(directory, ".swarm", "evidence", `${args2.task_id}.json`);
116991
- fs107.mkdirSync(path138.dirname(evidencePath), { recursive: true });
116992
- const fd = fs107.openSync(evidencePath, "wx");
117138
+ fs108.mkdirSync(path138.dirname(evidencePath), { recursive: true });
117139
+ const fd = fs108.openSync(evidencePath, "wx");
116993
117140
  let writeOk = false;
116994
117141
  try {
116995
- fs107.writeSync(fd, JSON.stringify({
117142
+ fs108.writeSync(fd, JSON.stringify({
116996
117143
  taskId: args2.task_id,
116997
117144
  required_gates: [],
116998
117145
  gates: {}
116999
117146
  }, null, 2));
117000
117147
  writeOk = true;
117001
117148
  } finally {
117002
- fs107.closeSync(fd);
117149
+ fs108.closeSync(fd);
117003
117150
  if (!writeOk) {
117004
117151
  try {
117005
- fs107.unlinkSync(evidencePath);
117152
+ fs108.unlinkSync(evidencePath);
117006
117153
  } catch {}
117007
117154
  }
117008
117155
  }
@@ -117013,7 +117160,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
117013
117160
  let phaseRequiresReviewer = true;
117014
117161
  try {
117015
117162
  const planPath = path138.join(directory, ".swarm", "plan.json");
117016
- const planRaw = fs107.readFileSync(planPath, "utf-8");
117163
+ const planRaw = fs108.readFileSync(planPath, "utf-8");
117017
117164
  const plan = JSON.parse(planRaw);
117018
117165
  const taskPhase = plan.phases.find((p) => p.tasks.some((t) => t.id === args2.task_id));
117019
117166
  if (taskPhase?.required_agents && !taskPhase.required_agents.includes("reviewer")) {
@@ -117323,7 +117470,7 @@ init_utils2();
117323
117470
  init_ledger();
117324
117471
  init_manager();
117325
117472
  init_create_tool();
117326
- import fs108 from "node:fs";
117473
+ import fs109 from "node:fs";
117327
117474
  import path139 from "node:path";
117328
117475
  function normalizeVerdict(verdict) {
117329
117476
  switch (verdict) {
@@ -117385,10 +117532,10 @@ async function executeWriteDriftEvidence(args2, directory) {
117385
117532
  }
117386
117533
  const evidenceDir = path139.dirname(validatedPath);
117387
117534
  try {
117388
- await fs108.promises.mkdir(evidenceDir, { recursive: true });
117535
+ await fs109.promises.mkdir(evidenceDir, { recursive: true });
117389
117536
  const tempPath = path139.join(evidenceDir, `.${filename}.tmp`);
117390
- await fs108.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
117391
- await fs108.promises.rename(tempPath, validatedPath);
117537
+ await fs109.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
117538
+ await fs109.promises.rename(tempPath, validatedPath);
117392
117539
  let snapshotInfo;
117393
117540
  let snapshotError;
117394
117541
  let qaProfileLocked;
@@ -117481,7 +117628,7 @@ var write_drift_evidence = createSwarmTool({
117481
117628
  // src/tools/write-final-council-evidence.ts
117482
117629
  init_zod();
117483
117630
  init_loader();
117484
- import fs109 from "node:fs";
117631
+ import fs110 from "node:fs";
117485
117632
  import path140 from "node:path";
117486
117633
  init_utils2();
117487
117634
  init_manager();
@@ -117586,10 +117733,10 @@ async function executeWriteFinalCouncilEvidence(args2, directory) {
117586
117733
  };
117587
117734
  const evidenceDir = path140.dirname(validatedPath);
117588
117735
  try {
117589
- await fs109.promises.mkdir(evidenceDir, { recursive: true });
117736
+ await fs110.promises.mkdir(evidenceDir, { recursive: true });
117590
117737
  const tempPath = path140.join(evidenceDir, `.${filename}.tmp`);
117591
- await fs109.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
117592
- await fs109.promises.rename(tempPath, validatedPath);
117738
+ await fs110.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
117739
+ await fs110.promises.rename(tempPath, validatedPath);
117593
117740
  return JSON.stringify({
117594
117741
  success: true,
117595
117742
  phase: input.phase,
@@ -117645,7 +117792,7 @@ var write_final_council_evidence = createSwarmTool({
117645
117792
  init_zod();
117646
117793
  init_utils2();
117647
117794
  init_create_tool();
117648
- import fs110 from "node:fs";
117795
+ import fs111 from "node:fs";
117649
117796
  import path141 from "node:path";
117650
117797
  function normalizeVerdict2(verdict) {
117651
117798
  switch (verdict) {
@@ -117707,10 +117854,10 @@ async function executeWriteHallucinationEvidence(args2, directory) {
117707
117854
  }
117708
117855
  const evidenceDir = path141.dirname(validatedPath);
117709
117856
  try {
117710
- await fs110.promises.mkdir(evidenceDir, { recursive: true });
117857
+ await fs111.promises.mkdir(evidenceDir, { recursive: true });
117711
117858
  const tempPath = path141.join(evidenceDir, `.${filename}.tmp`);
117712
- await fs110.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
117713
- await fs110.promises.rename(tempPath, validatedPath);
117859
+ await fs111.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
117860
+ await fs111.promises.rename(tempPath, validatedPath);
117714
117861
  return JSON.stringify({
117715
117862
  success: true,
117716
117863
  phase,
@@ -117756,7 +117903,7 @@ var write_hallucination_evidence = createSwarmTool({
117756
117903
  init_zod();
117757
117904
  init_utils2();
117758
117905
  init_create_tool();
117759
- import fs111 from "node:fs";
117906
+ import fs112 from "node:fs";
117760
117907
  import path142 from "node:path";
117761
117908
  function normalizeVerdict3(verdict) {
117762
117909
  switch (verdict) {
@@ -117844,10 +117991,10 @@ async function executeWriteMutationEvidence(args2, directory) {
117844
117991
  }
117845
117992
  const evidenceDir = path142.dirname(validatedPath);
117846
117993
  try {
117847
- await fs111.promises.mkdir(evidenceDir, { recursive: true });
117994
+ await fs112.promises.mkdir(evidenceDir, { recursive: true });
117848
117995
  const tempPath = path142.join(evidenceDir, `.${filename}.tmp`);
117849
- await fs111.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
117850
- await fs111.promises.rename(tempPath, validatedPath);
117996
+ await fs112.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
117997
+ await fs112.promises.rename(tempPath, validatedPath);
117851
117998
  return JSON.stringify({
117852
117999
  success: true,
117853
118000
  phase,