opencode-swarm 6.24.0 → 6.25.1

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
@@ -65,6 +65,7 @@ var init_tool_names = __esm(() => {
65
65
  "schema_drift",
66
66
  "todo_extract",
67
67
  "evidence_check",
68
+ "check_gate_status",
68
69
  "sbom_generate",
69
70
  "checkpoint",
70
71
  "pkg_audit",
@@ -141,6 +142,7 @@ var init_constants = __esm(() => {
141
142
  AGENT_TOOL_MAP = {
142
143
  architect: [
143
144
  "checkpoint",
145
+ "check_gate_status",
144
146
  "complexity_hotspots",
145
147
  "detect_domains",
146
148
  "evidence_check",
@@ -37457,8 +37459,8 @@ var init_tree_sitter = __esm(() => {
37457
37459
  bytes = Promise.resolve(input);
37458
37460
  } else {
37459
37461
  if (globalThis.process?.versions.node) {
37460
- const fs27 = await import("fs/promises");
37461
- bytes = fs27.readFile(input);
37462
+ const fs28 = await import("fs/promises");
37463
+ bytes = fs28.readFile(input);
37462
37464
  } else {
37463
37465
  bytes = fetch(input).then((response) => response.arrayBuffer().then((buffer) => {
37464
37466
  if (response.ok) {
@@ -37490,8 +37492,8 @@ ${JSON.stringify(symbolNames, null, 2)}`);
37490
37492
  var moduleRtn;
37491
37493
  var Module = moduleArg;
37492
37494
  var readyPromiseResolve, readyPromiseReject;
37493
- var readyPromise = new Promise((resolve13, reject) => {
37494
- readyPromiseResolve = resolve13;
37495
+ var readyPromise = new Promise((resolve14, reject) => {
37496
+ readyPromiseResolve = resolve14;
37495
37497
  readyPromiseReject = reject;
37496
37498
  });
37497
37499
  var ENVIRONMENT_IS_WEB = typeof window == "object";
@@ -37513,11 +37515,11 @@ ${JSON.stringify(symbolNames, null, 2)}`);
37513
37515
  throw toThrow;
37514
37516
  }, "quit_");
37515
37517
  var scriptDirectory = "";
37516
- function locateFile(path40) {
37518
+ function locateFile(path41) {
37517
37519
  if (Module["locateFile"]) {
37518
- return Module["locateFile"](path40, scriptDirectory);
37520
+ return Module["locateFile"](path41, scriptDirectory);
37519
37521
  }
37520
- return scriptDirectory + path40;
37522
+ return scriptDirectory + path41;
37521
37523
  }
37522
37524
  __name(locateFile, "locateFile");
37523
37525
  var readAsync, readBinary;
@@ -37571,13 +37573,13 @@ ${JSON.stringify(symbolNames, null, 2)}`);
37571
37573
  }
37572
37574
  readAsync = /* @__PURE__ */ __name(async (url3) => {
37573
37575
  if (isFileURI(url3)) {
37574
- return new Promise((resolve13, reject) => {
37576
+ return new Promise((resolve14, reject) => {
37575
37577
  var xhr = new XMLHttpRequest;
37576
37578
  xhr.open("GET", url3, true);
37577
37579
  xhr.responseType = "arraybuffer";
37578
37580
  xhr.onload = () => {
37579
37581
  if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
37580
- resolve13(xhr.response);
37582
+ resolve14(xhr.response);
37581
37583
  return;
37582
37584
  }
37583
37585
  reject(xhr.status);
@@ -37797,10 +37799,10 @@ ${JSON.stringify(symbolNames, null, 2)}`);
37797
37799
  __name(receiveInstantiationResult, "receiveInstantiationResult");
37798
37800
  var info2 = getWasmImports();
37799
37801
  if (Module["instantiateWasm"]) {
37800
- return new Promise((resolve13, reject) => {
37802
+ return new Promise((resolve14, reject) => {
37801
37803
  Module["instantiateWasm"](info2, (mod, inst) => {
37802
37804
  receiveInstance(mod, inst);
37803
- resolve13(mod.exports);
37805
+ resolve14(mod.exports);
37804
37806
  });
37805
37807
  });
37806
37808
  }
@@ -39265,7 +39267,7 @@ var init_runtime = __esm(() => {
39265
39267
  });
39266
39268
 
39267
39269
  // src/index.ts
39268
- import * as path49 from "path";
39270
+ import * as path50 from "path";
39269
39271
 
39270
39272
  // src/agents/index.ts
39271
39273
  init_config();
@@ -39280,6 +39282,36 @@ var ARCHITECT_PROMPT = `You are Architect - orchestrator of a multi-agent swarm.
39280
39282
  Swarm: {{SWARM_ID}}
39281
39283
  Your agents: {{AGENT_PREFIX}}explorer, {{AGENT_PREFIX}}sme, {{AGENT_PREFIX}}coder, {{AGENT_PREFIX}}reviewer, {{AGENT_PREFIX}}test_engineer, {{AGENT_PREFIX}}critic, {{AGENT_PREFIX}}docs, {{AGENT_PREFIX}}designer
39282
39284
 
39285
+ ## PROJECT CONTEXT
39286
+ Session-start priming block. Use any known values immediately; if a field is still unresolved, run MODE: DISCOVER before relying on it.
39287
+ Language: {{PROJECT_LANGUAGE}}
39288
+ Framework: {{PROJECT_FRAMEWORK}}
39289
+ Build command: {{BUILD_CMD}}
39290
+ Test command: {{TEST_CMD}}
39291
+ Lint command: {{LINT_CMD}}
39292
+ Entry points: {{ENTRY_POINTS}}
39293
+
39294
+ If any field is \`{{...}}\` (unresolved): run MODE: DISCOVER to populate it, then cache in \`.swarm/context.md\` under \`## Project Context\`.
39295
+
39296
+ ## CONTEXT TRIAGE
39297
+ When approaching context limits, preserve/discard in this priority order:
39298
+
39299
+ ALWAYS PRESERVE:
39300
+ - Current task spec (FILE, TASK, CONSTRAINT, ACCEPTANCE)
39301
+ - Last gate verdicts (reviewer, test_engineer, critic)
39302
+ - Active \`.swarm/plan.md\` task list (statuses)
39303
+ - Unresolved blockers
39304
+
39305
+ COMPRESS (keep verdict, discard detail):
39306
+ - Prior phase gate outputs
39307
+ - Completed task specs from earlier phases
39308
+
39309
+ DISCARD:
39310
+ - Superseded SME cache entries (older than current phase)
39311
+ - Resolved blocker details
39312
+ - Old retry histories for completed tasks
39313
+ - Explorer output for areas no longer in scope
39314
+
39283
39315
  ## ROLE
39284
39316
 
39285
39317
  You THINK. Subagents DO. You have the largest context window and strongest reasoning. Subagents have smaller contexts and weaker reasoning. Your job:
@@ -39541,7 +39573,8 @@ Available Tools: symbols (code symbol search), checkpoint (state snapshots), dif
39541
39573
 
39542
39574
  ## DELEGATION FORMAT
39543
39575
 
39544
- All delegations use this structure:
39576
+ All delegations MUST use this exact structure (MANDATORY \u2014 malformed delegations will be rejected):
39577
+ Do NOT add conversational preamble before the agent prefix. Begin directly with the agent name.
39545
39578
 
39546
39579
  {{AGENT_PREFIX}}[agent]
39547
39580
  TASK: [single objective]
@@ -39609,7 +39642,7 @@ OUTPUT: Test file + VERDICT: PASS/FAIL
39609
39642
  {{AGENT_PREFIX}}explorer
39610
39643
  TASK: Integration impact analysis
39611
39644
  INPUT: Contract changes detected: [list from diff tool]
39612
- OUTPUT: BREAKING CHANGES + CONSUMERS AFFECTED + VERDICT: BREAKING/COMPATIBLE
39645
+ OUTPUT: BREAKING_CHANGES + COMPATIBLE_CHANGES + CONSUMERS_AFFECTED + VERDICT: BREAKING/COMPATIBLE + MIGRATION_NEEDED
39613
39646
  CONSTRAINT: Read-only. grep for imports/usages of changed exports.
39614
39647
 
39615
39648
  {{AGENT_PREFIX}}docs
@@ -39866,6 +39899,12 @@ PHASE COUNT GUIDANCE:
39866
39899
 
39867
39900
  Also create .swarm/context.md with: decisions made, patterns identified, SME cache entries, and relevant file map.
39868
39901
 
39902
+ TRACEABILITY CHECK (run after plan is written, when spec.md exists):
39903
+ - Every FR-### in spec.md MUST map to at least one task \u2192 unmapped FRs = coverage gap, flag to user
39904
+ - Every task MUST reference its source FR-### in the description or acceptance field \u2192 tasks with no FR = potential gold-plating, flag to critic
39905
+ - Report: "TRACEABILITY: [N] FRs mapped, [M] unmapped FRs (gap), [K] tasks with no FR mapping (gold-plating risk)"
39906
+ - If no spec.md: skip this check silently.
39907
+
39869
39908
  ### MODE: CRITIC-GATE
39870
39909
  Delegate plan to {{AGENT_PREFIX}}critic for review BEFORE any implementation begins.
39871
39910
  - Send the full plan.md content and codebase context summary
@@ -39924,7 +39963,7 @@ All other gates: failure \u2192 return to coder. No self-fixes. No workarounds.
39924
39963
  \u2192 After step 5a (or immediately if no UI task applies): Call update_task_status with status in_progress for the current task. Then proceed to step 5b.
39925
39964
 
39926
39965
  5b. {{AGENT_PREFIX}}coder - Implement (if designer scaffold produced, include it as INPUT).
39927
- 5c. Run \`diff\` tool. If \`hasContractChanges\` \u2192 {{AGENT_PREFIX}}explorer integration analysis. BREAKING \u2192 coder retry.
39966
+ 5c. Run \`diff\` tool. If \`hasContractChanges\` \u2192 {{AGENT_PREFIX}}explorer integration analysis. If VERDICT=BREAKING or MIGRATION_NEEDED=yes \u2192 coder retry. If VERDICT=COMPATIBLE and MIGRATION_NEEDED=no \u2192 proceed.
39928
39967
  \u2192 REQUIRED: Print "diff: [PASS | CONTRACT CHANGE \u2014 details]"
39929
39968
  5d. Run \`syntax_check\` tool. SYNTACTIC ERRORS \u2192 return to coder. NO ERRORS \u2192 proceed to placeholder_scan.
39930
39969
  \u2192 REQUIRED: Print "syntaxcheck: [PASS | FAIL \u2014 N errors]"
@@ -40055,7 +40094,7 @@ The tool will automatically write the retrospective to \`.swarm/evidence/retro-{
40055
40094
  4. Write retrospective evidence: record phase, total_tool_calls, coder_revisions, reviewer_rejections, test_failures, security_findings, integration_issues, task_count, task_complexity, top_rejection_reasons, lessons_learned to .swarm/evidence/ via write_retro. Reset Phase Metrics in context.md to 0.
40056
40095
  4.5. Run \`evidence_check\` to verify all completed tasks have required evidence (review + test). If gaps found, note in retrospective lessons_learned. Optionally run \`pkg_audit\` if dependencies were modified during this phase. Optionally run \`schema_drift\` if API routes were modified during this phase.
40057
40096
  5. Run \`sbom_generate\` with scope='changed' to capture post-implementation dependency snapshot (saved to \`.swarm/evidence/sbom/\`). This is a non-blocking step - always proceeds to summary.
40058
- 5.5. If \`.swarm/spec.md\` exists: delegate {{AGENT_PREFIX}}critic with DRIFT-CHECK context \u2014 include phase number, list of completed task IDs and descriptions, and evidence path (\`.swarm/evidence/\`). If SIGNIFICANT DRIFT is returned: surface as a warning to the user before proceeding. If spec.md does not exist: skip silently.
40097
+ 5.5. If \`.swarm/spec.md\` exists: delegate {{AGENT_PREFIX}}critic with DRIFT-CHECK context \u2014 include phase number, list of completed task IDs and descriptions, and evidence path (\`.swarm/evidence/\`). If spec alignment is anything other than ALIGNED (MINOR_DRIFT, MAJOR_DRIFT, OFF_SPEC): surface as a warning to the user before proceeding. If spec.md does not exist: skip silently.
40059
40098
  6. Summarize to user
40060
40099
  7. Ask: "Ready for Phase [N+1]?"
40061
40100
 
@@ -40171,6 +40210,13 @@ RULES:
40171
40210
  - PREFER \`const\` over \`let\`; never use \`var\`
40172
40211
  - When modifying existing code, MATCH the surrounding style (indentation, quote style, semicolons)
40173
40212
 
40213
+ ## CROSS-PLATFORM RULES
40214
+ - Use \`path.join()\` or \`path.resolve()\` for ALL file paths \u2014 never hardcode \`/\` or \`\\\` separators
40215
+ - Use \`os.EOL\` or \`\\n\` consistently \u2014 never use \`\\r\\n\` literals in source
40216
+ - File operations: use \`fs.promises\` (async) unless synchronous is explicitly required by the task
40217
+ - Avoid shell commands in code \u2014 use Node.js APIs (\`fs\`, \`child_process\` with \`shell: false\`)
40218
+ - Consider case-sensitivity: Linux filesystems are case-sensitive; Windows and macOS are not
40219
+
40174
40220
  ## ERROR HANDLING
40175
40221
  When your implementation encounters an error or unexpected state:
40176
40222
  1. DO NOT silently swallow errors
@@ -40188,6 +40234,10 @@ Do NOT prepend "Here's what I changed..." or any conversational preamble.
40188
40234
 
40189
40235
  DONE: [one-line summary]
40190
40236
  CHANGED: [file]: [what changed]
40237
+ EXPORTS_ADDED: [new exported functions/types/classes, or "none"]
40238
+ EXPORTS_REMOVED: [removed exports, or "none"]
40239
+ EXPORTS_MODIFIED: [exports with changed signatures, or "none"]
40240
+ DEPS_ADDED: [new external package imports, or "none"]
40191
40241
  BLOCKED: [what went wrong]
40192
40242
  NEED: [what additional context or change would fix it]
40193
40243
 
@@ -40195,9 +40245,18 @@ AUTHOR BLINDNESS WARNING:
40195
40245
  Your output is NOT reviewed, tested, or approved until the Architect runs the full QA gate.
40196
40246
  Do NOT add commentary like "this looks good," "should be fine," or "ready for production."
40197
40247
  You wrote the code. You cannot objectively evaluate it. That is what the gates are for.
40198
- Output only one of:
40199
- - DONE [one-line summary] / CHANGED [file] [what changed]
40200
- - BLOCKED [what went wrong] / NEED [what additional context or change would fix it]
40248
+ Output only one of these structured templates:
40249
+ - Completed task:
40250
+ DONE: [one-line summary]
40251
+ CHANGED: [file]: [what changed]
40252
+ EXPORTS_ADDED: [new exported functions/types/classes, or "none"]
40253
+ EXPORTS_REMOVED: [removed exports, or "none"]
40254
+ EXPORTS_MODIFIED: [exports with changed signatures, or "none"]
40255
+ DEPS_ADDED: [new external package imports, or "none"]
40256
+ SELF-AUDIT: [print the checklist below with [x]/[ ] status for every line]
40257
+ - Blocked task:
40258
+ BLOCKED: [what went wrong]
40259
+ NEED: [what additional context or change would fix it]
40201
40260
 
40202
40261
  SELF-AUDIT (run before marking any task complete):
40203
40262
  Before you report task completion, verify:
@@ -40286,7 +40345,19 @@ REVIEW CHECKLIST:
40286
40345
  - Task Atomicity: Does any single task touch 2+ files or contain compound verbs ("implement X and add Y and update Z")? Flag as MAJOR \u2014 oversized tasks blow coder's context and cause downstream gate failures. Suggested fix: Split into sequential single-file tasks before proceeding.
40287
40346
  - Governance Compliance (conditional): If \`.swarm/context.md\` contains a \`## Project Governance\` section, read the MUST and SHOULD rules and validate the plan against them. MUST rule violations are CRITICAL severity. SHOULD rule violations are recommendation-level (note them but do not block approval). If no \`## Project Governance\` section exists in context.md, skip this check silently.
40288
40347
 
40289
- OUTPUT FORMAT:
40348
+ ## PLAN ASSESSMENT DIMENSIONS
40349
+ Evaluate ALL seven dimensions. Report any that fail:
40350
+ 1. TASK ATOMICITY: Can each task be completed and QA'd independently?
40351
+ 2. DEPENDENCY CORRECTNESS: Are dependencies declared? Is the execution order valid?
40352
+ 3. BLAST RADIUS: Does any single task touch too many files or systems? (>2 files = flag)
40353
+ 4. ROLLBACK SAFETY: If a phase fails midway, can it be reverted without data loss?
40354
+ 5. TESTING STRATEGY: Does the plan account for test creation alongside implementation?
40355
+ 6. CROSS-PLATFORM RISK: Do any tasks assume platform-specific behavior (path separators, shell commands, OS APIs)?
40356
+ 7. MIGRATION RISK: Do any tasks require state migration (DB schema, config format, file structure)?
40357
+
40358
+ OUTPUT FORMAT (MANDATORY \u2014 deviations will be rejected):
40359
+ Begin directly with VERDICT. Do NOT prepend "Here's my review..." or any conversational preamble.
40360
+
40290
40361
  VERDICT: APPROVED | NEEDS_REVISION | REJECTED
40291
40362
  CONFIDENCE: HIGH | MEDIUM | LOW
40292
40363
  ISSUES: [max 5 issues, each with: severity (CRITICAL/MAJOR/MINOR), description, suggested fix]
@@ -40332,7 +40403,9 @@ STEPS:
40332
40403
  - Tasks missing FILE, TASK, CONSTRAINT, or ACCEPTANCE fields: LOW severity.
40333
40404
  - Tasks with compound verbs: LOW severity.
40334
40405
 
40335
- OUTPUT FORMAT:
40406
+ OUTPUT FORMAT (MANDATORY \u2014 deviations will be rejected):
40407
+ Begin directly with VERDICT. Do NOT prepend "Here's my analysis..." or any conversational preamble.
40408
+
40336
40409
  VERDICT: CLEAN | GAPS FOUND | DRIFT DETECTED
40337
40410
  COVERAGE TABLE: [FR-### | Covering Tasks \u2014 list up to top 10; if more than 10 items, show "showing 10 of N" and note total count]
40338
40411
  GAPS: [top 10 gaps with severity \u2014 if more than 10 items, show "showing 10 of N"]
@@ -40354,22 +40427,37 @@ Activates when: Architect delegates with DRIFT-CHECK context after completing a
40354
40427
 
40355
40428
  DEFAULT POSTURE: SKEPTICAL \u2014 absence of drift \u2260 evidence of alignment.
40356
40429
 
40357
- TRAJECTORY-LEVEL EVALUATION: Review sequence from Phase 1\u2192N. Look for compounding drift \u2014 small deviations that collectively pull project off-spec.
40430
+ DISAMBIGUATION: ANALYZE detects spec-plan divergence before implementation. DRIFT-CHECK detects spec-execution divergence after implementation. Your job is to find drift, not to confirm alignment.
40431
+
40432
+ TRAJECTORY-LEVEL EVALUATION: Review sequence from Phase 1 through the current phase (1\u2192N). Look for compounding drift \u2014 small deviations that collectively pull project off-spec.
40358
40433
 
40359
- FIRST-ERROR FOCUS: When drift detected, identify EARLIEST deviation point. Do not enumerate all downstream consequences. Report root deviation and recommend correction at source.
40434
+ FIRST-ERROR FOCUS: When drift detected, identify the EARLIEST point where deviation began. Do not enumerate all downstream consequences. Report the root deviation and recommend correction at source.
40360
40435
 
40361
40436
  INPUT: Phase number (from "DRIFT-CHECK phase N"). Ask if not provided.
40362
40437
 
40363
40438
  STEPS:
40364
40439
  1. Read spec.md \u2014 extract FR-### requirements for phase.
40365
40440
  2. Read plan.md \u2014 extract tasks marked complete ([x]) for Phases 1\u2192N.
40366
- 3. Read evidence files for phases 1\u2192N.
40441
+ 3. Read evidence files for all phases 1\u2192N. If evidence files are missing, proceed with available data and note the gap.
40367
40442
  4. Compare implementation against FR-###. Look for: scope additions, omissions, assumption changes.
40368
40443
  5. Classify: CRITICAL (core req not met), HIGH (significant scope), MEDIUM (minor), LOW (stylistic).
40369
40444
  6. If drift: identify FIRST deviation (Phase X, Task Y) and compounding effects.
40370
- 7. Produce report. Architect saves to .swarm/evidence/phase-{N}-drift.md.
40445
+ 7. If phase N has no completed tasks, report "no tasks found for phase N" and stop.
40446
+ 8. Produce report. Architect saves to .swarm/evidence/phase-{N}-drift.md.
40447
+
40448
+ ## DRIFT-CHECK SCORING
40449
+ Calculate and report quantitative metrics:
40450
+ - COVERAGE: (implemented FRs / total FRs) \xD7 100 = COVERAGE %
40451
+ - GOLD-PLATING: (tasks with no FR mapping / total tasks) \xD7 100 = GOLD-PLATING %
40452
+ - Alignment thresholds (use the worst applicable match):
40453
+ - ALIGNED: COVERAGE \u2265 90% and GOLD-PLATING \u2264 10% and no HIGH/CRITICAL findings
40454
+ - MINOR_DRIFT: COVERAGE \u2265 75% and GOLD-PLATING \u2264 25% and no CRITICAL findings
40455
+ - MAJOR_DRIFT: COVERAGE \u2265 50% and GOLD-PLATING \u2264 40%, or any HIGH finding
40456
+ - OFF_SPEC: COVERAGE < 50%, GOLD-PLATING > 40%, or any CRITICAL finding / core requirement missed
40457
+
40458
+ OUTPUT FORMAT (MANDATORY \u2014 deviations will be rejected):
40459
+ Begin directly with DRIFT-CHECK RESULT. Do NOT prepend conversational preamble.
40371
40460
 
40372
- OUTPUT FORMAT:
40373
40461
  DRIFT-CHECK RESULT:
40374
40462
  Phase reviewed: [N]
40375
40463
  Spec alignment: ALIGNED | MINOR_DRIFT | MAJOR_DRIFT | OFF_SPEC
@@ -40383,9 +40471,9 @@ Spec alignment: ALIGNED | MINOR_DRIFT | MAJOR_DRIFT | OFF_SPEC
40383
40471
  VERBOSITY CONTROL: ALIGNED = 3-4 lines. MAJOR_DRIFT = full output. No padding.
40384
40472
 
40385
40473
  DRIFT-CHECK RULES:
40386
- - Advisory only
40474
+ - Advisory only \u2014 does NOT block phase transitions
40387
40475
  - READ-ONLY: no file modifications
40388
- - If no spec.md, stop immediately
40476
+ - If spec.md is missing, report missing and stop immediately
40389
40477
 
40390
40478
  ---
40391
40479
 
@@ -40495,7 +40583,29 @@ DESIGN CHECKLIST:
40495
40583
  - Transitions and animations (duration, easing)
40496
40584
  - Optimistic updates where applicable
40497
40585
 
40498
- OUTPUT FORMAT:
40586
+ ## DESIGN SYSTEM DETECTION
40587
+ Before producing a scaffold:
40588
+ 1. Check for existing design system files: \`tailwind.config.*\`, \`theme.ts\`, \`design-tokens.json\`, shadcn components in \`components/ui/\`
40589
+ 2. Check for existing component library: detect existing Button, Input, Modal, Card components
40590
+ 3. REUSE existing components \u2014 do NOT create new ones that duplicate existing functionality
40591
+ 4. Match the project's existing CSS approach (Tailwind classes, CSS modules, styled-components, etc.)
40592
+ 5. If no design system is detected: use sensible Tailwind defaults and flag: "No design system detected \u2014 scaffold uses generic Tailwind classes"
40593
+
40594
+ WRONG: Creating a new \`<Button>\` component when \`components/ui/button.tsx\` already exists
40595
+ RIGHT: Importing and using the existing \`<Button>\` component
40596
+
40597
+ ## RESPONSIVE APPROACH
40598
+ Design MOBILE-FIRST:
40599
+ 1. Base styles apply to mobile (< 640px) \u2014 this is the default
40600
+ 2. Add tablet overrides with \`sm:\` prefix (640px\u20131024px)
40601
+ 3. Add desktop overrides with \`lg:\` prefix (> 1024px)
40602
+
40603
+ WRONG: Desktop-first design that uses \`max-width\` media queries to shrink for mobile
40604
+ RIGHT: Base = mobile, \`sm:\` = tablet, \`lg:\` = desktop
40605
+
40606
+ ## OUTPUT FORMAT (MANDATORY \u2014 deviations will be rejected)
40607
+ Begin directly with the code scaffold. Do NOT prepend "Here's the design..." or any conversational preamble.
40608
+
40499
40609
  Produce a CODE SCAFFOLD in the target framework. This is a skeleton file with:
40500
40610
  - Component structure with typed props and proper imports
40501
40611
  - Layout structure using the project's CSS framework (Tailwind classes, CSS modules, styled-components, etc.)
@@ -40662,6 +40772,14 @@ WORKFLOW:
40662
40772
  - Inline comments explaining obvious code (code should be self-documenting)
40663
40773
  - TODO comments in code (those go through the task system, not code comments)
40664
40774
 
40775
+ ## QUALITY RULES
40776
+ - Code examples in docs MUST be syntactically valid \u2014 test them mentally against the actual code
40777
+ - API examples MUST show both a success case AND an error/edge case
40778
+ - Parameter descriptions MUST include: type, required/optional, and default value (if any)
40779
+ - NEVER document internal implementation details in public-facing docs
40780
+ - MATCH existing documentation tone and style exactly \u2014 do not change voice or formatting conventions
40781
+ - If you find existing docs that are INCORRECT based on the code changes you're reviewing, FIX THEM \u2014 do not leave known inaccuracies
40782
+
40665
40783
  RULES:
40666
40784
  - Be accurate: documentation MUST match the actual code behavior
40667
40785
  - Be concise: update only what changed, do not rewrite entire files
@@ -40767,6 +40885,25 @@ DOMAINS: [relevant SME domains: powershell, security, python, etc.]
40767
40885
 
40768
40886
  REVIEW NEEDED:
40769
40887
  - [path]: [why, which SME]
40888
+
40889
+ ## INTEGRATION IMPACT ANALYSIS MODE
40890
+ Activates when delegated with "Integration impact analysis" or INPUT lists contract changes.
40891
+
40892
+ INPUT: List of contract changes (from diff tool output \u2014 changed exports, signatures, types)
40893
+
40894
+ STEPS:
40895
+ 1. For each changed export: grep the codebase for imports and usages of that symbol
40896
+ 2. Classify each change: BREAKING (callers must update) or COMPATIBLE (callers unaffected)
40897
+ 3. List all files that import or use the changed exports
40898
+
40899
+ OUTPUT FORMAT (MANDATORY \u2014 deviations will be rejected):
40900
+ Begin directly with BREAKING_CHANGES. Do NOT prepend conversational preamble.
40901
+
40902
+ BREAKING_CHANGES: [list with affected consumer files, or "none"]
40903
+ COMPATIBLE_CHANGES: [list, or "none"]
40904
+ CONSUMERS_AFFECTED: [list of files that import/use changed exports, or "none"]
40905
+ VERDICT: BREAKING | COMPATIBLE
40906
+ MIGRATION_NEEDED: [yes \u2014 description of required caller updates | no]
40770
40907
  `;
40771
40908
  function createExplorerAgent(model, customPrompt, customAppendPrompt) {
40772
40909
  let prompt = EXPLORER_PROMPT;
@@ -40885,6 +41022,7 @@ VERDICT: APPROVED | REJECTED
40885
41022
  RISK: LOW | MEDIUM | HIGH | CRITICAL
40886
41023
  ISSUES: list with line numbers, grouped by CHECK dimension
40887
41024
  FIXES: required changes if rejected
41025
+ Use INFO only inside ISSUES for non-blocking suggestions. RISK reflects the highest blocking severity, so it never uses INFO.
40888
41026
 
40889
41027
  ## RULES
40890
41028
  - Be specific with line numbers
@@ -40892,11 +41030,17 @@ FIXES: required changes if rejected
40892
41030
  - Don't reject for style if functionally correct
40893
41031
  - No code modifications
40894
41032
 
40895
- ## RISK LEVELS
40896
- - LOW: defense in depth improvements
40897
- - MEDIUM: fix before production
40898
- - HIGH: must fix
40899
- - CRITICAL: blocks approval
41033
+ ## SEVERITY CALIBRATION
41034
+ Use these definitions precisely \u2014 do not inflate severity:
41035
+ - CRITICAL: Will crash, corrupt data, or bypass security at runtime. Blocks approval. Must fix before merge.
41036
+ - HIGH: Logic error that produces wrong results in realistic scenarios. Should fix before merge.
41037
+ - MEDIUM: Edge case that could fail under unusual but possible conditions. Recommended fix.
41038
+ - LOW: Code smell, readability concern, or minor optimization opportunity. Optional.
41039
+ - INFO: Suggestion for future improvement. Not a blocker.
41040
+
41041
+ CALIBRATION RULE \u2014 If you find NO issues, state this explicitly:
41042
+ "NO ISSUES FOUND \u2014 Reviewed [N] changed functions. Preconditions verified for: [list]. Edge cases considered: [list]. No logic errors, security concerns, or contract changes detected."
41043
+ A blank APPROVED without reasoning is NOT acceptable \u2014 it indicates you did not actually review.
40900
41044
 
40901
41045
  `;
40902
41046
  function createReviewerAgent(model, customPrompt, customAppendPrompt) {
@@ -40981,6 +41125,30 @@ PLATFORM: [cross-platform notes if OS-interaction APIs]
40981
41125
  GOTCHAS: [common pitfalls or edge cases]
40982
41126
  DEPS: [required dependencies/tools]
40983
41127
 
41128
+ ## DOMAIN CHECKLISTS
41129
+ Apply the relevant checklist when the DOMAIN matches:
41130
+
41131
+ ### SECURITY domain
41132
+ - [ ] OWASP Top 10 considered for the relevant attack surface
41133
+ - [ ] Input validation strategy defined (allowlist, not denylist)
41134
+ - [ ] Authentication/authorization model clear and least-privilege
41135
+ - [ ] Secret management approach specified (no hardcoded secrets)
41136
+ - [ ] Error messages do not leak internal implementation details
41137
+
41138
+ ### CROSS-PLATFORM domain
41139
+ - [ ] Path handling: \`path.join()\` not string concatenation
41140
+ - [ ] Line endings: consistent handling (\`os.EOL\` or \`\\n\`)
41141
+ - [ ] File system: case sensitivity considered (Linux = case-sensitive)
41142
+ - [ ] Shell commands: cross-platform alternatives identified
41143
+ - [ ] Node.js APIs: no platform-specific APIs without fallbacks
41144
+
41145
+ ### PERFORMANCE domain
41146
+ - [ ] Time complexity analyzed (O(n) vs O(n\xB2) for realistic input sizes)
41147
+ - [ ] Memory allocation patterns reviewed (no unnecessary object creation in hot paths)
41148
+ - [ ] I/O operations minimized (batch where possible)
41149
+ - [ ] Caching strategy considered
41150
+ - [ ] Streaming vs. buffering decision made for large data
41151
+
40984
41152
  ## RULES
40985
41153
  - Be specific: exact names, paths, parameters, versions
40986
41154
  - Be concise: under 1500 characters
@@ -41140,6 +41308,20 @@ COVERAGE FLOOR: If you tested fewer than 80% of public functions, report:
41140
41308
  INCOMPLETE \u2014 [N] of [M] public functions tested. Missing: [list of untested functions]
41141
41309
  Do NOT report PASS/FAIL until coverage is at least 80%.
41142
41310
 
41311
+ ## ADVERSARIAL TEST PATTERNS
41312
+ When writing adversarial or security-focused tests, cover these attack categories:
41313
+
41314
+ - OVERSIZED INPUT: Strings > 10KB, arrays > 100K elements, deeply nested objects (100+ levels)
41315
+ - TYPE CONFUSION: Pass number where string expected, object where array expected, null where object expected
41316
+ - INJECTION: SQL fragments, HTML/script tags (\`<script>alert(1)</script>\`), template literals (\`\${...}\`), path traversal (\`../\`)
41317
+ - UNICODE: Null bytes (\`\\x00\`), RTL override characters, zero-width spaces, emoji, combining characters
41318
+ - BOUNDARY: \`Number.MAX_SAFE_INTEGER\`, \`-0\`, \`NaN\`, \`Infinity\`, empty string vs null vs undefined
41319
+ - AUTH BYPASS: Missing headers, expired tokens, tokens for wrong users, malformed JWT structure
41320
+ - CONCURRENCY: Simultaneous calls to same function/endpoint, race conditions on shared state
41321
+ - FILESYSTEM: Paths with spaces, Unicode filenames, symlinks, paths that would escape workspace
41322
+
41323
+ For each adversarial test: assert a SPECIFIC outcome (error thrown, value rejected, sanitized output) \u2014 not just "it doesn't crash."
41324
+
41143
41325
  ## EXECUTION VERIFICATION
41144
41326
 
41145
41327
  After writing tests, you MUST run them. A test file that was written but never executed is NOT a deliverable.
@@ -41335,6 +41517,7 @@ function getAgentConfigs(config2) {
41335
41517
  };
41336
41518
  if (agent.name === "architect" || agent.name.endsWith("_architect")) {
41337
41519
  sdkConfig.mode = "primary";
41520
+ sdkConfig.permission = { task: "allow" };
41338
41521
  } else {
41339
41522
  sdkConfig.mode = "subagent";
41340
41523
  }
@@ -52800,12 +52983,139 @@ var build_check = createSwarmTool({
52800
52983
  return JSON.stringify(result, null, 2);
52801
52984
  }
52802
52985
  });
52986
+ // src/tools/check-gate-status.ts
52987
+ init_dist();
52988
+ init_create_tool();
52989
+ import * as fs19 from "fs";
52990
+ import * as path32 from "path";
52991
+ var EVIDENCE_DIR = ".swarm/evidence";
52992
+ function isPathWithinSwarm(filePath, workspaceRoot) {
52993
+ const normalizedWorkspace = path32.resolve(workspaceRoot);
52994
+ const swarmPath = path32.join(normalizedWorkspace, ".swarm", "evidence");
52995
+ const normalizedPath = path32.resolve(filePath);
52996
+ return normalizedPath.startsWith(swarmPath);
52997
+ }
52998
+ function readEvidenceFile(evidencePath) {
52999
+ if (!fs19.existsSync(evidencePath)) {
53000
+ return null;
53001
+ }
53002
+ let content;
53003
+ try {
53004
+ content = fs19.readFileSync(evidencePath, "utf-8");
53005
+ } catch {
53006
+ return null;
53007
+ }
53008
+ let parsed;
53009
+ try {
53010
+ parsed = JSON.parse(content);
53011
+ } catch {
53012
+ return null;
53013
+ }
53014
+ if (parsed && typeof parsed === "object" && Array.isArray(parsed.required_gates) && typeof parsed.gates === "object" && parsed.gates !== null) {
53015
+ return parsed;
53016
+ }
53017
+ return null;
53018
+ }
53019
+ var check_gate_status = createSwarmTool({
53020
+ description: "Read-only tool to check the gate status of a specific task. Reads .swarm/evidence/{taskId}.json and returns structured JSON describing required, passed, and missing gates.",
53021
+ args: {
53022
+ task_id: tool.schema.string().min(1).regex(/^\d+\.\d+(\.\d+)?$/, "Task ID must be in N.M or N.M.P format").describe('The task ID to check gate status for (e.g., "1.1", "2.3.1")')
53023
+ },
53024
+ async execute(args2, directory) {
53025
+ let taskIdInput;
53026
+ try {
53027
+ if (args2 && typeof args2 === "object") {
53028
+ const obj = args2;
53029
+ taskIdInput = typeof obj.task_id === "string" ? obj.task_id : undefined;
53030
+ }
53031
+ } catch {}
53032
+ if (!taskIdInput) {
53033
+ const errorResult = {
53034
+ taskId: "",
53035
+ status: "no_evidence",
53036
+ required_gates: [],
53037
+ passed_gates: [],
53038
+ missing_gates: [],
53039
+ gates: {},
53040
+ message: "Invalid task_id: task_id is required"
53041
+ };
53042
+ return JSON.stringify(errorResult, null, 2);
53043
+ }
53044
+ const taskIdPattern = /^\d+\.\d+(\.\d+)?$/;
53045
+ if (!taskIdPattern.test(taskIdInput)) {
53046
+ const errorResult = {
53047
+ taskId: taskIdInput,
53048
+ status: "no_evidence",
53049
+ required_gates: [],
53050
+ passed_gates: [],
53051
+ missing_gates: [],
53052
+ gates: {},
53053
+ message: `Invalid task_id format: "${taskIdInput}". Must match pattern N.M or N.M.P (e.g., "1.1", "1.2.3")`
53054
+ };
53055
+ return JSON.stringify(errorResult, null, 2);
53056
+ }
53057
+ const evidencePath = path32.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
53058
+ if (!isPathWithinSwarm(evidencePath, directory)) {
53059
+ const errorResult = {
53060
+ taskId: taskIdInput,
53061
+ status: "no_evidence",
53062
+ required_gates: [],
53063
+ passed_gates: [],
53064
+ missing_gates: [],
53065
+ gates: {},
53066
+ message: "Invalid path: evidence path validation failed"
53067
+ };
53068
+ return JSON.stringify(errorResult, null, 2);
53069
+ }
53070
+ const evidenceData = readEvidenceFile(evidencePath);
53071
+ if (!evidenceData) {
53072
+ const errorResult = {
53073
+ taskId: taskIdInput,
53074
+ status: "no_evidence",
53075
+ required_gates: [],
53076
+ passed_gates: [],
53077
+ missing_gates: [],
53078
+ gates: {},
53079
+ message: `No evidence file found for task "${taskIdInput}" at ${evidencePath}. Evidence file may be missing or invalid.`
53080
+ };
53081
+ return JSON.stringify(errorResult, null, 2);
53082
+ }
53083
+ const requiredGates = evidenceData.required_gates || [];
53084
+ const gatesMap = evidenceData.gates || {};
53085
+ const passedGates = [];
53086
+ const missingGates = [];
53087
+ for (const requiredGate of requiredGates) {
53088
+ if (gatesMap[requiredGate]) {
53089
+ passedGates.push(requiredGate);
53090
+ } else {
53091
+ missingGates.push(requiredGate);
53092
+ }
53093
+ }
53094
+ const status = missingGates.length === 0 ? "all_passed" : "incomplete";
53095
+ let message;
53096
+ if (status === "all_passed") {
53097
+ message = `All required gates have passed for task "${taskIdInput}".`;
53098
+ } else {
53099
+ message = `Task "${taskIdInput}" is incomplete. Missing gates: ${missingGates.join(", ")}.`;
53100
+ }
53101
+ const result = {
53102
+ taskId: taskIdInput,
53103
+ status,
53104
+ required_gates: requiredGates,
53105
+ passed_gates: passedGates,
53106
+ missing_gates: missingGates,
53107
+ gates: gatesMap,
53108
+ message
53109
+ };
53110
+ return JSON.stringify(result, null, 2);
53111
+ }
53112
+ });
52803
53113
  // src/tools/checkpoint.ts
52804
53114
  init_tool();
52805
53115
  init_create_tool();
52806
53116
  import { spawnSync } from "child_process";
52807
- import * as fs19 from "fs";
52808
- import * as path32 from "path";
53117
+ import * as fs20 from "fs";
53118
+ import * as path33 from "path";
52809
53119
  var CHECKPOINT_LOG_PATH = ".swarm/checkpoints.json";
52810
53120
  var MAX_LABEL_LENGTH = 100;
52811
53121
  var GIT_TIMEOUT_MS = 30000;
@@ -52856,13 +53166,13 @@ function validateLabel(label) {
52856
53166
  return null;
52857
53167
  }
52858
53168
  function getCheckpointLogPath(directory) {
52859
- return path32.join(directory, CHECKPOINT_LOG_PATH);
53169
+ return path33.join(directory, CHECKPOINT_LOG_PATH);
52860
53170
  }
52861
53171
  function readCheckpointLog(directory) {
52862
53172
  const logPath = getCheckpointLogPath(directory);
52863
53173
  try {
52864
- if (fs19.existsSync(logPath)) {
52865
- const content = fs19.readFileSync(logPath, "utf-8");
53174
+ if (fs20.existsSync(logPath)) {
53175
+ const content = fs20.readFileSync(logPath, "utf-8");
52866
53176
  const parsed = JSON.parse(content);
52867
53177
  if (!parsed.checkpoints || !Array.isArray(parsed.checkpoints)) {
52868
53178
  return { version: 1, checkpoints: [] };
@@ -52874,13 +53184,13 @@ function readCheckpointLog(directory) {
52874
53184
  }
52875
53185
  function writeCheckpointLog(log2, directory) {
52876
53186
  const logPath = getCheckpointLogPath(directory);
52877
- const dir = path32.dirname(logPath);
52878
- if (!fs19.existsSync(dir)) {
52879
- fs19.mkdirSync(dir, { recursive: true });
53187
+ const dir = path33.dirname(logPath);
53188
+ if (!fs20.existsSync(dir)) {
53189
+ fs20.mkdirSync(dir, { recursive: true });
52880
53190
  }
52881
53191
  const tempPath = `${logPath}.tmp`;
52882
- fs19.writeFileSync(tempPath, JSON.stringify(log2, null, 2), "utf-8");
52883
- fs19.renameSync(tempPath, logPath);
53192
+ fs20.writeFileSync(tempPath, JSON.stringify(log2, null, 2), "utf-8");
53193
+ fs20.renameSync(tempPath, logPath);
52884
53194
  }
52885
53195
  function gitExec(args2) {
52886
53196
  const result = spawnSync("git", args2, {
@@ -53081,8 +53391,8 @@ var checkpoint = createSwarmTool({
53081
53391
  // src/tools/complexity-hotspots.ts
53082
53392
  init_dist();
53083
53393
  init_create_tool();
53084
- import * as fs20 from "fs";
53085
- import * as path33 from "path";
53394
+ import * as fs21 from "fs";
53395
+ import * as path34 from "path";
53086
53396
  var MAX_FILE_SIZE_BYTES2 = 256 * 1024;
53087
53397
  var DEFAULT_DAYS = 90;
53088
53398
  var DEFAULT_TOP_N = 20;
@@ -53211,11 +53521,11 @@ function estimateComplexity(content) {
53211
53521
  }
53212
53522
  function getComplexityForFile(filePath) {
53213
53523
  try {
53214
- const stat2 = fs20.statSync(filePath);
53524
+ const stat2 = fs21.statSync(filePath);
53215
53525
  if (stat2.size > MAX_FILE_SIZE_BYTES2) {
53216
53526
  return null;
53217
53527
  }
53218
- const content = fs20.readFileSync(filePath, "utf-8");
53528
+ const content = fs21.readFileSync(filePath, "utf-8");
53219
53529
  return estimateComplexity(content);
53220
53530
  } catch {
53221
53531
  return null;
@@ -53226,7 +53536,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
53226
53536
  const extSet = new Set(extensions.map((e) => e.startsWith(".") ? e : `.${e}`));
53227
53537
  const filteredChurn = new Map;
53228
53538
  for (const [file3, count] of churnMap) {
53229
- const ext = path33.extname(file3).toLowerCase();
53539
+ const ext = path34.extname(file3).toLowerCase();
53230
53540
  if (extSet.has(ext)) {
53231
53541
  filteredChurn.set(file3, count);
53232
53542
  }
@@ -53236,8 +53546,8 @@ async function analyzeHotspots(days, topN, extensions, directory) {
53236
53546
  let analyzedFiles = 0;
53237
53547
  for (const [file3, churnCount] of filteredChurn) {
53238
53548
  let fullPath = file3;
53239
- if (!fs20.existsSync(fullPath)) {
53240
- fullPath = path33.join(cwd, file3);
53549
+ if (!fs21.existsSync(fullPath)) {
53550
+ fullPath = path34.join(cwd, file3);
53241
53551
  }
53242
53552
  const complexity = getComplexityForFile(fullPath);
53243
53553
  if (complexity !== null) {
@@ -53384,8 +53694,8 @@ var complexity_hotspots = createSwarmTool({
53384
53694
  });
53385
53695
  // src/tools/declare-scope.ts
53386
53696
  init_tool();
53387
- import * as fs21 from "fs";
53388
- import * as path34 from "path";
53697
+ import * as fs22 from "fs";
53698
+ import * as path35 from "path";
53389
53699
  init_create_tool();
53390
53700
  function validateTaskIdFormat(taskId) {
53391
53701
  const taskIdPattern = /^\d+\.\d+(\.\d+)*$/;
@@ -53464,8 +53774,8 @@ async function executeDeclareScope(args2, fallbackDir) {
53464
53774
  };
53465
53775
  }
53466
53776
  }
53467
- normalizedDir = path34.normalize(args2.working_directory);
53468
- const pathParts = normalizedDir.split(path34.sep);
53777
+ normalizedDir = path35.normalize(args2.working_directory);
53778
+ const pathParts = normalizedDir.split(path35.sep);
53469
53779
  if (pathParts.includes("..")) {
53470
53780
  return {
53471
53781
  success: false,
@@ -53475,11 +53785,11 @@ async function executeDeclareScope(args2, fallbackDir) {
53475
53785
  ]
53476
53786
  };
53477
53787
  }
53478
- const resolvedDir = path34.resolve(normalizedDir);
53788
+ const resolvedDir = path35.resolve(normalizedDir);
53479
53789
  try {
53480
- const realPath = fs21.realpathSync(resolvedDir);
53481
- const planPath2 = path34.join(realPath, ".swarm", "plan.json");
53482
- if (!fs21.existsSync(planPath2)) {
53790
+ const realPath = fs22.realpathSync(resolvedDir);
53791
+ const planPath2 = path35.join(realPath, ".swarm", "plan.json");
53792
+ if (!fs22.existsSync(planPath2)) {
53483
53793
  return {
53484
53794
  success: false,
53485
53795
  message: `Invalid working_directory: plan not found in "${realPath}"`,
@@ -53499,8 +53809,8 @@ async function executeDeclareScope(args2, fallbackDir) {
53499
53809
  }
53500
53810
  }
53501
53811
  const directory = normalizedDir ?? fallbackDir ?? process.cwd();
53502
- const planPath = path34.resolve(directory, ".swarm", "plan.json");
53503
- if (!fs21.existsSync(planPath)) {
53812
+ const planPath = path35.resolve(directory, ".swarm", "plan.json");
53813
+ if (!fs22.existsSync(planPath)) {
53504
53814
  return {
53505
53815
  success: false,
53506
53816
  message: "No plan found",
@@ -53509,7 +53819,7 @@ async function executeDeclareScope(args2, fallbackDir) {
53509
53819
  }
53510
53820
  let planContent;
53511
53821
  try {
53512
- planContent = JSON.parse(fs21.readFileSync(planPath, "utf-8"));
53822
+ planContent = JSON.parse(fs22.readFileSync(planPath, "utf-8"));
53513
53823
  } catch {
53514
53824
  return {
53515
53825
  success: false,
@@ -53589,20 +53899,20 @@ function validateBase(base) {
53589
53899
  function validatePaths(paths) {
53590
53900
  if (!paths)
53591
53901
  return null;
53592
- for (const path35 of paths) {
53593
- if (!path35 || path35.length === 0) {
53902
+ for (const path36 of paths) {
53903
+ if (!path36 || path36.length === 0) {
53594
53904
  return "empty path not allowed";
53595
53905
  }
53596
- if (path35.length > MAX_PATH_LENGTH) {
53906
+ if (path36.length > MAX_PATH_LENGTH) {
53597
53907
  return `path exceeds maximum length of ${MAX_PATH_LENGTH}`;
53598
53908
  }
53599
- if (SHELL_METACHARACTERS2.test(path35)) {
53909
+ if (SHELL_METACHARACTERS2.test(path36)) {
53600
53910
  return "path contains shell metacharacters";
53601
53911
  }
53602
- if (path35.startsWith("-")) {
53912
+ if (path36.startsWith("-")) {
53603
53913
  return 'path cannot start with "-" (option-like arguments not allowed)';
53604
53914
  }
53605
- if (CONTROL_CHAR_PATTERN2.test(path35)) {
53915
+ if (CONTROL_CHAR_PATTERN2.test(path36)) {
53606
53916
  return "path contains control characters";
53607
53917
  }
53608
53918
  }
@@ -53682,8 +53992,8 @@ var diff = tool({
53682
53992
  if (parts2.length >= 3) {
53683
53993
  const additions = parseInt(parts2[0], 10) || 0;
53684
53994
  const deletions = parseInt(parts2[1], 10) || 0;
53685
- const path35 = parts2[2];
53686
- files.push({ path: path35, additions, deletions });
53995
+ const path36 = parts2[2];
53996
+ files.push({ path: path36, additions, deletions });
53687
53997
  }
53688
53998
  }
53689
53999
  const contractChanges = [];
@@ -53912,11 +54222,11 @@ Use these as DOMAIN values when delegating to @sme.`;
53912
54222
  // src/tools/evidence-check.ts
53913
54223
  init_dist();
53914
54224
  init_create_tool();
53915
- import * as fs22 from "fs";
53916
- import * as path35 from "path";
54225
+ import * as fs23 from "fs";
54226
+ import * as path36 from "path";
53917
54227
  var MAX_FILE_SIZE_BYTES3 = 1024 * 1024;
53918
54228
  var MAX_EVIDENCE_FILES = 1000;
53919
- var EVIDENCE_DIR = ".swarm/evidence";
54229
+ var EVIDENCE_DIR2 = ".swarm/evidence";
53920
54230
  var PLAN_FILE = ".swarm/plan.md";
53921
54231
  var SHELL_METACHAR_REGEX2 = /[;&|%$`\\]/;
53922
54232
  var VALID_EVIDENCE_FILENAME_REGEX = /^[a-zA-Z0-9_-]+\.json$/;
@@ -53935,10 +54245,10 @@ function validateRequiredTypes(input) {
53935
54245
  }
53936
54246
  return null;
53937
54247
  }
53938
- function isPathWithinSwarm(filePath, cwd) {
53939
- const normalizedCwd = path35.resolve(cwd);
53940
- const swarmPath = path35.join(normalizedCwd, ".swarm");
53941
- const normalizedPath = path35.resolve(filePath);
54248
+ function isPathWithinSwarm2(filePath, cwd) {
54249
+ const normalizedCwd = path36.resolve(cwd);
54250
+ const swarmPath = path36.join(normalizedCwd, ".swarm");
54251
+ const normalizedPath = path36.resolve(filePath);
53942
54252
  return normalizedPath.startsWith(swarmPath);
53943
54253
  }
53944
54254
  function parseCompletedTasks(planContent) {
@@ -53954,12 +54264,12 @@ function parseCompletedTasks(planContent) {
53954
54264
  }
53955
54265
  function readEvidenceFiles(evidenceDir, _cwd) {
53956
54266
  const evidence = [];
53957
- if (!fs22.existsSync(evidenceDir) || !fs22.statSync(evidenceDir).isDirectory()) {
54267
+ if (!fs23.existsSync(evidenceDir) || !fs23.statSync(evidenceDir).isDirectory()) {
53958
54268
  return evidence;
53959
54269
  }
53960
54270
  let files;
53961
54271
  try {
53962
- files = fs22.readdirSync(evidenceDir);
54272
+ files = fs23.readdirSync(evidenceDir);
53963
54273
  } catch {
53964
54274
  return evidence;
53965
54275
  }
@@ -53968,14 +54278,14 @@ function readEvidenceFiles(evidenceDir, _cwd) {
53968
54278
  if (!VALID_EVIDENCE_FILENAME_REGEX.test(filename)) {
53969
54279
  continue;
53970
54280
  }
53971
- const filePath = path35.join(evidenceDir, filename);
54281
+ const filePath = path36.join(evidenceDir, filename);
53972
54282
  try {
53973
- const resolvedPath = path35.resolve(filePath);
53974
- const evidenceDirResolved = path35.resolve(evidenceDir);
54283
+ const resolvedPath = path36.resolve(filePath);
54284
+ const evidenceDirResolved = path36.resolve(evidenceDir);
53975
54285
  if (!resolvedPath.startsWith(evidenceDirResolved)) {
53976
54286
  continue;
53977
54287
  }
53978
- const stat2 = fs22.lstatSync(filePath);
54288
+ const stat2 = fs23.lstatSync(filePath);
53979
54289
  if (!stat2.isFile()) {
53980
54290
  continue;
53981
54291
  }
@@ -53984,7 +54294,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
53984
54294
  }
53985
54295
  let fileStat;
53986
54296
  try {
53987
- fileStat = fs22.statSync(filePath);
54297
+ fileStat = fs23.statSync(filePath);
53988
54298
  if (fileStat.size > MAX_FILE_SIZE_BYTES3) {
53989
54299
  continue;
53990
54300
  }
@@ -53993,7 +54303,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
53993
54303
  }
53994
54304
  let content;
53995
54305
  try {
53996
- content = fs22.readFileSync(filePath, "utf-8");
54306
+ content = fs23.readFileSync(filePath, "utf-8");
53997
54307
  } catch {
53998
54308
  continue;
53999
54309
  }
@@ -54078,8 +54388,8 @@ var evidence_check = createSwarmTool({
54078
54388
  return JSON.stringify(errorResult, null, 2);
54079
54389
  }
54080
54390
  const requiredTypes = requiredTypesValue.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
54081
- const planPath = path35.join(cwd, PLAN_FILE);
54082
- if (!isPathWithinSwarm(planPath, cwd)) {
54391
+ const planPath = path36.join(cwd, PLAN_FILE);
54392
+ if (!isPathWithinSwarm2(planPath, cwd)) {
54083
54393
  const errorResult = {
54084
54394
  error: "plan file path validation failed",
54085
54395
  completedTasks: [],
@@ -54092,7 +54402,7 @@ var evidence_check = createSwarmTool({
54092
54402
  }
54093
54403
  let planContent;
54094
54404
  try {
54095
- planContent = fs22.readFileSync(planPath, "utf-8");
54405
+ planContent = fs23.readFileSync(planPath, "utf-8");
54096
54406
  } catch {
54097
54407
  const result2 = {
54098
54408
  message: "No completed tasks found in plan.",
@@ -54110,7 +54420,7 @@ var evidence_check = createSwarmTool({
54110
54420
  };
54111
54421
  return JSON.stringify(result2, null, 2);
54112
54422
  }
54113
- const evidenceDir = path35.join(cwd, EVIDENCE_DIR);
54423
+ const evidenceDir = path36.join(cwd, EVIDENCE_DIR2);
54114
54424
  const evidence = readEvidenceFiles(evidenceDir, cwd);
54115
54425
  const { tasksWithFullEvidence, gaps } = analyzeGaps(completedTasks, evidence, requiredTypes);
54116
54426
  const completeness = completedTasks.length > 0 ? Math.round(tasksWithFullEvidence.length / completedTasks.length * 100) / 100 : 1;
@@ -54127,8 +54437,8 @@ var evidence_check = createSwarmTool({
54127
54437
  // src/tools/file-extractor.ts
54128
54438
  init_tool();
54129
54439
  init_create_tool();
54130
- import * as fs23 from "fs";
54131
- import * as path36 from "path";
54440
+ import * as fs24 from "fs";
54441
+ import * as path37 from "path";
54132
54442
  var EXT_MAP = {
54133
54443
  python: ".py",
54134
54444
  py: ".py",
@@ -54190,8 +54500,8 @@ var extract_code_blocks = createSwarmTool({
54190
54500
  execute: async (args2, directory) => {
54191
54501
  const { content, output_dir, prefix } = args2;
54192
54502
  const targetDir = output_dir || directory;
54193
- if (!fs23.existsSync(targetDir)) {
54194
- fs23.mkdirSync(targetDir, { recursive: true });
54503
+ if (!fs24.existsSync(targetDir)) {
54504
+ fs24.mkdirSync(targetDir, { recursive: true });
54195
54505
  }
54196
54506
  if (!content) {
54197
54507
  return "Error: content is required";
@@ -54209,16 +54519,16 @@ var extract_code_blocks = createSwarmTool({
54209
54519
  if (prefix) {
54210
54520
  filename = `${prefix}_${filename}`;
54211
54521
  }
54212
- let filepath = path36.join(targetDir, filename);
54213
- const base = path36.basename(filepath, path36.extname(filepath));
54214
- const ext = path36.extname(filepath);
54522
+ let filepath = path37.join(targetDir, filename);
54523
+ const base = path37.basename(filepath, path37.extname(filepath));
54524
+ const ext = path37.extname(filepath);
54215
54525
  let counter = 1;
54216
- while (fs23.existsSync(filepath)) {
54217
- filepath = path36.join(targetDir, `${base}_${counter}${ext}`);
54526
+ while (fs24.existsSync(filepath)) {
54527
+ filepath = path37.join(targetDir, `${base}_${counter}${ext}`);
54218
54528
  counter++;
54219
54529
  }
54220
54530
  try {
54221
- fs23.writeFileSync(filepath, code.trim(), "utf-8");
54531
+ fs24.writeFileSync(filepath, code.trim(), "utf-8");
54222
54532
  savedFiles.push(filepath);
54223
54533
  } catch (error93) {
54224
54534
  errors5.push(`Failed to save ${filename}: ${error93 instanceof Error ? error93.message : String(error93)}`);
@@ -54247,7 +54557,7 @@ init_dist();
54247
54557
  var GITINGEST_TIMEOUT_MS = 1e4;
54248
54558
  var GITINGEST_MAX_RESPONSE_BYTES = 5242880;
54249
54559
  var GITINGEST_MAX_RETRIES = 2;
54250
- var delay = (ms) => new Promise((resolve12) => setTimeout(resolve12, ms));
54560
+ var delay = (ms) => new Promise((resolve13) => setTimeout(resolve13, ms));
54251
54561
  async function fetchGitingest(args2) {
54252
54562
  for (let attempt = 0;attempt <= GITINGEST_MAX_RETRIES; attempt++) {
54253
54563
  try {
@@ -54331,8 +54641,8 @@ var gitingest = tool({
54331
54641
  });
54332
54642
  // src/tools/imports.ts
54333
54643
  init_dist();
54334
- import * as fs24 from "fs";
54335
- import * as path37 from "path";
54644
+ import * as fs25 from "fs";
54645
+ import * as path38 from "path";
54336
54646
  var MAX_FILE_PATH_LENGTH2 = 500;
54337
54647
  var MAX_SYMBOL_LENGTH = 256;
54338
54648
  var MAX_FILE_SIZE_BYTES4 = 1024 * 1024;
@@ -54386,7 +54696,7 @@ function validateSymbolInput(symbol3) {
54386
54696
  return null;
54387
54697
  }
54388
54698
  function isBinaryFile2(filePath, buffer) {
54389
- const ext = path37.extname(filePath).toLowerCase();
54699
+ const ext = path38.extname(filePath).toLowerCase();
54390
54700
  if (ext === ".json" || ext === ".md" || ext === ".txt") {
54391
54701
  return false;
54392
54702
  }
@@ -54410,15 +54720,15 @@ function parseImports(content, targetFile, targetSymbol) {
54410
54720
  const imports = [];
54411
54721
  let _resolvedTarget;
54412
54722
  try {
54413
- _resolvedTarget = path37.resolve(targetFile);
54723
+ _resolvedTarget = path38.resolve(targetFile);
54414
54724
  } catch {
54415
54725
  _resolvedTarget = targetFile;
54416
54726
  }
54417
- const targetBasename = path37.basename(targetFile, path37.extname(targetFile));
54727
+ const targetBasename = path38.basename(targetFile, path38.extname(targetFile));
54418
54728
  const targetWithExt = targetFile;
54419
54729
  const targetWithoutExt = targetFile.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
54420
- const normalizedTargetWithExt = path37.normalize(targetWithExt).replace(/\\/g, "/");
54421
- const normalizedTargetWithoutExt = path37.normalize(targetWithoutExt).replace(/\\/g, "/");
54730
+ const normalizedTargetWithExt = path38.normalize(targetWithExt).replace(/\\/g, "/");
54731
+ const normalizedTargetWithoutExt = path38.normalize(targetWithoutExt).replace(/\\/g, "/");
54422
54732
  const importRegex = /import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
54423
54733
  for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
54424
54734
  const modulePath = match[1] || match[2] || match[3];
@@ -54441,9 +54751,9 @@ function parseImports(content, targetFile, targetSymbol) {
54441
54751
  }
54442
54752
  const _normalizedModule = modulePath.replace(/^\.\//, "").replace(/^\.\.\\/, "../");
54443
54753
  let isMatch = false;
54444
- const _targetDir = path37.dirname(targetFile);
54445
- const targetExt = path37.extname(targetFile);
54446
- const targetBasenameNoExt = path37.basename(targetFile, targetExt);
54754
+ const _targetDir = path38.dirname(targetFile);
54755
+ const targetExt = path38.extname(targetFile);
54756
+ const targetBasenameNoExt = path38.basename(targetFile, targetExt);
54447
54757
  const moduleNormalized = modulePath.replace(/\\/g, "/").replace(/^\.\//, "");
54448
54758
  const moduleName = modulePath.split(/[/\\]/).pop() || "";
54449
54759
  const moduleNameNoExt = moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
@@ -54500,7 +54810,7 @@ var SKIP_DIRECTORIES2 = new Set([
54500
54810
  function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFiles: 0, fileErrors: [] }) {
54501
54811
  let entries;
54502
54812
  try {
54503
- entries = fs24.readdirSync(dir);
54813
+ entries = fs25.readdirSync(dir);
54504
54814
  } catch (e) {
54505
54815
  stats.fileErrors.push({
54506
54816
  path: dir,
@@ -54511,13 +54821,13 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
54511
54821
  entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
54512
54822
  for (const entry of entries) {
54513
54823
  if (SKIP_DIRECTORIES2.has(entry)) {
54514
- stats.skippedDirs.push(path37.join(dir, entry));
54824
+ stats.skippedDirs.push(path38.join(dir, entry));
54515
54825
  continue;
54516
54826
  }
54517
- const fullPath = path37.join(dir, entry);
54827
+ const fullPath = path38.join(dir, entry);
54518
54828
  let stat2;
54519
54829
  try {
54520
- stat2 = fs24.statSync(fullPath);
54830
+ stat2 = fs25.statSync(fullPath);
54521
54831
  } catch (e) {
54522
54832
  stats.fileErrors.push({
54523
54833
  path: fullPath,
@@ -54528,7 +54838,7 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
54528
54838
  if (stat2.isDirectory()) {
54529
54839
  findSourceFiles2(fullPath, files, stats);
54530
54840
  } else if (stat2.isFile()) {
54531
- const ext = path37.extname(fullPath).toLowerCase();
54841
+ const ext = path38.extname(fullPath).toLowerCase();
54532
54842
  if (SUPPORTED_EXTENSIONS.includes(ext)) {
54533
54843
  files.push(fullPath);
54534
54844
  }
@@ -54584,8 +54894,8 @@ var imports = tool({
54584
54894
  return JSON.stringify(errorResult, null, 2);
54585
54895
  }
54586
54896
  try {
54587
- const targetFile = path37.resolve(file3);
54588
- if (!fs24.existsSync(targetFile)) {
54897
+ const targetFile = path38.resolve(file3);
54898
+ if (!fs25.existsSync(targetFile)) {
54589
54899
  const errorResult = {
54590
54900
  error: `target file not found: ${file3}`,
54591
54901
  target: file3,
@@ -54595,7 +54905,7 @@ var imports = tool({
54595
54905
  };
54596
54906
  return JSON.stringify(errorResult, null, 2);
54597
54907
  }
54598
- const targetStat = fs24.statSync(targetFile);
54908
+ const targetStat = fs25.statSync(targetFile);
54599
54909
  if (!targetStat.isFile()) {
54600
54910
  const errorResult = {
54601
54911
  error: "target must be a file, not a directory",
@@ -54606,7 +54916,7 @@ var imports = tool({
54606
54916
  };
54607
54917
  return JSON.stringify(errorResult, null, 2);
54608
54918
  }
54609
- const baseDir = path37.dirname(targetFile);
54919
+ const baseDir = path38.dirname(targetFile);
54610
54920
  const scanStats = {
54611
54921
  skippedDirs: [],
54612
54922
  skippedFiles: 0,
@@ -54621,12 +54931,12 @@ var imports = tool({
54621
54931
  if (consumers.length >= MAX_CONSUMERS)
54622
54932
  break;
54623
54933
  try {
54624
- const stat2 = fs24.statSync(filePath);
54934
+ const stat2 = fs25.statSync(filePath);
54625
54935
  if (stat2.size > MAX_FILE_SIZE_BYTES4) {
54626
54936
  skippedFileCount++;
54627
54937
  continue;
54628
54938
  }
54629
- const buffer = fs24.readFileSync(filePath);
54939
+ const buffer = fs25.readFileSync(filePath);
54630
54940
  if (isBinaryFile2(filePath, buffer)) {
54631
54941
  skippedFileCount++;
54632
54942
  continue;
@@ -54691,7 +55001,7 @@ var imports = tool({
54691
55001
  });
54692
55002
  // src/tools/knowledge-query.ts
54693
55003
  init_dist();
54694
- import { existsSync as existsSync25 } from "fs";
55004
+ import { existsSync as existsSync26 } from "fs";
54695
55005
  init_create_tool();
54696
55006
  var DEFAULT_LIMIT = 10;
54697
55007
  var MAX_LESSON_LENGTH = 200;
@@ -54761,14 +55071,14 @@ function validateLimit(limit) {
54761
55071
  }
54762
55072
  async function readSwarmKnowledge(directory) {
54763
55073
  const swarmPath = resolveSwarmKnowledgePath(directory);
54764
- if (!existsSync25(swarmPath)) {
55074
+ if (!existsSync26(swarmPath)) {
54765
55075
  return [];
54766
55076
  }
54767
55077
  return readKnowledge(swarmPath);
54768
55078
  }
54769
55079
  async function readHiveKnowledge() {
54770
55080
  const hivePath = resolveHiveKnowledgePath();
54771
- if (!existsSync25(hivePath)) {
55081
+ if (!existsSync26(hivePath)) {
54772
55082
  return [];
54773
55083
  }
54774
55084
  return readKnowledge(hivePath);
@@ -54927,8 +55237,8 @@ init_dist();
54927
55237
  init_config();
54928
55238
  init_schema();
54929
55239
  init_manager();
54930
- import * as fs25 from "fs";
54931
- import * as path38 from "path";
55240
+ import * as fs26 from "fs";
55241
+ import * as path39 from "path";
54932
55242
  init_utils2();
54933
55243
  init_create_tool();
54934
55244
  function safeWarn(message, error93) {
@@ -55123,7 +55433,7 @@ async function executePhaseComplete(args2, workingDirectory) {
55123
55433
  }
55124
55434
  if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
55125
55435
  try {
55126
- const projectName = path38.basename(dir);
55436
+ const projectName = path39.basename(dir);
55127
55437
  const knowledgeConfig = {
55128
55438
  enabled: true,
55129
55439
  swarm_max_entries: 100,
@@ -55171,7 +55481,7 @@ async function executePhaseComplete(args2, workingDirectory) {
55171
55481
  if (agentsMissing.length > 0) {
55172
55482
  try {
55173
55483
  const planPath = validateSwarmPath(dir, "plan.json");
55174
- const planRaw = fs25.readFileSync(planPath, "utf-8");
55484
+ const planRaw = fs26.readFileSync(planPath, "utf-8");
55175
55485
  const plan = JSON.parse(planRaw);
55176
55486
  const targetPhase = plan.phases.find((p) => p.id === phase);
55177
55487
  if (targetPhase && targetPhase.tasks.length > 0 && targetPhase.tasks.every((t) => t.status === "completed")) {
@@ -55212,7 +55522,7 @@ async function executePhaseComplete(args2, workingDirectory) {
55212
55522
  };
55213
55523
  try {
55214
55524
  const eventsPath = validateSwarmPath(dir, "events.jsonl");
55215
- fs25.appendFileSync(eventsPath, `${JSON.stringify(event)}
55525
+ fs26.appendFileSync(eventsPath, `${JSON.stringify(event)}
55216
55526
  `, "utf-8");
55217
55527
  } catch (writeError) {
55218
55528
  warnings.push(`Warning: failed to write phase complete event: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
@@ -55231,12 +55541,12 @@ async function executePhaseComplete(args2, workingDirectory) {
55231
55541
  }
55232
55542
  try {
55233
55543
  const planPath = validateSwarmPath(dir, "plan.json");
55234
- const planJson = fs25.readFileSync(planPath, "utf-8");
55544
+ const planJson = fs26.readFileSync(planPath, "utf-8");
55235
55545
  const plan = JSON.parse(planJson);
55236
55546
  const phaseObj = plan.phases.find((p) => p.id === phase);
55237
55547
  if (phaseObj) {
55238
55548
  phaseObj.status = "completed";
55239
- fs25.writeFileSync(planPath, `${JSON.stringify(plan, null, 2)}
55549
+ fs26.writeFileSync(planPath, `${JSON.stringify(plan, null, 2)}
55240
55550
  `, "utf-8");
55241
55551
  }
55242
55552
  } catch (error93) {
@@ -55286,8 +55596,8 @@ init_dist();
55286
55596
  init_discovery();
55287
55597
  init_utils();
55288
55598
  init_create_tool();
55289
- import * as fs26 from "fs";
55290
- import * as path39 from "path";
55599
+ import * as fs27 from "fs";
55600
+ import * as path40 from "path";
55291
55601
  var MAX_OUTPUT_BYTES5 = 52428800;
55292
55602
  var AUDIT_TIMEOUT_MS = 120000;
55293
55603
  function isValidEcosystem(value) {
@@ -55305,28 +55615,28 @@ function validateArgs3(args2) {
55305
55615
  function detectEcosystems(directory) {
55306
55616
  const ecosystems = [];
55307
55617
  const cwd = directory;
55308
- if (fs26.existsSync(path39.join(cwd, "package.json"))) {
55618
+ if (fs27.existsSync(path40.join(cwd, "package.json"))) {
55309
55619
  ecosystems.push("npm");
55310
55620
  }
55311
- if (fs26.existsSync(path39.join(cwd, "pyproject.toml")) || fs26.existsSync(path39.join(cwd, "requirements.txt"))) {
55621
+ if (fs27.existsSync(path40.join(cwd, "pyproject.toml")) || fs27.existsSync(path40.join(cwd, "requirements.txt"))) {
55312
55622
  ecosystems.push("pip");
55313
55623
  }
55314
- if (fs26.existsSync(path39.join(cwd, "Cargo.toml"))) {
55624
+ if (fs27.existsSync(path40.join(cwd, "Cargo.toml"))) {
55315
55625
  ecosystems.push("cargo");
55316
55626
  }
55317
- if (fs26.existsSync(path39.join(cwd, "go.mod"))) {
55627
+ if (fs27.existsSync(path40.join(cwd, "go.mod"))) {
55318
55628
  ecosystems.push("go");
55319
55629
  }
55320
55630
  try {
55321
- const files = fs26.readdirSync(cwd);
55631
+ const files = fs27.readdirSync(cwd);
55322
55632
  if (files.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"))) {
55323
55633
  ecosystems.push("dotnet");
55324
55634
  }
55325
55635
  } catch {}
55326
- if (fs26.existsSync(path39.join(cwd, "Gemfile")) || fs26.existsSync(path39.join(cwd, "Gemfile.lock"))) {
55636
+ if (fs27.existsSync(path40.join(cwd, "Gemfile")) || fs27.existsSync(path40.join(cwd, "Gemfile.lock"))) {
55327
55637
  ecosystems.push("ruby");
55328
55638
  }
55329
- if (fs26.existsSync(path39.join(cwd, "pubspec.yaml"))) {
55639
+ if (fs27.existsSync(path40.join(cwd, "pubspec.yaml"))) {
55330
55640
  ecosystems.push("dart");
55331
55641
  }
55332
55642
  return ecosystems;
@@ -55339,7 +55649,7 @@ async function runNpmAudit(directory) {
55339
55649
  stderr: "pipe",
55340
55650
  cwd: directory
55341
55651
  });
55342
- const timeoutPromise = new Promise((resolve13) => setTimeout(() => resolve13("timeout"), AUDIT_TIMEOUT_MS));
55652
+ const timeoutPromise = new Promise((resolve14) => setTimeout(() => resolve14("timeout"), AUDIT_TIMEOUT_MS));
55343
55653
  const result = await Promise.race([
55344
55654
  Promise.all([
55345
55655
  new Response(proc.stdout).text(),
@@ -55462,7 +55772,7 @@ async function runPipAudit(directory) {
55462
55772
  stderr: "pipe",
55463
55773
  cwd: directory
55464
55774
  });
55465
- const timeoutPromise = new Promise((resolve13) => setTimeout(() => resolve13("timeout"), AUDIT_TIMEOUT_MS));
55775
+ const timeoutPromise = new Promise((resolve14) => setTimeout(() => resolve14("timeout"), AUDIT_TIMEOUT_MS));
55466
55776
  const result = await Promise.race([
55467
55777
  Promise.all([
55468
55778
  new Response(proc.stdout).text(),
@@ -55593,7 +55903,7 @@ async function runCargoAudit(directory) {
55593
55903
  stderr: "pipe",
55594
55904
  cwd: directory
55595
55905
  });
55596
- const timeoutPromise = new Promise((resolve13) => setTimeout(() => resolve13("timeout"), AUDIT_TIMEOUT_MS));
55906
+ const timeoutPromise = new Promise((resolve14) => setTimeout(() => resolve14("timeout"), AUDIT_TIMEOUT_MS));
55597
55907
  const result = await Promise.race([
55598
55908
  Promise.all([
55599
55909
  new Response(proc.stdout).text(),
@@ -55720,7 +56030,7 @@ async function runGoAudit(directory) {
55720
56030
  stderr: "pipe",
55721
56031
  cwd: directory
55722
56032
  });
55723
- const timeoutPromise = new Promise((resolve13) => setTimeout(() => resolve13("timeout"), AUDIT_TIMEOUT_MS));
56033
+ const timeoutPromise = new Promise((resolve14) => setTimeout(() => resolve14("timeout"), AUDIT_TIMEOUT_MS));
55724
56034
  const result = await Promise.race([
55725
56035
  Promise.all([
55726
56036
  new Response(proc.stdout).text(),
@@ -55856,7 +56166,7 @@ async function runDotnetAudit(directory) {
55856
56166
  stderr: "pipe",
55857
56167
  cwd: directory
55858
56168
  });
55859
- const timeoutPromise = new Promise((resolve13) => setTimeout(() => resolve13("timeout"), AUDIT_TIMEOUT_MS));
56169
+ const timeoutPromise = new Promise((resolve14) => setTimeout(() => resolve14("timeout"), AUDIT_TIMEOUT_MS));
55860
56170
  const result = await Promise.race([
55861
56171
  Promise.all([
55862
56172
  new Response(proc.stdout).text(),
@@ -55975,7 +56285,7 @@ async function runBundleAudit(directory) {
55975
56285
  stderr: "pipe",
55976
56286
  cwd: directory
55977
56287
  });
55978
- const timeoutPromise = new Promise((resolve13) => setTimeout(() => resolve13("timeout"), AUDIT_TIMEOUT_MS));
56288
+ const timeoutPromise = new Promise((resolve14) => setTimeout(() => resolve14("timeout"), AUDIT_TIMEOUT_MS));
55979
56289
  const result = await Promise.race([
55980
56290
  Promise.all([
55981
56291
  new Response(proc.stdout).text(),
@@ -56122,7 +56432,7 @@ async function runDartAudit(directory) {
56122
56432
  stderr: "pipe",
56123
56433
  cwd: directory
56124
56434
  });
56125
- const timeoutPromise = new Promise((resolve13) => setTimeout(() => resolve13("timeout"), AUDIT_TIMEOUT_MS));
56435
+ const timeoutPromise = new Promise((resolve14) => setTimeout(() => resolve14("timeout"), AUDIT_TIMEOUT_MS));
56126
56436
  const result = await Promise.race([
56127
56437
  Promise.all([
56128
56438
  new Response(proc.stdout).text(),
@@ -56388,8 +56698,8 @@ var SUPPORTED_PARSER_EXTENSIONS = new Set([
56388
56698
  ]);
56389
56699
  // src/tools/pre-check-batch.ts
56390
56700
  init_dist();
56391
- import * as fs29 from "fs";
56392
- import * as path42 from "path";
56701
+ import * as fs30 from "fs";
56702
+ import * as path43 from "path";
56393
56703
 
56394
56704
  // node_modules/yocto-queue/index.js
56395
56705
  class Node2 {
@@ -56480,26 +56790,26 @@ function pLimit(concurrency) {
56480
56790
  activeCount--;
56481
56791
  resumeNext();
56482
56792
  };
56483
- const run2 = async (function_, resolve13, arguments_2) => {
56793
+ const run2 = async (function_, resolve14, arguments_2) => {
56484
56794
  const result = (async () => function_(...arguments_2))();
56485
- resolve13(result);
56795
+ resolve14(result);
56486
56796
  try {
56487
56797
  await result;
56488
56798
  } catch {}
56489
56799
  next();
56490
56800
  };
56491
- const enqueue = (function_, resolve13, reject, arguments_2) => {
56801
+ const enqueue = (function_, resolve14, reject, arguments_2) => {
56492
56802
  const queueItem = { reject };
56493
56803
  new Promise((internalResolve) => {
56494
56804
  queueItem.run = internalResolve;
56495
56805
  queue.enqueue(queueItem);
56496
- }).then(run2.bind(undefined, function_, resolve13, arguments_2));
56806
+ }).then(run2.bind(undefined, function_, resolve14, arguments_2));
56497
56807
  if (activeCount < concurrency) {
56498
56808
  resumeNext();
56499
56809
  }
56500
56810
  };
56501
- const generator = (function_, ...arguments_2) => new Promise((resolve13, reject) => {
56502
- enqueue(function_, resolve13, reject, arguments_2);
56811
+ const generator = (function_, ...arguments_2) => new Promise((resolve14, reject) => {
56812
+ enqueue(function_, resolve14, reject, arguments_2);
56503
56813
  });
56504
56814
  Object.defineProperties(generator, {
56505
56815
  activeCount: {
@@ -56556,8 +56866,8 @@ init_lint();
56556
56866
  init_manager();
56557
56867
 
56558
56868
  // src/quality/metrics.ts
56559
- import * as fs27 from "fs";
56560
- import * as path40 from "path";
56869
+ import * as fs28 from "fs";
56870
+ import * as path41 from "path";
56561
56871
  var MAX_FILE_SIZE_BYTES5 = 256 * 1024;
56562
56872
  var MIN_DUPLICATION_LINES = 10;
56563
56873
  function estimateCyclomaticComplexity(content) {
@@ -56595,11 +56905,11 @@ function estimateCyclomaticComplexity(content) {
56595
56905
  }
56596
56906
  function getComplexityForFile2(filePath) {
56597
56907
  try {
56598
- const stat2 = fs27.statSync(filePath);
56908
+ const stat2 = fs28.statSync(filePath);
56599
56909
  if (stat2.size > MAX_FILE_SIZE_BYTES5) {
56600
56910
  return null;
56601
56911
  }
56602
- const content = fs27.readFileSync(filePath, "utf-8");
56912
+ const content = fs28.readFileSync(filePath, "utf-8");
56603
56913
  return estimateCyclomaticComplexity(content);
56604
56914
  } catch {
56605
56915
  return null;
@@ -56609,8 +56919,8 @@ async function computeComplexityDelta(files, workingDir) {
56609
56919
  let totalComplexity = 0;
56610
56920
  const analyzedFiles = [];
56611
56921
  for (const file3 of files) {
56612
- const fullPath = path40.isAbsolute(file3) ? file3 : path40.join(workingDir, file3);
56613
- if (!fs27.existsSync(fullPath)) {
56922
+ const fullPath = path41.isAbsolute(file3) ? file3 : path41.join(workingDir, file3);
56923
+ if (!fs28.existsSync(fullPath)) {
56614
56924
  continue;
56615
56925
  }
56616
56926
  const complexity = getComplexityForFile2(fullPath);
@@ -56731,8 +57041,8 @@ function countGoExports(content) {
56731
57041
  }
56732
57042
  function getExportCountForFile(filePath) {
56733
57043
  try {
56734
- const content = fs27.readFileSync(filePath, "utf-8");
56735
- const ext = path40.extname(filePath).toLowerCase();
57044
+ const content = fs28.readFileSync(filePath, "utf-8");
57045
+ const ext = path41.extname(filePath).toLowerCase();
56736
57046
  switch (ext) {
56737
57047
  case ".ts":
56738
57048
  case ".tsx":
@@ -56758,8 +57068,8 @@ async function computePublicApiDelta(files, workingDir) {
56758
57068
  let totalExports = 0;
56759
57069
  const analyzedFiles = [];
56760
57070
  for (const file3 of files) {
56761
- const fullPath = path40.isAbsolute(file3) ? file3 : path40.join(workingDir, file3);
56762
- if (!fs27.existsSync(fullPath)) {
57071
+ const fullPath = path41.isAbsolute(file3) ? file3 : path41.join(workingDir, file3);
57072
+ if (!fs28.existsSync(fullPath)) {
56763
57073
  continue;
56764
57074
  }
56765
57075
  const exports = getExportCountForFile(fullPath);
@@ -56792,16 +57102,16 @@ async function computeDuplicationRatio(files, workingDir) {
56792
57102
  let duplicateLines = 0;
56793
57103
  const analyzedFiles = [];
56794
57104
  for (const file3 of files) {
56795
- const fullPath = path40.isAbsolute(file3) ? file3 : path40.join(workingDir, file3);
56796
- if (!fs27.existsSync(fullPath)) {
57105
+ const fullPath = path41.isAbsolute(file3) ? file3 : path41.join(workingDir, file3);
57106
+ if (!fs28.existsSync(fullPath)) {
56797
57107
  continue;
56798
57108
  }
56799
57109
  try {
56800
- const stat2 = fs27.statSync(fullPath);
57110
+ const stat2 = fs28.statSync(fullPath);
56801
57111
  if (stat2.size > MAX_FILE_SIZE_BYTES5) {
56802
57112
  continue;
56803
57113
  }
56804
- const content = fs27.readFileSync(fullPath, "utf-8");
57114
+ const content = fs28.readFileSync(fullPath, "utf-8");
56805
57115
  const lines = content.split(`
56806
57116
  `).filter((line) => line.trim().length > 0);
56807
57117
  if (lines.length < MIN_DUPLICATION_LINES) {
@@ -56825,8 +57135,8 @@ function countCodeLines(content) {
56825
57135
  return lines.length;
56826
57136
  }
56827
57137
  function isTestFile(filePath) {
56828
- const basename8 = path40.basename(filePath);
56829
- const _ext = path40.extname(filePath).toLowerCase();
57138
+ const basename8 = path41.basename(filePath);
57139
+ const _ext = path41.extname(filePath).toLowerCase();
56830
57140
  const testPatterns = [
56831
57141
  ".test.",
56832
57142
  ".spec.",
@@ -56907,8 +57217,8 @@ function matchGlobSegment(globSegments, pathSegments) {
56907
57217
  }
56908
57218
  return gIndex === globSegments.length && pIndex === pathSegments.length;
56909
57219
  }
56910
- function matchesGlobSegment(path41, glob) {
56911
- const normalizedPath = path41.replace(/\\/g, "/");
57220
+ function matchesGlobSegment(path42, glob) {
57221
+ const normalizedPath = path42.replace(/\\/g, "/");
56912
57222
  const normalizedGlob = glob.replace(/\\/g, "/");
56913
57223
  if (normalizedPath.includes("//")) {
56914
57224
  return false;
@@ -56939,8 +57249,8 @@ function simpleGlobToRegex2(glob) {
56939
57249
  function hasGlobstar(glob) {
56940
57250
  return glob.includes("**");
56941
57251
  }
56942
- function globMatches(path41, glob) {
56943
- const normalizedPath = path41.replace(/\\/g, "/");
57252
+ function globMatches(path42, glob) {
57253
+ const normalizedPath = path42.replace(/\\/g, "/");
56944
57254
  if (!glob || glob === "") {
56945
57255
  if (normalizedPath.includes("//")) {
56946
57256
  return false;
@@ -56976,31 +57286,31 @@ function shouldExcludeFile(filePath, excludeGlobs) {
56976
57286
  async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
56977
57287
  let testLines = 0;
56978
57288
  let codeLines = 0;
56979
- const srcDir = path40.join(workingDir, "src");
56980
- if (fs27.existsSync(srcDir)) {
57289
+ const srcDir = path41.join(workingDir, "src");
57290
+ if (fs28.existsSync(srcDir)) {
56981
57291
  await scanDirectoryForLines(srcDir, enforceGlobs, excludeGlobs, false, (lines) => {
56982
57292
  codeLines += lines;
56983
57293
  });
56984
57294
  }
56985
57295
  const possibleSrcDirs = ["lib", "app", "source", "core"];
56986
57296
  for (const dir of possibleSrcDirs) {
56987
- const dirPath = path40.join(workingDir, dir);
56988
- if (fs27.existsSync(dirPath)) {
57297
+ const dirPath = path41.join(workingDir, dir);
57298
+ if (fs28.existsSync(dirPath)) {
56989
57299
  await scanDirectoryForLines(dirPath, enforceGlobs, excludeGlobs, false, (lines) => {
56990
57300
  codeLines += lines;
56991
57301
  });
56992
57302
  }
56993
57303
  }
56994
- const testsDir = path40.join(workingDir, "tests");
56995
- if (fs27.existsSync(testsDir)) {
57304
+ const testsDir = path41.join(workingDir, "tests");
57305
+ if (fs28.existsSync(testsDir)) {
56996
57306
  await scanDirectoryForLines(testsDir, ["**"], ["node_modules", "dist"], true, (lines) => {
56997
57307
  testLines += lines;
56998
57308
  });
56999
57309
  }
57000
57310
  const possibleTestDirs = ["test", "__tests__", "specs"];
57001
57311
  for (const dir of possibleTestDirs) {
57002
- const dirPath = path40.join(workingDir, dir);
57003
- if (fs27.existsSync(dirPath) && dirPath !== testsDir) {
57312
+ const dirPath = path41.join(workingDir, dir);
57313
+ if (fs28.existsSync(dirPath) && dirPath !== testsDir) {
57004
57314
  await scanDirectoryForLines(dirPath, ["**"], ["node_modules", "dist"], true, (lines) => {
57005
57315
  testLines += lines;
57006
57316
  });
@@ -57012,9 +57322,9 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
57012
57322
  }
57013
57323
  async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTestScan, callback) {
57014
57324
  try {
57015
- const entries = fs27.readdirSync(dirPath, { withFileTypes: true });
57325
+ const entries = fs28.readdirSync(dirPath, { withFileTypes: true });
57016
57326
  for (const entry of entries) {
57017
- const fullPath = path40.join(dirPath, entry.name);
57327
+ const fullPath = path41.join(dirPath, entry.name);
57018
57328
  if (entry.isDirectory()) {
57019
57329
  if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === ".git") {
57020
57330
  continue;
@@ -57022,7 +57332,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
57022
57332
  await scanDirectoryForLines(fullPath, includeGlobs, excludeGlobs, isTestScan, callback);
57023
57333
  } else if (entry.isFile()) {
57024
57334
  const relativePath = fullPath.replace(`${process.cwd()}/`, "");
57025
- const ext = path40.extname(entry.name).toLowerCase();
57335
+ const ext = path41.extname(entry.name).toLowerCase();
57026
57336
  const validExts = [
57027
57337
  ".ts",
57028
57338
  ".tsx",
@@ -57058,7 +57368,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
57058
57368
  continue;
57059
57369
  }
57060
57370
  try {
57061
- const content = fs27.readFileSync(fullPath, "utf-8");
57371
+ const content = fs28.readFileSync(fullPath, "utf-8");
57062
57372
  const lines = countCodeLines(content);
57063
57373
  callback(lines);
57064
57374
  } catch {}
@@ -57272,8 +57582,8 @@ async function qualityBudget(input, directory) {
57272
57582
  init_dist();
57273
57583
  init_manager();
57274
57584
  init_detector();
57275
- import * as fs28 from "fs";
57276
- import * as path41 from "path";
57585
+ import * as fs29 from "fs";
57586
+ import * as path42 from "path";
57277
57587
  import { extname as extname9 } from "path";
57278
57588
 
57279
57589
  // src/sast/rules/c.ts
@@ -58021,7 +58331,7 @@ function mapSemgrepSeverity(severity) {
58021
58331
  }
58022
58332
  }
58023
58333
  async function executeWithTimeout(command, args2, options) {
58024
- return new Promise((resolve13) => {
58334
+ return new Promise((resolve14) => {
58025
58335
  const child = spawn(command, args2, {
58026
58336
  shell: false,
58027
58337
  cwd: options.cwd
@@ -58030,7 +58340,7 @@ async function executeWithTimeout(command, args2, options) {
58030
58340
  let stderr = "";
58031
58341
  const timeout = setTimeout(() => {
58032
58342
  child.kill("SIGTERM");
58033
- resolve13({
58343
+ resolve14({
58034
58344
  stdout,
58035
58345
  stderr: "Process timed out",
58036
58346
  exitCode: 124
@@ -58044,7 +58354,7 @@ async function executeWithTimeout(command, args2, options) {
58044
58354
  });
58045
58355
  child.on("close", (code) => {
58046
58356
  clearTimeout(timeout);
58047
- resolve13({
58357
+ resolve14({
58048
58358
  stdout,
58049
58359
  stderr,
58050
58360
  exitCode: code ?? 0
@@ -58052,7 +58362,7 @@ async function executeWithTimeout(command, args2, options) {
58052
58362
  });
58053
58363
  child.on("error", (err2) => {
58054
58364
  clearTimeout(timeout);
58055
- resolve13({
58365
+ resolve14({
58056
58366
  stdout,
58057
58367
  stderr: err2.message,
58058
58368
  exitCode: 1
@@ -58140,17 +58450,17 @@ var SEVERITY_ORDER = {
58140
58450
  };
58141
58451
  function shouldSkipFile(filePath) {
58142
58452
  try {
58143
- const stats = fs28.statSync(filePath);
58453
+ const stats = fs29.statSync(filePath);
58144
58454
  if (stats.size > MAX_FILE_SIZE_BYTES6) {
58145
58455
  return { skip: true, reason: "file too large" };
58146
58456
  }
58147
58457
  if (stats.size === 0) {
58148
58458
  return { skip: true, reason: "empty file" };
58149
58459
  }
58150
- const fd = fs28.openSync(filePath, "r");
58460
+ const fd = fs29.openSync(filePath, "r");
58151
58461
  const buffer = Buffer.alloc(8192);
58152
- const bytesRead = fs28.readSync(fd, buffer, 0, 8192, 0);
58153
- fs28.closeSync(fd);
58462
+ const bytesRead = fs29.readSync(fd, buffer, 0, 8192, 0);
58463
+ fs29.closeSync(fd);
58154
58464
  if (bytesRead > 0) {
58155
58465
  let nullCount = 0;
58156
58466
  for (let i2 = 0;i2 < bytesRead; i2++) {
@@ -58189,7 +58499,7 @@ function countBySeverity(findings) {
58189
58499
  }
58190
58500
  function scanFileWithTierA(filePath, language) {
58191
58501
  try {
58192
- const content = fs28.readFileSync(filePath, "utf-8");
58502
+ const content = fs29.readFileSync(filePath, "utf-8");
58193
58503
  const findings = executeRulesSync(filePath, content, language);
58194
58504
  return findings.map((f) => ({
58195
58505
  rule_id: f.rule_id,
@@ -58236,8 +58546,8 @@ async function sastScan(input, directory, config3) {
58236
58546
  _filesSkipped++;
58237
58547
  continue;
58238
58548
  }
58239
- const resolvedPath = path41.isAbsolute(filePath) ? filePath : path41.resolve(directory, filePath);
58240
- if (!fs28.existsSync(resolvedPath)) {
58549
+ const resolvedPath = path42.isAbsolute(filePath) ? filePath : path42.resolve(directory, filePath);
58550
+ if (!fs29.existsSync(resolvedPath)) {
58241
58551
  _filesSkipped++;
58242
58552
  continue;
58243
58553
  }
@@ -58435,18 +58745,18 @@ function validatePath(inputPath, baseDir, workspaceDir) {
58435
58745
  let resolved;
58436
58746
  const isWinAbs = isWindowsAbsolutePath(inputPath);
58437
58747
  if (isWinAbs) {
58438
- resolved = path42.win32.resolve(inputPath);
58439
- } else if (path42.isAbsolute(inputPath)) {
58440
- resolved = path42.resolve(inputPath);
58748
+ resolved = path43.win32.resolve(inputPath);
58749
+ } else if (path43.isAbsolute(inputPath)) {
58750
+ resolved = path43.resolve(inputPath);
58441
58751
  } else {
58442
- resolved = path42.resolve(baseDir, inputPath);
58752
+ resolved = path43.resolve(baseDir, inputPath);
58443
58753
  }
58444
- const workspaceResolved = path42.resolve(workspaceDir);
58754
+ const workspaceResolved = path43.resolve(workspaceDir);
58445
58755
  let relative5;
58446
58756
  if (isWinAbs) {
58447
- relative5 = path42.win32.relative(workspaceResolved, resolved);
58757
+ relative5 = path43.win32.relative(workspaceResolved, resolved);
58448
58758
  } else {
58449
- relative5 = path42.relative(workspaceResolved, resolved);
58759
+ relative5 = path43.relative(workspaceResolved, resolved);
58450
58760
  }
58451
58761
  if (relative5.startsWith("..")) {
58452
58762
  return "path traversal detected";
@@ -58507,13 +58817,13 @@ async function runLintWrapped(files, directory, _config) {
58507
58817
  }
58508
58818
  async function runLintOnFiles(linter, files, workspaceDir) {
58509
58819
  const isWindows = process.platform === "win32";
58510
- const binDir = path42.join(workspaceDir, "node_modules", ".bin");
58820
+ const binDir = path43.join(workspaceDir, "node_modules", ".bin");
58511
58821
  const validatedFiles = [];
58512
58822
  for (const file3 of files) {
58513
58823
  if (typeof file3 !== "string") {
58514
58824
  continue;
58515
58825
  }
58516
- const resolvedPath = path42.resolve(file3);
58826
+ const resolvedPath = path43.resolve(file3);
58517
58827
  const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
58518
58828
  if (validationError) {
58519
58829
  continue;
@@ -58531,10 +58841,10 @@ async function runLintOnFiles(linter, files, workspaceDir) {
58531
58841
  }
58532
58842
  let command;
58533
58843
  if (linter === "biome") {
58534
- const biomeBin = isWindows ? path42.join(binDir, "biome.EXE") : path42.join(binDir, "biome");
58844
+ const biomeBin = isWindows ? path43.join(binDir, "biome.EXE") : path43.join(binDir, "biome");
58535
58845
  command = [biomeBin, "check", ...validatedFiles];
58536
58846
  } else {
58537
- const eslintBin = isWindows ? path42.join(binDir, "eslint.cmd") : path42.join(binDir, "eslint");
58847
+ const eslintBin = isWindows ? path43.join(binDir, "eslint.cmd") : path43.join(binDir, "eslint");
58538
58848
  command = [eslintBin, ...validatedFiles];
58539
58849
  }
58540
58850
  try {
@@ -58671,7 +58981,7 @@ async function runSecretscanWithFiles(files, directory) {
58671
58981
  skippedFiles++;
58672
58982
  continue;
58673
58983
  }
58674
- const resolvedPath = path42.resolve(file3);
58984
+ const resolvedPath = path43.resolve(file3);
58675
58985
  const validationError = validatePath(resolvedPath, directory, directory);
58676
58986
  if (validationError) {
58677
58987
  skippedFiles++;
@@ -58689,14 +58999,14 @@ async function runSecretscanWithFiles(files, directory) {
58689
58999
  };
58690
59000
  }
58691
59001
  for (const file3 of validatedFiles) {
58692
- const ext = path42.extname(file3).toLowerCase();
59002
+ const ext = path43.extname(file3).toLowerCase();
58693
59003
  if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
58694
59004
  skippedFiles++;
58695
59005
  continue;
58696
59006
  }
58697
59007
  let stat2;
58698
59008
  try {
58699
- stat2 = fs29.statSync(file3);
59009
+ stat2 = fs30.statSync(file3);
58700
59010
  } catch {
58701
59011
  skippedFiles++;
58702
59012
  continue;
@@ -58707,7 +59017,7 @@ async function runSecretscanWithFiles(files, directory) {
58707
59017
  }
58708
59018
  let content;
58709
59019
  try {
58710
- const buffer = fs29.readFileSync(file3);
59020
+ const buffer = fs30.readFileSync(file3);
58711
59021
  if (buffer.includes(0)) {
58712
59022
  skippedFiles++;
58713
59023
  continue;
@@ -58848,7 +59158,7 @@ async function runPreCheckBatch(input, workspaceDir) {
58848
59158
  warn(`pre_check_batch: Invalid file path: ${file3}`);
58849
59159
  continue;
58850
59160
  }
58851
- changedFiles.push(path42.resolve(directory, file3));
59161
+ changedFiles.push(path43.resolve(directory, file3));
58852
59162
  }
58853
59163
  if (changedFiles.length === 0) {
58854
59164
  warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
@@ -58999,7 +59309,7 @@ var pre_check_batch = createSwarmTool({
58999
59309
  };
59000
59310
  return JSON.stringify(errorResult, null, 2);
59001
59311
  }
59002
- const resolvedDirectory = path42.resolve(typedArgs.directory);
59312
+ const resolvedDirectory = path43.resolve(typedArgs.directory);
59003
59313
  const workspaceAnchor = resolvedDirectory;
59004
59314
  const dirError = validateDirectory3(resolvedDirectory, workspaceAnchor);
59005
59315
  if (dirError) {
@@ -59106,8 +59416,8 @@ ${paginatedContent}`;
59106
59416
  init_tool();
59107
59417
  init_manager2();
59108
59418
  init_create_tool();
59109
- import * as fs30 from "fs";
59110
- import * as path43 from "path";
59419
+ import * as fs31 from "fs";
59420
+ import * as path44 from "path";
59111
59421
  function detectPlaceholderContent(args2) {
59112
59422
  const issues = [];
59113
59423
  const placeholderPattern = /^\[\w[\w\s]*\]$/;
@@ -59211,19 +59521,19 @@ async function executeSavePlan(args2, fallbackDir) {
59211
59521
  try {
59212
59522
  await savePlan(dir, plan);
59213
59523
  try {
59214
- const markerPath = path43.join(dir, ".swarm", ".plan-write-marker");
59524
+ const markerPath = path44.join(dir, ".swarm", ".plan-write-marker");
59215
59525
  const marker = JSON.stringify({
59216
59526
  source: "save_plan",
59217
59527
  timestamp: new Date().toISOString(),
59218
59528
  phases_count: plan.phases.length,
59219
59529
  tasks_count: tasksCount
59220
59530
  });
59221
- await fs30.promises.writeFile(markerPath, marker, "utf8");
59531
+ await fs31.promises.writeFile(markerPath, marker, "utf8");
59222
59532
  } catch {}
59223
59533
  return {
59224
59534
  success: true,
59225
59535
  message: "Plan saved successfully",
59226
- plan_path: path43.join(dir, ".swarm", "plan.json"),
59536
+ plan_path: path44.join(dir, ".swarm", "plan.json"),
59227
59537
  phases_count: plan.phases.length,
59228
59538
  tasks_count: tasksCount
59229
59539
  };
@@ -59261,8 +59571,8 @@ var save_plan = createSwarmTool({
59261
59571
  // src/tools/sbom-generate.ts
59262
59572
  init_dist();
59263
59573
  init_manager();
59264
- import * as fs31 from "fs";
59265
- import * as path44 from "path";
59574
+ import * as fs32 from "fs";
59575
+ import * as path45 from "path";
59266
59576
 
59267
59577
  // src/sbom/detectors/index.ts
59268
59578
  init_utils();
@@ -60108,9 +60418,9 @@ function findManifestFiles(rootDir) {
60108
60418
  const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
60109
60419
  function searchDir(dir) {
60110
60420
  try {
60111
- const entries = fs31.readdirSync(dir, { withFileTypes: true });
60421
+ const entries = fs32.readdirSync(dir, { withFileTypes: true });
60112
60422
  for (const entry of entries) {
60113
- const fullPath = path44.join(dir, entry.name);
60423
+ const fullPath = path45.join(dir, entry.name);
60114
60424
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
60115
60425
  continue;
60116
60426
  }
@@ -60119,7 +60429,7 @@ function findManifestFiles(rootDir) {
60119
60429
  } else if (entry.isFile()) {
60120
60430
  for (const pattern of patterns) {
60121
60431
  if (simpleGlobToRegex(pattern).test(entry.name)) {
60122
- manifestFiles.push(path44.relative(rootDir, fullPath));
60432
+ manifestFiles.push(path45.relative(rootDir, fullPath));
60123
60433
  break;
60124
60434
  }
60125
60435
  }
@@ -60135,13 +60445,13 @@ function findManifestFilesInDirs(directories, workingDir) {
60135
60445
  const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
60136
60446
  for (const dir of directories) {
60137
60447
  try {
60138
- const entries = fs31.readdirSync(dir, { withFileTypes: true });
60448
+ const entries = fs32.readdirSync(dir, { withFileTypes: true });
60139
60449
  for (const entry of entries) {
60140
- const fullPath = path44.join(dir, entry.name);
60450
+ const fullPath = path45.join(dir, entry.name);
60141
60451
  if (entry.isFile()) {
60142
60452
  for (const pattern of patterns) {
60143
60453
  if (simpleGlobToRegex(pattern).test(entry.name)) {
60144
- found.push(path44.relative(workingDir, fullPath));
60454
+ found.push(path45.relative(workingDir, fullPath));
60145
60455
  break;
60146
60456
  }
60147
60457
  }
@@ -60154,11 +60464,11 @@ function findManifestFilesInDirs(directories, workingDir) {
60154
60464
  function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
60155
60465
  const dirs = new Set;
60156
60466
  for (const file3 of changedFiles) {
60157
- let currentDir = path44.dirname(file3);
60467
+ let currentDir = path45.dirname(file3);
60158
60468
  while (true) {
60159
- if (currentDir && currentDir !== "." && currentDir !== path44.sep) {
60160
- dirs.add(path44.join(workingDir, currentDir));
60161
- const parent = path44.dirname(currentDir);
60469
+ if (currentDir && currentDir !== "." && currentDir !== path45.sep) {
60470
+ dirs.add(path45.join(workingDir, currentDir));
60471
+ const parent = path45.dirname(currentDir);
60162
60472
  if (parent === currentDir)
60163
60473
  break;
60164
60474
  currentDir = parent;
@@ -60172,7 +60482,7 @@ function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
60172
60482
  }
60173
60483
  function ensureOutputDir(outputDir) {
60174
60484
  try {
60175
- fs31.mkdirSync(outputDir, { recursive: true });
60485
+ fs32.mkdirSync(outputDir, { recursive: true });
60176
60486
  } catch (error93) {
60177
60487
  if (!error93 || error93.code !== "EEXIST") {
60178
60488
  throw error93;
@@ -60242,7 +60552,7 @@ var sbom_generate = createSwarmTool({
60242
60552
  const changedFiles = obj.changed_files;
60243
60553
  const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
60244
60554
  const workingDir = directory;
60245
- const outputDir = path44.isAbsolute(relativeOutputDir) ? relativeOutputDir : path44.join(workingDir, relativeOutputDir);
60555
+ const outputDir = path45.isAbsolute(relativeOutputDir) ? relativeOutputDir : path45.join(workingDir, relativeOutputDir);
60246
60556
  let manifestFiles = [];
60247
60557
  if (scope === "all") {
60248
60558
  manifestFiles = findManifestFiles(workingDir);
@@ -60265,11 +60575,11 @@ var sbom_generate = createSwarmTool({
60265
60575
  const processedFiles = [];
60266
60576
  for (const manifestFile of manifestFiles) {
60267
60577
  try {
60268
- const fullPath = path44.isAbsolute(manifestFile) ? manifestFile : path44.join(workingDir, manifestFile);
60269
- if (!fs31.existsSync(fullPath)) {
60578
+ const fullPath = path45.isAbsolute(manifestFile) ? manifestFile : path45.join(workingDir, manifestFile);
60579
+ if (!fs32.existsSync(fullPath)) {
60270
60580
  continue;
60271
60581
  }
60272
- const content = fs31.readFileSync(fullPath, "utf-8");
60582
+ const content = fs32.readFileSync(fullPath, "utf-8");
60273
60583
  const components = detectComponents(manifestFile, content);
60274
60584
  processedFiles.push(manifestFile);
60275
60585
  if (components.length > 0) {
@@ -60282,8 +60592,8 @@ var sbom_generate = createSwarmTool({
60282
60592
  const bom = generateCycloneDX(allComponents);
60283
60593
  const bomJson = serializeCycloneDX(bom);
60284
60594
  const filename = generateSbomFilename();
60285
- const outputPath = path44.join(outputDir, filename);
60286
- fs31.writeFileSync(outputPath, bomJson, "utf-8");
60595
+ const outputPath = path45.join(outputDir, filename);
60596
+ fs32.writeFileSync(outputPath, bomJson, "utf-8");
60287
60597
  const verdict = processedFiles.length > 0 ? "pass" : "pass";
60288
60598
  try {
60289
60599
  const timestamp = new Date().toISOString();
@@ -60325,8 +60635,8 @@ var sbom_generate = createSwarmTool({
60325
60635
  // src/tools/schema-drift.ts
60326
60636
  init_dist();
60327
60637
  init_create_tool();
60328
- import * as fs32 from "fs";
60329
- import * as path45 from "path";
60638
+ import * as fs33 from "fs";
60639
+ import * as path46 from "path";
60330
60640
  var SPEC_CANDIDATES = [
60331
60641
  "openapi.json",
60332
60642
  "openapi.yaml",
@@ -60358,28 +60668,28 @@ function normalizePath2(p) {
60358
60668
  }
60359
60669
  function discoverSpecFile(cwd, specFileArg) {
60360
60670
  if (specFileArg) {
60361
- const resolvedPath = path45.resolve(cwd, specFileArg);
60362
- const normalizedCwd = cwd.endsWith(path45.sep) ? cwd : cwd + path45.sep;
60671
+ const resolvedPath = path46.resolve(cwd, specFileArg);
60672
+ const normalizedCwd = cwd.endsWith(path46.sep) ? cwd : cwd + path46.sep;
60363
60673
  if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
60364
60674
  throw new Error("Invalid spec_file: path traversal detected");
60365
60675
  }
60366
- const ext = path45.extname(resolvedPath).toLowerCase();
60676
+ const ext = path46.extname(resolvedPath).toLowerCase();
60367
60677
  if (!ALLOWED_EXTENSIONS.includes(ext)) {
60368
60678
  throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
60369
60679
  }
60370
- const stats = fs32.statSync(resolvedPath);
60680
+ const stats = fs33.statSync(resolvedPath);
60371
60681
  if (stats.size > MAX_SPEC_SIZE) {
60372
60682
  throw new Error(`Invalid spec_file: file exceeds ${MAX_SPEC_SIZE / 1024 / 1024}MB limit`);
60373
60683
  }
60374
- if (!fs32.existsSync(resolvedPath)) {
60684
+ if (!fs33.existsSync(resolvedPath)) {
60375
60685
  throw new Error(`Spec file not found: ${resolvedPath}`);
60376
60686
  }
60377
60687
  return resolvedPath;
60378
60688
  }
60379
60689
  for (const candidate of SPEC_CANDIDATES) {
60380
- const candidatePath = path45.resolve(cwd, candidate);
60381
- if (fs32.existsSync(candidatePath)) {
60382
- const stats = fs32.statSync(candidatePath);
60690
+ const candidatePath = path46.resolve(cwd, candidate);
60691
+ if (fs33.existsSync(candidatePath)) {
60692
+ const stats = fs33.statSync(candidatePath);
60383
60693
  if (stats.size <= MAX_SPEC_SIZE) {
60384
60694
  return candidatePath;
60385
60695
  }
@@ -60388,8 +60698,8 @@ function discoverSpecFile(cwd, specFileArg) {
60388
60698
  return null;
60389
60699
  }
60390
60700
  function parseSpec(specFile) {
60391
- const content = fs32.readFileSync(specFile, "utf-8");
60392
- const ext = path45.extname(specFile).toLowerCase();
60701
+ const content = fs33.readFileSync(specFile, "utf-8");
60702
+ const ext = path46.extname(specFile).toLowerCase();
60393
60703
  if (ext === ".json") {
60394
60704
  return parseJsonSpec(content);
60395
60705
  }
@@ -60460,12 +60770,12 @@ function extractRoutes(cwd) {
60460
60770
  function walkDir(dir) {
60461
60771
  let entries;
60462
60772
  try {
60463
- entries = fs32.readdirSync(dir, { withFileTypes: true });
60773
+ entries = fs33.readdirSync(dir, { withFileTypes: true });
60464
60774
  } catch {
60465
60775
  return;
60466
60776
  }
60467
60777
  for (const entry of entries) {
60468
- const fullPath = path45.join(dir, entry.name);
60778
+ const fullPath = path46.join(dir, entry.name);
60469
60779
  if (entry.isSymbolicLink()) {
60470
60780
  continue;
60471
60781
  }
@@ -60475,7 +60785,7 @@ function extractRoutes(cwd) {
60475
60785
  }
60476
60786
  walkDir(fullPath);
60477
60787
  } else if (entry.isFile()) {
60478
- const ext = path45.extname(entry.name).toLowerCase();
60788
+ const ext = path46.extname(entry.name).toLowerCase();
60479
60789
  const baseName = entry.name.toLowerCase();
60480
60790
  if (![".ts", ".js", ".mjs"].includes(ext)) {
60481
60791
  continue;
@@ -60493,7 +60803,7 @@ function extractRoutes(cwd) {
60493
60803
  }
60494
60804
  function extractRoutesFromFile(filePath) {
60495
60805
  const routes = [];
60496
- const content = fs32.readFileSync(filePath, "utf-8");
60806
+ const content = fs33.readFileSync(filePath, "utf-8");
60497
60807
  const lines = content.split(/\r?\n/);
60498
60808
  const expressRegex = /(?:app|router|server|express)\.(get|post|put|patch|delete|options|head)\s*\(\s*['"`]([^'"`]+)['"`]/g;
60499
60809
  const flaskRegex = /@(?:app|blueprint|bp)\.route\s*\(\s*['"]([^'"]+)['"]/g;
@@ -60644,8 +60954,8 @@ init_secretscan();
60644
60954
  // src/tools/symbols.ts
60645
60955
  init_tool();
60646
60956
  init_create_tool();
60647
- import * as fs33 from "fs";
60648
- import * as path46 from "path";
60957
+ import * as fs34 from "fs";
60958
+ import * as path47 from "path";
60649
60959
  var MAX_FILE_SIZE_BYTES7 = 1024 * 1024;
60650
60960
  var WINDOWS_RESERVED_NAMES = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
60651
60961
  function containsControlCharacters(str) {
@@ -60674,11 +60984,11 @@ function containsWindowsAttacks(str) {
60674
60984
  }
60675
60985
  function isPathInWorkspace(filePath, workspace) {
60676
60986
  try {
60677
- const resolvedPath = path46.resolve(workspace, filePath);
60678
- const realWorkspace = fs33.realpathSync(workspace);
60679
- const realResolvedPath = fs33.realpathSync(resolvedPath);
60680
- const relativePath = path46.relative(realWorkspace, realResolvedPath);
60681
- if (relativePath.startsWith("..") || path46.isAbsolute(relativePath)) {
60987
+ const resolvedPath = path47.resolve(workspace, filePath);
60988
+ const realWorkspace = fs34.realpathSync(workspace);
60989
+ const realResolvedPath = fs34.realpathSync(resolvedPath);
60990
+ const relativePath = path47.relative(realWorkspace, realResolvedPath);
60991
+ if (relativePath.startsWith("..") || path47.isAbsolute(relativePath)) {
60682
60992
  return false;
60683
60993
  }
60684
60994
  return true;
@@ -60690,17 +61000,17 @@ function validatePathForRead(filePath, workspace) {
60690
61000
  return isPathInWorkspace(filePath, workspace);
60691
61001
  }
60692
61002
  function extractTSSymbols(filePath, cwd) {
60693
- const fullPath = path46.join(cwd, filePath);
61003
+ const fullPath = path47.join(cwd, filePath);
60694
61004
  if (!validatePathForRead(fullPath, cwd)) {
60695
61005
  return [];
60696
61006
  }
60697
61007
  let content;
60698
61008
  try {
60699
- const stats = fs33.statSync(fullPath);
61009
+ const stats = fs34.statSync(fullPath);
60700
61010
  if (stats.size > MAX_FILE_SIZE_BYTES7) {
60701
61011
  throw new Error(`File too large: ${stats.size} bytes (max: ${MAX_FILE_SIZE_BYTES7})`);
60702
61012
  }
60703
- content = fs33.readFileSync(fullPath, "utf-8");
61013
+ content = fs34.readFileSync(fullPath, "utf-8");
60704
61014
  } catch {
60705
61015
  return [];
60706
61016
  }
@@ -60842,17 +61152,17 @@ function extractTSSymbols(filePath, cwd) {
60842
61152
  });
60843
61153
  }
60844
61154
  function extractPythonSymbols(filePath, cwd) {
60845
- const fullPath = path46.join(cwd, filePath);
61155
+ const fullPath = path47.join(cwd, filePath);
60846
61156
  if (!validatePathForRead(fullPath, cwd)) {
60847
61157
  return [];
60848
61158
  }
60849
61159
  let content;
60850
61160
  try {
60851
- const stats = fs33.statSync(fullPath);
61161
+ const stats = fs34.statSync(fullPath);
60852
61162
  if (stats.size > MAX_FILE_SIZE_BYTES7) {
60853
61163
  throw new Error(`File too large: ${stats.size} bytes (max: ${MAX_FILE_SIZE_BYTES7})`);
60854
61164
  }
60855
- content = fs33.readFileSync(fullPath, "utf-8");
61165
+ content = fs34.readFileSync(fullPath, "utf-8");
60856
61166
  } catch {
60857
61167
  return [];
60858
61168
  }
@@ -60925,7 +61235,7 @@ var symbols = createSwarmTool({
60925
61235
  }, null, 2);
60926
61236
  }
60927
61237
  const cwd = directory;
60928
- const ext = path46.extname(file3);
61238
+ const ext = path47.extname(file3);
60929
61239
  if (containsControlCharacters(file3)) {
60930
61240
  return JSON.stringify({
60931
61241
  file: file3,
@@ -60996,8 +61306,8 @@ init_test_runner();
60996
61306
  init_dist();
60997
61307
  init_utils();
60998
61308
  init_create_tool();
60999
- import * as fs34 from "fs";
61000
- import * as path47 from "path";
61309
+ import * as fs35 from "fs";
61310
+ import * as path48 from "path";
61001
61311
  var MAX_TEXT_LENGTH = 200;
61002
61312
  var MAX_FILE_SIZE_BYTES8 = 1024 * 1024;
61003
61313
  var SUPPORTED_EXTENSIONS2 = new Set([
@@ -61068,9 +61378,9 @@ function validatePathsInput(paths, cwd) {
61068
61378
  return { error: "paths contains path traversal", resolvedPath: null };
61069
61379
  }
61070
61380
  try {
61071
- const resolvedPath = path47.resolve(paths);
61072
- const normalizedCwd = path47.resolve(cwd);
61073
- const normalizedResolved = path47.resolve(resolvedPath);
61381
+ const resolvedPath = path48.resolve(paths);
61382
+ const normalizedCwd = path48.resolve(cwd);
61383
+ const normalizedResolved = path48.resolve(resolvedPath);
61074
61384
  if (!normalizedResolved.startsWith(normalizedCwd)) {
61075
61385
  return {
61076
61386
  error: "paths must be within the current working directory",
@@ -61086,13 +61396,13 @@ function validatePathsInput(paths, cwd) {
61086
61396
  }
61087
61397
  }
61088
61398
  function isSupportedExtension(filePath) {
61089
- const ext = path47.extname(filePath).toLowerCase();
61399
+ const ext = path48.extname(filePath).toLowerCase();
61090
61400
  return SUPPORTED_EXTENSIONS2.has(ext);
61091
61401
  }
61092
61402
  function findSourceFiles3(dir, files = []) {
61093
61403
  let entries;
61094
61404
  try {
61095
- entries = fs34.readdirSync(dir);
61405
+ entries = fs35.readdirSync(dir);
61096
61406
  } catch {
61097
61407
  return files;
61098
61408
  }
@@ -61101,10 +61411,10 @@ function findSourceFiles3(dir, files = []) {
61101
61411
  if (SKIP_DIRECTORIES3.has(entry)) {
61102
61412
  continue;
61103
61413
  }
61104
- const fullPath = path47.join(dir, entry);
61414
+ const fullPath = path48.join(dir, entry);
61105
61415
  let stat2;
61106
61416
  try {
61107
- stat2 = fs34.statSync(fullPath);
61417
+ stat2 = fs35.statSync(fullPath);
61108
61418
  } catch {
61109
61419
  continue;
61110
61420
  }
@@ -61197,7 +61507,7 @@ var todo_extract = createSwarmTool({
61197
61507
  return JSON.stringify(errorResult, null, 2);
61198
61508
  }
61199
61509
  const scanPath = resolvedPath;
61200
- if (!fs34.existsSync(scanPath)) {
61510
+ if (!fs35.existsSync(scanPath)) {
61201
61511
  const errorResult = {
61202
61512
  error: `path not found: ${pathsInput}`,
61203
61513
  total: 0,
@@ -61207,13 +61517,13 @@ var todo_extract = createSwarmTool({
61207
61517
  return JSON.stringify(errorResult, null, 2);
61208
61518
  }
61209
61519
  const filesToScan = [];
61210
- const stat2 = fs34.statSync(scanPath);
61520
+ const stat2 = fs35.statSync(scanPath);
61211
61521
  if (stat2.isFile()) {
61212
61522
  if (isSupportedExtension(scanPath)) {
61213
61523
  filesToScan.push(scanPath);
61214
61524
  } else {
61215
61525
  const errorResult = {
61216
- error: `unsupported file extension: ${path47.extname(scanPath)}`,
61526
+ error: `unsupported file extension: ${path48.extname(scanPath)}`,
61217
61527
  total: 0,
61218
61528
  byPriority: { high: 0, medium: 0, low: 0 },
61219
61529
  entries: []
@@ -61226,11 +61536,11 @@ var todo_extract = createSwarmTool({
61226
61536
  const allEntries = [];
61227
61537
  for (const filePath of filesToScan) {
61228
61538
  try {
61229
- const fileStat = fs34.statSync(filePath);
61539
+ const fileStat = fs35.statSync(filePath);
61230
61540
  if (fileStat.size > MAX_FILE_SIZE_BYTES8) {
61231
61541
  continue;
61232
61542
  }
61233
- const content = fs34.readFileSync(filePath, "utf-8");
61543
+ const content = fs35.readFileSync(filePath, "utf-8");
61234
61544
  const entries = parseTodoComments(content, filePath, tagsSet);
61235
61545
  allEntries.push(...entries);
61236
61546
  } catch {}
@@ -61259,8 +61569,8 @@ var todo_extract = createSwarmTool({
61259
61569
  init_tool();
61260
61570
  init_schema();
61261
61571
  init_manager2();
61262
- import * as fs35 from "fs";
61263
- import * as path48 from "path";
61572
+ import * as fs36 from "fs";
61573
+ import * as path49 from "path";
61264
61574
  init_create_tool();
61265
61575
  var VALID_STATUSES2 = [
61266
61576
  "pending",
@@ -61285,8 +61595,8 @@ function checkReviewerGate(taskId, workingDirectory) {
61285
61595
  try {
61286
61596
  const resolvedDir = workingDirectory ?? process.cwd();
61287
61597
  try {
61288
- const evidencePath = path48.join(resolvedDir, ".swarm", "evidence", `${taskId}.json`);
61289
- const raw = fs35.readFileSync(evidencePath, "utf-8");
61598
+ const evidencePath = path49.join(resolvedDir, ".swarm", "evidence", `${taskId}.json`);
61599
+ const raw = fs36.readFileSync(evidencePath, "utf-8");
61290
61600
  const evidence = JSON.parse(raw);
61291
61601
  if (evidence?.required_gates && Array.isArray(evidence.required_gates) && evidence?.gates) {
61292
61602
  const allGatesMet = evidence.required_gates.every((gate) => evidence.gates[gate] != null);
@@ -61326,8 +61636,8 @@ function checkReviewerGate(taskId, workingDirectory) {
61326
61636
  }
61327
61637
  try {
61328
61638
  const resolvedDir2 = workingDirectory ?? process.cwd();
61329
- const planPath = path48.join(resolvedDir2, ".swarm", "plan.json");
61330
- const planRaw = fs35.readFileSync(planPath, "utf-8");
61639
+ const planPath = path49.join(resolvedDir2, ".swarm", "plan.json");
61640
+ const planRaw = fs36.readFileSync(planPath, "utf-8");
61331
61641
  const plan = JSON.parse(planRaw);
61332
61642
  for (const planPhase of plan.phases ?? []) {
61333
61643
  for (const task of planPhase.tasks ?? []) {
@@ -61437,8 +61747,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
61437
61747
  };
61438
61748
  }
61439
61749
  }
61440
- normalizedDir = path48.normalize(args2.working_directory);
61441
- const pathParts = normalizedDir.split(path48.sep);
61750
+ normalizedDir = path49.normalize(args2.working_directory);
61751
+ const pathParts = normalizedDir.split(path49.sep);
61442
61752
  if (pathParts.includes("..")) {
61443
61753
  return {
61444
61754
  success: false,
@@ -61448,11 +61758,11 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
61448
61758
  ]
61449
61759
  };
61450
61760
  }
61451
- const resolvedDir = path48.resolve(normalizedDir);
61761
+ const resolvedDir = path49.resolve(normalizedDir);
61452
61762
  try {
61453
- const realPath = fs35.realpathSync(resolvedDir);
61454
- const planPath = path48.join(realPath, ".swarm", "plan.json");
61455
- if (!fs35.existsSync(planPath)) {
61763
+ const realPath = fs36.realpathSync(resolvedDir);
61764
+ const planPath = path49.join(realPath, ".swarm", "plan.json");
61765
+ if (!fs36.existsSync(planPath)) {
61456
61766
  return {
61457
61767
  success: false,
61458
61768
  message: `Invalid working_directory: plan not found in "${realPath}"`,
@@ -61609,7 +61919,7 @@ var OpenCodeSwarm = async (ctx) => {
61609
61919
  const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
61610
61920
  preflightTriggerManager = new PTM(automationConfig);
61611
61921
  const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
61612
- const swarmDir = path49.resolve(ctx.directory, ".swarm");
61922
+ const swarmDir = path50.resolve(ctx.directory, ".swarm");
61613
61923
  statusArtifact = new ASA(swarmDir);
61614
61924
  statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
61615
61925
  if (automationConfig.capabilities?.evidence_auto_summaries === true) {
@@ -61703,6 +62013,7 @@ var OpenCodeSwarm = async (ctx) => {
61703
62013
  name: "opencode-swarm",
61704
62014
  agent: agents,
61705
62015
  tool: {
62016
+ check_gate_status,
61706
62017
  checkpoint,
61707
62018
  complexity_hotspots,
61708
62019
  detect_domains,