opencode-swarm 7.27.4 → 7.28.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/cli/index.js +1 -1
- package/dist/hooks/skill-propagation-gate.d.ts +10 -0
- package/dist/hooks/skill-scoring.d.ts +23 -0
- package/dist/index.js +521 -391
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -48,7 +48,7 @@ var package_default;
|
|
|
48
48
|
var init_package = __esm(() => {
|
|
49
49
|
package_default = {
|
|
50
50
|
name: "opencode-swarm",
|
|
51
|
-
version: "7.
|
|
51
|
+
version: "7.28.1",
|
|
52
52
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
53
53
|
main: "dist/index.js",
|
|
54
54
|
types: "dist/index.d.ts",
|
|
@@ -75885,64 +75885,58 @@ SECURITY_KEYWORDS: password, secret, token, credential, auth, login, encryption,
|
|
|
75885
75885
|
|
|
75886
75886
|
## SKILLS PROPAGATION
|
|
75887
75887
|
|
|
75888
|
-
Subagents run in isolated contexts.
|
|
75888
|
+
Subagents run in isolated contexts. Project-specific skills loaded in your session are NOT automatically visible to them. Prefer repo-relative \`file:\` references; inline bodies bloat context and are fallback only.
|
|
75889
75889
|
|
|
75890
75890
|
### Step 1 — Discover available skills (once per session)
|
|
75891
75891
|
|
|
75892
75892
|
At session start, before your first delegation:
|
|
75893
|
-
1.
|
|
75894
|
-
2.
|
|
75895
|
-
3.
|
|
75893
|
+
1. Read contract files first: \`AGENTS.md\`, \`CLAUDE.md\`, \`CONTRIBUTING.md\`, \`TESTING.md\` when present. Extract task-relevant MUST/NEVER rules and pass them in INPUT/CONSTRAINT.
|
|
75894
|
+
2. Reuse \`<skill-context>\` skills when present.
|
|
75895
|
+
3. Otherwise use \`search\` with \`include\` patterns like \`.opencode/skills/*/SKILL.md,.claude/skills/*/SKILL.md\` and frontmatter queries \`^name:\` / \`^description:\`.
|
|
75896
|
+
4. Cache a short \`.swarm/context.md\` \`## Available Skills\` index. Include the repo-relative \`file:\` path and description so subagents can load on demand:
|
|
75896
75897
|
- writing-tests: Guidelines for writing tests (used: 12, compliance: 95%) → test_engineer, coder
|
|
75897
75898
|
- engineering-conventions: Engineering invariants (used: 8, compliance: 100%) → coder, reviewer, test_engineer
|
|
75898
75899
|
- [name]: [description] (used: N, compliance: N%) → [applicable agents]
|
|
75899
75900
|
|
|
75900
|
-
|
|
75901
|
+
Use \`.swarm/skill-usage.jsonl\` when present; otherwise weight skills equally.
|
|
75901
75902
|
|
|
75902
75903
|
If skill-usage.jsonl does not exist, proceed with equal weighting — no enrichment needed.
|
|
75903
75904
|
|
|
75904
|
-
4. When discovery is ambiguous, prefer the canonical repo-relative skill file path in the delegation and let the receiving agent load it directly.
|
|
75905
75905
|
|
|
75906
75906
|
### Step 2 — Route skills to agents
|
|
75907
75907
|
|
|
75908
|
-
Include a skill
|
|
75908
|
+
Include a skill when its name/description matches:
|
|
75909
75909
|
|
|
75910
75910
|
| Skill description / name contains… | Pass to agents… |
|
|
75911
|
-
|
|
75912
|
-
| "test", "testing", "test files", "writing tests" | test_engineer, coder |
|
|
75913
|
-
| "engineering", "conventions", "invariants", "rules" | coder, reviewer, test_engineer |
|
|
75914
|
-
| "code", "implementation", "coding standards" | coder, reviewer |
|
|
75915
|
-
| "review", "security audit", "security guidelines" | reviewer |
|
|
75916
|
-
| "documentation", "docs", "writing docs" | docs |
|
|
75917
|
-
| "architecture", "design patterns", "ui" | designer, sme |
|
|
75918
|
-
| domain-specific (database, cloud, mobile, etc.) | sme |
|
|
75911
|
+
Route tests to test_engineer/coder; conventions to coder/reviewer/test_engineer; implementation to coder/reviewer; review/security to reviewer; docs to docs; architecture/ui/domain topics to designer or sme.
|
|
75919
75912
|
|
|
75920
|
-
When uncertain
|
|
75913
|
+
When uncertain, pass the skill. Missing applicable skills cause convention drift.
|
|
75921
75914
|
|
|
75922
75915
|
### Step 3 — Include skill references in delegations
|
|
75923
75916
|
|
|
75924
|
-
Add
|
|
75917
|
+
Add \`SKILLS:\` to every coder, reviewer, test_engineer, sme, docs, and designer delegation:
|
|
75925
75918
|
|
|
75926
75919
|
- \`SKILLS: none\` — only when no project-specific skill applies to that delegation
|
|
75927
75920
|
- \`SKILLS: file:.claude/skills/writing-tests/SKILL.md\` — preferred for skills that exist on disk; use repo-relative \`file:\` references, comma-separated when multiple skills apply
|
|
75928
|
-
-
|
|
75921
|
+
- Descriptive multi-line catalog:
|
|
75922
|
+
SKILLS:
|
|
75923
|
+
- file:.claude/skills/writing-tests/SKILL.md - Guidelines for writing tests
|
|
75924
|
+
- file:.claude/skills/engineering-conventions/SKILL.md - Engineering invariants for safe changes
|
|
75925
|
+
- Inline fallback:
|
|
75929
75926
|
SKILLS:
|
|
75930
75927
|
--- [skill-name] ---
|
|
75931
75928
|
[full SKILL.md body content pasted here]
|
|
75932
|
-
--- [skill-name-2] ---
|
|
75933
|
-
[full SKILL.md body content pasted here]
|
|
75934
75929
|
|
|
75935
|
-
Default to repo-relative \`file:\` references
|
|
75930
|
+
Default to repo-relative \`file:\` references. Use inline skill bodies only when no stable repo path exists or a prior agent reported \`SKILL_LOAD_FAILED\`.
|
|
75936
75931
|
|
|
75937
|
-
**SKILL_LOAD_FAILED recovery:**
|
|
75932
|
+
**SKILL_LOAD_FAILED recovery:** do NOT retry with the same reference. Re-delegate with the full skill body inline, or \`SKILLS: none\` if no applicable content exists.
|
|
75938
75933
|
|
|
75939
|
-
**Mandatory for coding tasks:**
|
|
75934
|
+
**Mandatory for coding tasks:** provide \`writing-tests\` to test_engineer and \`engineering-conventions\` to coder + reviewer when present.
|
|
75940
75935
|
|
|
75941
75936
|
### Step 4 — Forward skills to reviewer
|
|
75942
75937
|
|
|
75943
|
-
When delegating to
|
|
75938
|
+
When delegating to reviewer after coder, include \`SKILLS_USED_BY_CODER: [comma-separated skill paths from coder]\` plus reviewer \`SKILLS:\` so compliance can be checked.
|
|
75944
75939
|
|
|
75945
|
-
Example: If the coder received \`SKILLS: file:.claude/skills/writing-tests/SKILL.md\`, the reviewer delegation must include \`SKILLS_USED_BY_CODER: file:.claude/skills/writing-tests/SKILL.md\` in addition to the reviewer's own \`SKILLS:\` field.
|
|
75946
75940
|
|
|
75947
75941
|
## SWARM KNOWLEDGE DIRECTIVES (v2 acknowledgment contract)
|
|
75948
75942
|
|
|
@@ -75965,28 +75959,14 @@ You may also call the \`knowledge_ack\` tool to record an outcome explicitly whe
|
|
|
75965
75959
|
|
|
75966
75960
|
## SKILL IMPROVER (low-frequency, expensive-model adviser)
|
|
75967
75961
|
|
|
75968
|
-
|
|
75969
|
-
review of accumulated knowledge / skills / spec / architect prompt. They are
|
|
75970
|
-
quota-bounded (default 10 calls/day) and disabled by default. Suggest running
|
|
75971
|
-
\`skill_improve\` only after one of:
|
|
75972
|
-
- repeated reviewer rejections in a row,
|
|
75973
|
-
- many \`KNOWLEDGE_IGNORED\` outcomes for the same cluster,
|
|
75974
|
-
- stale skills (no updates while their target area changed),
|
|
75975
|
-
- a fresh spec mismatch with shipped behaviour.
|
|
75962
|
+
Use \`skill_improver\` / \`skill_improve\` rarely for repeated review failures, ignored knowledge clusters, stale skills, or fresh spec drift. It is quota-bounded and proposal-only.
|
|
75976
75963
|
|
|
75977
75964
|
When \`skill_improver.require_user_approval\` is true (default), ASK the user
|
|
75978
75965
|
before running. Default outputs are proposals only — they never modify source.
|
|
75979
75966
|
|
|
75980
75967
|
## SPEC WRITER
|
|
75981
75968
|
|
|
75982
|
-
For substantial spec authoring
|
|
75983
|
-
\`spec_writer\` agent (independent model from architect). It writes only via
|
|
75984
|
-
the safe \`spec_write\` tool. Use it when:
|
|
75985
|
-
- the user requests a new spec or major spec revision,
|
|
75986
|
-
- requirements decomposition is non-trivial,
|
|
75987
|
-
- you would otherwise inline-author \`.swarm/spec.md\` yourself.
|
|
75988
|
-
|
|
75989
|
-
Continue handling small touch-ups (typos, cross-references) inline.
|
|
75969
|
+
For substantial spec authoring/revision, prefer \`spec_writer\`; it writes only via \`spec_write\`. Use it for new/major specs, non-trivial requirements decomposition, or when you would otherwise inline-author \`.swarm/spec.md\`. Handle small typos/cross-references inline.
|
|
75990
75970
|
|
|
75991
75971
|
### ANTI-RATIONALIZATION
|
|
75992
75972
|
- ✗ "The coder already knows these conventions" → Skills contain project-specific rules the model cannot know from training. Always pass.
|
|
@@ -75999,7 +75979,7 @@ Continue handling small touch-ups (typos, cross-references) inline.
|
|
|
75999
75979
|
## SLASH COMMANDS
|
|
76000
75980
|
{{SLASH_COMMANDS}}
|
|
76001
75981
|
Commands above are documented with args and behavioral details. Run commands via /swarm <command> [args].
|
|
76002
|
-
Outside OpenCode,
|
|
75982
|
+
Outside OpenCode, use \`bunx opencode-swarm run <command> [args]\`; never use \`bun -e\` or internal \`src/commands/\` paths. Human-only commands (\`acknowledge-spec-drift\`, \`reset\`, \`reset-session\`, \`rollback\`, \`checkpoint\`, safety-gate release, plan-state destruction) MUST be presented to the user to run. Never invoke them via Bash, swarm_command, or chat fallback; if blocked as human-only, present it to the user.
|
|
76003
75983
|
|
|
76004
75984
|
SMEs advise only. Reviewer and critic review only. None of them write code.
|
|
76005
75985
|
|
|
@@ -76007,15 +75987,15 @@ Available Tools: {{AVAILABLE_TOOLS}}
|
|
|
76007
75987
|
|
|
76008
75988
|
## DELEGATION FORMAT
|
|
76009
75989
|
|
|
76010
|
-
Delegations
|
|
75990
|
+
Delegations happen ONLY through the **Task** tool; chat text is not delivered to agents. Examples below are Task content.
|
|
76011
75991
|
|
|
76012
|
-
|
|
75992
|
+
follow the receiving agent's INPUT FORMAT exactly; do NOT invent/omit fields. Begin with agent name, \`TASK:\`, and \`SKILLS:\` when supported.
|
|
76013
75993
|
Do NOT add conversational preamble before the agent prefix. Begin directly with the agent name.
|
|
76014
75994
|
|
|
76015
75995
|
{{AGENT_PREFIX}}[agent]
|
|
76016
75996
|
TASK: [single objective]
|
|
76017
75997
|
[agent-specific fields required by that agent's INPUT FORMAT]
|
|
76018
|
-
SKILLS: [either "none", repo-relative file
|
|
75998
|
+
SKILLS: [either "none", repo-relative file references with descriptions, or inline skill bodies — see SKILLS PROPAGATION; use "none" only when no project-specific skill applies]
|
|
76019
75999
|
|
|
76020
76000
|
Examples:
|
|
76021
76001
|
|
|
@@ -76048,22 +76028,22 @@ FILE: src/auth/login.ts
|
|
|
76048
76028
|
INPUT: Validate email format, password >= 8 chars
|
|
76049
76029
|
OUTPUT: Modified file
|
|
76050
76030
|
CONSTRAINT: Do not modify other functions
|
|
76051
|
-
SKILLS: file:.claude/skills/engineering-conventions/SKILL.md
|
|
76031
|
+
SKILLS: file:.claude/skills/engineering-conventions/SKILL.md - safe code changes
|
|
76052
76032
|
|
|
76053
76033
|
{{AGENT_PREFIX}}reviewer
|
|
76054
76034
|
TASK: Review login validation
|
|
76055
76035
|
FILE: src/auth/login.ts
|
|
76056
76036
|
CHECK: [security, correctness, edge-cases]
|
|
76057
76037
|
GATES: lint=PASS, sast_scan=PASS, secretscan=PASS
|
|
76058
|
-
SKILLS_USED_BY_CODER: file:.claude/skills/engineering-conventions/SKILL.md
|
|
76038
|
+
SKILLS_USED_BY_CODER: file:.claude/skills/engineering-conventions/SKILL.md - safe code changes
|
|
76059
76039
|
OUTPUT: VERDICT + RISK + ISSUES
|
|
76060
|
-
SKILLS: file:.claude/skills/engineering-conventions/SKILL.md
|
|
76040
|
+
SKILLS: file:.claude/skills/engineering-conventions/SKILL.md - safe code changes
|
|
76061
76041
|
|
|
76062
76042
|
{{AGENT_PREFIX}}test_engineer
|
|
76063
76043
|
TASK: Generate and run login validation tests
|
|
76064
76044
|
FILE: src/auth/login.ts
|
|
76065
76045
|
OUTPUT: Test file at src/auth/login.test.ts + VERDICT: PASS/FAIL with failure details
|
|
76066
|
-
SKILLS: file:.claude/skills/writing-tests/SKILL.md
|
|
76046
|
+
SKILLS: file:.claude/skills/writing-tests/SKILL.md - tests
|
|
76067
76047
|
|
|
76068
76048
|
{{AGENT_PREFIX}}critic
|
|
76069
76049
|
TASK: Review plan for user authentication feature
|
|
@@ -76078,14 +76058,14 @@ FILE: src/auth/login.ts
|
|
|
76078
76058
|
CHECK: [security-only] — evaluate against OWASP Top 10, scan for hardcoded secrets, injection vectors, insecure crypto, missing input validation
|
|
76079
76059
|
GATES: lint=PASS, sast_scan=PASS, secretscan=PASS
|
|
76080
76060
|
OUTPUT: VERDICT + RISK + SECURITY ISSUES ONLY
|
|
76081
|
-
SKILLS: file:.claude/skills/engineering-conventions/SKILL.md
|
|
76061
|
+
SKILLS: file:.claude/skills/engineering-conventions/SKILL.md - safe code changes
|
|
76082
76062
|
|
|
76083
76063
|
{{AGENT_PREFIX}}test_engineer
|
|
76084
76064
|
TASK: Adversarial security testing
|
|
76085
76065
|
FILE: src/auth/login.ts
|
|
76086
76066
|
CONSTRAINT: ONLY attack vectors — malformed inputs, oversized payloads, injection attempts, auth bypass, boundary violations
|
|
76087
76067
|
OUTPUT: Test file + VERDICT: PASS/FAIL
|
|
76088
|
-
SKILLS: file:.claude/skills/writing-tests/SKILL.md
|
|
76068
|
+
SKILLS: file:.claude/skills/writing-tests/SKILL.md - tests
|
|
76089
76069
|
|
|
76090
76070
|
{{AGENT_PREFIX}}explorer
|
|
76091
76071
|
TASK: Integration impact analysis
|
|
@@ -77284,7 +77264,8 @@ OUTPUT: [expected deliverable]
|
|
|
77284
77264
|
CONSTRAINT: [what NOT to do]
|
|
77285
77265
|
SKILLS: [optional — either "none", repo-relative file: references (preferred), or inline skill content pasted by architect]
|
|
77286
77266
|
|
|
77287
|
-
SKILLS HANDLING: If SKILLS is present and not "none", load
|
|
77267
|
+
SKILLS HANDLING: If SKILLS is present and not "none", read the skill names/descriptions first, then load every referenced skill that applies to your TASK before writing any code. If uncertain whether a skill applies, load it.
|
|
77268
|
+
- A file entry may include a short description after the path; use the description to decide whether the full skill body is relevant.
|
|
77288
77269
|
- For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 1000\`, and \`max_lines: 1000\`.
|
|
77289
77270
|
- After running search, inspect the result: if \`total === 0\` (file does not exist or is empty) OR \`truncated\` is \`true\` (file was too large and content was cut off), stop and report \`SKILL_LOAD_FAILED: <path>\`. Do NOT continue without the complete skill.
|
|
77290
77271
|
- If the search result has \`total > 0\` and \`truncated\` is \`false\`, reconstruct the full skill content from the line-by-line matches and apply it.
|
|
@@ -78277,7 +78258,8 @@ FRAMEWORK: [React/Vue/Svelte/SwiftUI/Flutter/etc.]
|
|
|
78277
78258
|
EXISTING PATTERNS: [current design system, component library, styling approach]
|
|
78278
78259
|
SKILLS: [optional — either "none", repo-relative file: references (preferred), or inline skill content pasted by architect]
|
|
78279
78260
|
|
|
78280
|
-
SKILLS HANDLING: If SKILLS is present and not "none", load
|
|
78261
|
+
SKILLS HANDLING: If SKILLS is present and not "none", read the skill names/descriptions first, then load every referenced skill that applies before producing the design specification. If uncertain whether a skill applies, load it.
|
|
78262
|
+
- A file entry may include a short description after the path; use the description to decide whether the full skill body is relevant.
|
|
78281
78263
|
- For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 1000\`, and \`max_lines: 1000\`.
|
|
78282
78264
|
- After running search, inspect the result: if \`total === 0\` (file does not exist or is empty) OR \`truncated\` is \`true\` (file was too large and content was cut off), stop and report \`SKILL_LOAD_FAILED: <path>\`. Do NOT continue without the complete skill.
|
|
78283
78265
|
- If the search result has \`total > 0\` and \`truncated\` is \`false\`, reconstruct the full skill content from the line-by-line matches and apply it.
|
|
@@ -78461,7 +78443,8 @@ CHANGES SUMMARY: [what was added/modified/removed]
|
|
|
78461
78443
|
DOC FILES: [list of documentation files to update]
|
|
78462
78444
|
SKILLS: [optional — either "none", repo-relative file: references (preferred), or inline skill content pasted by architect]
|
|
78463
78445
|
|
|
78464
|
-
SKILLS HANDLING: If SKILLS is present and not "none", load
|
|
78446
|
+
SKILLS HANDLING: If SKILLS is present and not "none", read the skill names/descriptions first, then load every referenced skill that applies before updating docs. If uncertain whether a skill applies, load it.
|
|
78447
|
+
- A file entry may include a short description after the path; use the description to decide whether the full skill body is relevant.
|
|
78465
78448
|
- For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 1000\`, and \`max_lines: 1000\`.
|
|
78466
78449
|
- After running search, inspect the result: if \`total === 0\` (file does not exist or is empty) OR \`truncated\` is \`true\` (file was too large and content was cut off), stop and report \`SKILL_LOAD_FAILED: <path>\`. Do NOT continue without the complete skill.
|
|
78467
78450
|
- If the search result has \`total > 0\` and \`truncated\` is \`false\`, reconstruct the full skill content from the line-by-line matches and apply it.
|
|
@@ -78782,7 +78765,8 @@ GATES: [pre-completed gate results (lint, SAST, secretscan, etc.), or "none" if
|
|
|
78782
78765
|
SKILLS: [optional — either "none", repo-relative file: references (preferred), or inline skill content pasted by architect]
|
|
78783
78766
|
SKILLS_USED_BY_CODER: [list of skill paths that were passed to the coder for this task, or "none" if no skills were used]
|
|
78784
78767
|
|
|
78785
|
-
SKILLS HANDLING: If SKILLS is present and not "none", load
|
|
78768
|
+
SKILLS HANDLING: If SKILLS is present and not "none", read the skill names/descriptions first, then load every referenced skill that applies before beginning your review. If uncertain whether a skill applies, load it.
|
|
78769
|
+
- A file entry may include a short description after the path; use the description to decide whether the full skill body is relevant.
|
|
78786
78770
|
- For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 1000\`, and \`max_lines: 1000\`.
|
|
78787
78771
|
- After running search, inspect the result: if \`total === 0\` (file does not exist or is empty) OR \`truncated\` is \`true\` (file was too large and content was cut off), stop and report \`SKILL_LOAD_FAILED: <path>\`. Do NOT continue without the complete skill.
|
|
78788
78772
|
- If the search result has \`total > 0\` and \`truncated\` is \`false\`, reconstruct the full skill content from the line-by-line matches and apply it.
|
|
@@ -78964,7 +78948,8 @@ DOMAIN: [the domain - e.g., security, ios, android, rust, kubernetes]
|
|
|
78964
78948
|
INPUT: [context/requirements]
|
|
78965
78949
|
SKILLS: [optional — either "none", repo-relative file: references (preferred), or inline skill content pasted by architect]
|
|
78966
78950
|
|
|
78967
|
-
SKILLS HANDLING: If SKILLS is present and not "none", load
|
|
78951
|
+
SKILLS HANDLING: If SKILLS is present and not "none", read the skill names/descriptions first, then load every referenced skill that applies before formulating your recommendation. If uncertain whether a skill applies, load it.
|
|
78952
|
+
- A file entry may include a short description after the path; use the description to decide whether the full skill body is relevant.
|
|
78968
78953
|
- For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 1000\`, and \`max_lines: 1000\`.
|
|
78969
78954
|
- After running search, inspect the result: if \`total === 0\` (file does not exist or is empty) OR \`truncated\` is \`true\` (file was too large and content was cut off), stop and report \`SKILL_LOAD_FAILED: <path>\`. Do NOT continue without the complete skill.
|
|
78970
78955
|
- If the search result has \`total > 0\` and \`truncated\` is \`false\`, reconstruct the full skill content from the line-by-line matches and apply it.
|
|
@@ -79170,7 +79155,8 @@ FILE: [source file path]
|
|
|
79170
79155
|
OUTPUT: [test file path]
|
|
79171
79156
|
SKILLS: [optional — either "none", repo-relative file: references (preferred), or inline skill content pasted by architect]
|
|
79172
79157
|
|
|
79173
|
-
SKILLS HANDLING: If SKILLS is present and not "none", load
|
|
79158
|
+
SKILLS HANDLING: If SKILLS is present and not "none", read the skill names/descriptions first, then load every referenced skill that applies before writing any test code. If uncertain whether a skill applies, load it.
|
|
79159
|
+
- A file entry may include a short description after the path; use the description to decide whether the full skill body is relevant.
|
|
79174
79160
|
- For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 1000\`, and \`max_lines: 1000\`.
|
|
79175
79161
|
- After running search, inspect the result: if \`total === 0\` (file does not exist or is empty) OR \`truncated\` is \`true\` (file was too large and content was cut off), stop and report \`SKILL_LOAD_FAILED: <path>\`. Do NOT continue without the complete skill.
|
|
79176
79162
|
- If the search result has \`total > 0\` and \`truncated\` is \`false\`, reconstruct the full skill content from the line-by-line matches and apply it.
|
|
@@ -84730,12 +84716,12 @@ __export(exports_project_context, {
|
|
|
84730
84716
|
_internals: () => _internals57,
|
|
84731
84717
|
LANG_BACKEND_DETECTION_TIMEOUT_MS: () => LANG_BACKEND_DETECTION_TIMEOUT_MS
|
|
84732
84718
|
});
|
|
84733
|
-
import * as
|
|
84719
|
+
import * as fs113 from "node:fs";
|
|
84734
84720
|
import * as path143 from "node:path";
|
|
84735
84721
|
function detectFileExists2(directory, pattern) {
|
|
84736
84722
|
if (pattern.includes("*") || pattern.includes("?")) {
|
|
84737
84723
|
try {
|
|
84738
|
-
const files =
|
|
84724
|
+
const files = fs113.readdirSync(directory);
|
|
84739
84725
|
const regex = new RegExp(`^${pattern.replace(/\./g, "\\.").replace(/\*/g, ".*").replace(/\?/g, ".")}$`);
|
|
84740
84726
|
return files.some((f) => regex.test(f));
|
|
84741
84727
|
} catch {
|
|
@@ -84743,7 +84729,7 @@ function detectFileExists2(directory, pattern) {
|
|
|
84743
84729
|
}
|
|
84744
84730
|
}
|
|
84745
84731
|
try {
|
|
84746
|
-
|
|
84732
|
+
fs113.accessSync(path143.join(directory, pattern));
|
|
84747
84733
|
return true;
|
|
84748
84734
|
} catch {
|
|
84749
84735
|
return false;
|
|
@@ -84752,7 +84738,7 @@ function detectFileExists2(directory, pattern) {
|
|
|
84752
84738
|
function selectTestCommandFromScriptsTest(backend, directory) {
|
|
84753
84739
|
let pkgRaw;
|
|
84754
84740
|
try {
|
|
84755
|
-
pkgRaw =
|
|
84741
|
+
pkgRaw = fs113.readFileSync(path143.join(directory, "package.json"), "utf-8");
|
|
84756
84742
|
} catch {
|
|
84757
84743
|
return null;
|
|
84758
84744
|
}
|
|
@@ -95751,10 +95737,11 @@ function createSelfReviewHook(config3, injectAdvisory) {
|
|
|
95751
95737
|
// src/hooks/skill-propagation-gate.ts
|
|
95752
95738
|
init_schema();
|
|
95753
95739
|
init_logger();
|
|
95754
|
-
import * as
|
|
95740
|
+
import * as fs63 from "node:fs";
|
|
95755
95741
|
import * as path90 from "node:path";
|
|
95756
95742
|
|
|
95757
95743
|
// src/hooks/skill-scoring.ts
|
|
95744
|
+
import * as fs62 from "node:fs";
|
|
95758
95745
|
import * as path89 from "node:path";
|
|
95759
95746
|
|
|
95760
95747
|
// src/hooks/skill-usage-log.ts
|
|
@@ -95921,11 +95908,14 @@ var RECENCY_WEIGHT = 0.15;
|
|
|
95921
95908
|
var TASK_DIVERSITY_WEIGHT = 0.05;
|
|
95922
95909
|
var CONTEXT_WEIGHT = 0.2;
|
|
95923
95910
|
var RECENCY_DECAY_MS = 30 * 24 * 60 * 60 * 1000;
|
|
95911
|
+
var SKILL_FRONTMATTER_READ_BYTES = 16 * 1024;
|
|
95924
95912
|
var _internals42 = {
|
|
95925
95913
|
computeSkillRelevanceScore: null,
|
|
95926
95914
|
rankSkillsForContext: null,
|
|
95927
95915
|
getSkillStats: null,
|
|
95928
95916
|
formatSkillIndexWithContext: null,
|
|
95917
|
+
parseSkillFrontmatter: null,
|
|
95918
|
+
readSkillMetadata: null,
|
|
95929
95919
|
extractSkillName: null,
|
|
95930
95920
|
computeRecencyScore: null,
|
|
95931
95921
|
computeContextMatchScore: null
|
|
@@ -95937,6 +95927,98 @@ function extractSkillName(skillPath) {
|
|
|
95937
95927
|
const parent = path89.basename(path89.dirname(skillPath));
|
|
95938
95928
|
return parent;
|
|
95939
95929
|
}
|
|
95930
|
+
function stripQuotes(value) {
|
|
95931
|
+
const trimmed = value.trim();
|
|
95932
|
+
if (trimmed.startsWith('"') && trimmed.endsWith('"') || trimmed.startsWith("'") && trimmed.endsWith("'")) {
|
|
95933
|
+
return trimmed.slice(1, -1).trim();
|
|
95934
|
+
}
|
|
95935
|
+
return trimmed;
|
|
95936
|
+
}
|
|
95937
|
+
function normalizeDescription(description) {
|
|
95938
|
+
const singleLine = description.replace(/\s+/g, " ").trim();
|
|
95939
|
+
if (!singleLine)
|
|
95940
|
+
return "No description provided";
|
|
95941
|
+
return singleLine.length > 240 ? `${singleLine.slice(0, 237)}...` : singleLine;
|
|
95942
|
+
}
|
|
95943
|
+
function parseSkillFrontmatter(content, skillPath) {
|
|
95944
|
+
const normalizedPath = skillPath.replace(/^file:/, "").replace(/\\/g, "/");
|
|
95945
|
+
const fallbackName = extractSkillName(normalizedPath);
|
|
95946
|
+
const fallback = {
|
|
95947
|
+
path: normalizedPath,
|
|
95948
|
+
name: fallbackName,
|
|
95949
|
+
description: "No description provided"
|
|
95950
|
+
};
|
|
95951
|
+
const lines = content.split(/\r?\n/);
|
|
95952
|
+
if (lines[0]?.trim() !== "---")
|
|
95953
|
+
return fallback;
|
|
95954
|
+
const end = lines.findIndex((line, index) => index > 0 && line.trim() === "---");
|
|
95955
|
+
if (end === -1)
|
|
95956
|
+
return fallback;
|
|
95957
|
+
let name2 = fallbackName;
|
|
95958
|
+
let description = "";
|
|
95959
|
+
for (let i2 = 1;i2 < end; i2++) {
|
|
95960
|
+
const line = lines[i2] ?? "";
|
|
95961
|
+
const match = line.match(/^([A-Za-z_][A-Za-z0-9_-]*)\s*:\s*(.*)$/);
|
|
95962
|
+
if (!match)
|
|
95963
|
+
continue;
|
|
95964
|
+
const key = match[1].toLowerCase();
|
|
95965
|
+
const rawValue = match[2].trim();
|
|
95966
|
+
if (key === "name") {
|
|
95967
|
+
const parsed = stripQuotes(rawValue);
|
|
95968
|
+
if (parsed)
|
|
95969
|
+
name2 = parsed;
|
|
95970
|
+
continue;
|
|
95971
|
+
}
|
|
95972
|
+
if (key !== "description")
|
|
95973
|
+
continue;
|
|
95974
|
+
if (rawValue === ">" || rawValue === "|") {
|
|
95975
|
+
const collected = [];
|
|
95976
|
+
for (let j = i2 + 1;j < end; j++) {
|
|
95977
|
+
const next = lines[j] ?? "";
|
|
95978
|
+
if (/^[A-Za-z_][A-Za-z0-9_-]*\s*:/.test(next))
|
|
95979
|
+
break;
|
|
95980
|
+
collected.push(next.trim());
|
|
95981
|
+
i2 = j;
|
|
95982
|
+
}
|
|
95983
|
+
description = collected.join(" ");
|
|
95984
|
+
} else {
|
|
95985
|
+
description = stripQuotes(rawValue);
|
|
95986
|
+
}
|
|
95987
|
+
}
|
|
95988
|
+
return {
|
|
95989
|
+
path: normalizedPath,
|
|
95990
|
+
name: name2 || fallbackName,
|
|
95991
|
+
description: normalizeDescription(description)
|
|
95992
|
+
};
|
|
95993
|
+
}
|
|
95994
|
+
function readFilePrefix(filePath) {
|
|
95995
|
+
const fd = fs62.openSync(filePath, "r");
|
|
95996
|
+
try {
|
|
95997
|
+
const buffer = Buffer.alloc(SKILL_FRONTMATTER_READ_BYTES);
|
|
95998
|
+
const bytesRead = fs62.readSync(fd, buffer, 0, SKILL_FRONTMATTER_READ_BYTES, 0);
|
|
95999
|
+
return buffer.toString("utf-8", 0, bytesRead);
|
|
96000
|
+
} finally {
|
|
96001
|
+
fs62.closeSync(fd);
|
|
96002
|
+
}
|
|
96003
|
+
}
|
|
96004
|
+
function readSkillMetadata(skillPath, directory) {
|
|
96005
|
+
const normalizedPath = skillPath.replace(/^file:/, "").replace(/\\/g, "/");
|
|
96006
|
+
const fallback = parseSkillFrontmatter("", normalizedPath);
|
|
96007
|
+
try {
|
|
96008
|
+
if (path89.isAbsolute(normalizedPath) || normalizedPath.split("/").includes("..")) {
|
|
96009
|
+
return fallback;
|
|
96010
|
+
}
|
|
96011
|
+
const root = path89.resolve(directory);
|
|
96012
|
+
const absolutePath = path89.resolve(directory, normalizedPath);
|
|
96013
|
+
if (absolutePath !== root && !absolutePath.startsWith(root + path89.sep)) {
|
|
96014
|
+
return fallback;
|
|
96015
|
+
}
|
|
96016
|
+
const content = readFilePrefix(absolutePath);
|
|
96017
|
+
return parseSkillFrontmatter(content, normalizedPath);
|
|
96018
|
+
} catch {
|
|
96019
|
+
return fallback;
|
|
96020
|
+
}
|
|
96021
|
+
}
|
|
95940
96022
|
function computeRecencyScore(lastUsedTimestamp) {
|
|
95941
96023
|
if (!lastUsedTimestamp)
|
|
95942
96024
|
return 0;
|
|
@@ -96041,16 +96123,19 @@ function formatSkillIndexWithContext(skills, directory) {
|
|
|
96041
96123
|
const allEntries = readSkillUsageEntries(directory);
|
|
96042
96124
|
const hasHistory = allEntries.length > 0;
|
|
96043
96125
|
if (!hasHistory) {
|
|
96044
|
-
return skills.map((sp) =>
|
|
96126
|
+
return skills.map((sp) => {
|
|
96127
|
+
const meta3 = _internals42.readSkillMetadata(sp, directory);
|
|
96128
|
+
return ` - file:${meta3.path} - ${meta3.name}: ${meta3.description}`;
|
|
96129
|
+
}).join(`
|
|
96045
96130
|
`);
|
|
96046
96131
|
}
|
|
96047
96132
|
const lines = [];
|
|
96048
96133
|
for (const skillPath of skills) {
|
|
96049
96134
|
const stats = getSkillStats(skillPath, directory);
|
|
96050
|
-
const
|
|
96135
|
+
const meta3 = _internals42.readSkillMetadata(skillPath, directory);
|
|
96051
96136
|
const compliancePct = Math.round(stats.complianceRate * 100);
|
|
96052
96137
|
const topAgentNames = stats.topAgents.slice(0, 3).map((a) => a.agent).join(", ");
|
|
96053
|
-
lines.push(` ${
|
|
96138
|
+
lines.push(` - file:${meta3.path} - ${meta3.name}: ${meta3.description} (used: ${stats.totalUsage}, compliance: ${compliancePct}%)` + (stats.topAgents.length > 0 ? ` → ${topAgentNames}` : ""));
|
|
96054
96139
|
}
|
|
96055
96140
|
return lines.join(`
|
|
96056
96141
|
`);
|
|
@@ -96059,6 +96144,8 @@ _internals42.computeSkillRelevanceScore = computeSkillRelevanceScore;
|
|
|
96059
96144
|
_internals42.rankSkillsForContext = rankSkillsForContext;
|
|
96060
96145
|
_internals42.getSkillStats = getSkillStats;
|
|
96061
96146
|
_internals42.formatSkillIndexWithContext = formatSkillIndexWithContext;
|
|
96147
|
+
_internals42.parseSkillFrontmatter = parseSkillFrontmatter;
|
|
96148
|
+
_internals42.readSkillMetadata = readSkillMetadata;
|
|
96062
96149
|
_internals42.extractSkillName = extractSkillName;
|
|
96063
96150
|
_internals42.computeRecencyScore = computeRecencyScore;
|
|
96064
96151
|
_internals42.computeContextMatchScore = computeContextMatchScore;
|
|
@@ -96079,13 +96166,13 @@ var SKILL_SEARCH_ROOTS = [
|
|
|
96079
96166
|
];
|
|
96080
96167
|
var MAX_SCORING_SESSION_ENTRIES = 500;
|
|
96081
96168
|
var _internals43 = {
|
|
96082
|
-
readdirSync:
|
|
96083
|
-
existsSync:
|
|
96084
|
-
statSync:
|
|
96085
|
-
mkdirSync:
|
|
96086
|
-
appendFileSync:
|
|
96087
|
-
readFileSync:
|
|
96088
|
-
writeFileSync:
|
|
96169
|
+
readdirSync: fs63.readdirSync.bind(fs63),
|
|
96170
|
+
existsSync: fs63.existsSync.bind(fs63),
|
|
96171
|
+
statSync: fs63.statSync.bind(fs63),
|
|
96172
|
+
mkdirSync: fs63.mkdirSync.bind(fs63),
|
|
96173
|
+
appendFileSync: fs63.appendFileSync.bind(fs63),
|
|
96174
|
+
readFileSync: fs63.readFileSync.bind(fs63),
|
|
96175
|
+
writeFileSync: fs63.writeFileSync.bind(fs63),
|
|
96089
96176
|
skillPropagationGateBefore: null,
|
|
96090
96177
|
skillPropagationTransformScan: null,
|
|
96091
96178
|
SKILL_CAPABLE_AGENTS,
|
|
@@ -96096,6 +96183,7 @@ var _internals43 = {
|
|
|
96096
96183
|
appendSkillUsageEntry,
|
|
96097
96184
|
readSkillUsageEntries,
|
|
96098
96185
|
readSkillUsageEntriesTail,
|
|
96186
|
+
extractSkillsFieldFromPrompt: null,
|
|
96099
96187
|
parseSkillPaths: null,
|
|
96100
96188
|
extractTaskIdFromPrompt: null,
|
|
96101
96189
|
computeSkillRelevanceScore,
|
|
@@ -96120,7 +96208,7 @@ function discoverAvailableSkills(directory) {
|
|
|
96120
96208
|
const skillFile = path90.join(skillDir, "SKILL.md");
|
|
96121
96209
|
try {
|
|
96122
96210
|
if (_internals43.statSync(skillDir).isDirectory() && _internals43.existsSync(skillFile)) {
|
|
96123
|
-
results.push(path90.join(root, entry, "SKILL.md"));
|
|
96211
|
+
results.push(path90.join(root, entry, "SKILL.md").replace(/\\/g, "/"));
|
|
96124
96212
|
}
|
|
96125
96213
|
} catch (err2) {
|
|
96126
96214
|
warn(`[skill-propagation-gate] failed to stat skill directory ${entry}: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
@@ -96151,19 +96239,42 @@ function parseDelegationArgs(args2) {
|
|
|
96151
96239
|
}
|
|
96152
96240
|
if (!targetAgent)
|
|
96153
96241
|
return null;
|
|
96154
|
-
|
|
96155
|
-
|
|
96156
|
-
|
|
96242
|
+
const skillsField = prompt ? _internals43.extractSkillsFieldFromPrompt(prompt) : "";
|
|
96243
|
+
return { targetAgent, skillsField };
|
|
96244
|
+
}
|
|
96245
|
+
function extractSkillsFieldFromPrompt(prompt) {
|
|
96246
|
+
const lines = prompt.split(`
|
|
96157
96247
|
`);
|
|
96158
|
-
|
|
96159
|
-
|
|
96160
|
-
|
|
96161
|
-
|
|
96248
|
+
for (let i2 = 0;i2 < lines.length; i2++) {
|
|
96249
|
+
const trimmed = lines[i2].trim();
|
|
96250
|
+
if (!/^SKILLS\s*:/i.test(trimmed))
|
|
96251
|
+
continue;
|
|
96252
|
+
const firstLine2 = trimmed.replace(/^SKILLS\s*:/i, "").trim();
|
|
96253
|
+
const collected = [];
|
|
96254
|
+
if (firstLine2)
|
|
96255
|
+
collected.push(firstLine2);
|
|
96256
|
+
for (let j = i2 + 1;j < lines.length; j++) {
|
|
96257
|
+
const next = lines[j];
|
|
96258
|
+
const nextTrimmed = next.trim();
|
|
96259
|
+
if (!nextTrimmed) {
|
|
96260
|
+
if (collected.length === 0)
|
|
96261
|
+
continue;
|
|
96262
|
+
break;
|
|
96263
|
+
}
|
|
96264
|
+
if (/^[A-Z][A-Z0-9_ -]{1,40}\s*:/i.test(nextTrimmed))
|
|
96162
96265
|
break;
|
|
96266
|
+
if (/^(?:-|\*|\d+\.)\s+/.test(nextTrimmed) || /^\s+/.test(next)) {
|
|
96267
|
+
collected.push(nextTrimmed);
|
|
96268
|
+
continue;
|
|
96163
96269
|
}
|
|
96270
|
+
if (collected.length === 0)
|
|
96271
|
+
collected.push(nextTrimmed);
|
|
96272
|
+
break;
|
|
96164
96273
|
}
|
|
96274
|
+
return collected.join(`
|
|
96275
|
+
`).trim();
|
|
96165
96276
|
}
|
|
96166
|
-
return
|
|
96277
|
+
return "";
|
|
96167
96278
|
}
|
|
96168
96279
|
function writeWarnEvent2(directory, record3) {
|
|
96169
96280
|
const filePath = path90.join(directory, ".swarm", "events.jsonl");
|
|
@@ -96184,7 +96295,22 @@ function parseSkillPaths(fieldValue) {
|
|
|
96184
96295
|
const trimmed = fieldValue.trim();
|
|
96185
96296
|
if (trimmed.toLowerCase() === "none" || trimmed === "")
|
|
96186
96297
|
return [];
|
|
96187
|
-
|
|
96298
|
+
const lines = trimmed.split(/\r?\n/);
|
|
96299
|
+
const hasCatalogLines = lines.some((line) => /^(?:-|\*|\d+\.)\s+/.test(line.trim()));
|
|
96300
|
+
const parts2 = hasCatalogLines ? lines : trimmed.split(",");
|
|
96301
|
+
const paths = [];
|
|
96302
|
+
for (const rawPart of parts2) {
|
|
96303
|
+
const part = rawPart.trim().replace(/^(?:-|\*|\d+\.)\s+/, "").trim();
|
|
96304
|
+
if (!part || part.toLowerCase() === "none")
|
|
96305
|
+
continue;
|
|
96306
|
+
const fileRef = part.match(/\bfile:[^\s,;)\]]+/);
|
|
96307
|
+
if (fileRef) {
|
|
96308
|
+
paths.push(fileRef[0].replace(/\\/g, "/"));
|
|
96309
|
+
continue;
|
|
96310
|
+
}
|
|
96311
|
+
paths.push(part);
|
|
96312
|
+
}
|
|
96313
|
+
return [...new Set(paths)];
|
|
96188
96314
|
}
|
|
96189
96315
|
function extractTaskIdFromPrompt(prompt) {
|
|
96190
96316
|
if (!prompt || typeof prompt !== "string")
|
|
@@ -96473,8 +96599,10 @@ async function skillPropagationTransformScan(directory, output, sessionID) {
|
|
|
96473
96599
|
continue;
|
|
96474
96600
|
let currentTargetAgent = "";
|
|
96475
96601
|
let skillsField = "";
|
|
96476
|
-
|
|
96477
|
-
`)
|
|
96602
|
+
const textLines = text.split(`
|
|
96603
|
+
`);
|
|
96604
|
+
for (let lineIndex = 0;lineIndex < textLines.length; lineIndex++) {
|
|
96605
|
+
const line = textLines[lineIndex] ?? "";
|
|
96478
96606
|
const trimmed = line.trim();
|
|
96479
96607
|
if (trimmed.match(/TO\s+(coder|reviewer|test_engineer|sme|docs|designer)/i)) {
|
|
96480
96608
|
const agentMatch = trimmed.match(/TO\s+(coder|reviewer|test_engineer|sme|docs|designer)/i);
|
|
@@ -96482,7 +96610,8 @@ async function skillPropagationTransformScan(directory, output, sessionID) {
|
|
|
96482
96610
|
currentTargetAgent = agentMatch[1].toLowerCase();
|
|
96483
96611
|
}
|
|
96484
96612
|
if (trimmed.startsWith("SKILLS:")) {
|
|
96485
|
-
skillsField =
|
|
96613
|
+
skillsField = _internals43.extractSkillsFieldFromPrompt(textLines.slice(lineIndex).join(`
|
|
96614
|
+
`));
|
|
96486
96615
|
}
|
|
96487
96616
|
if (currentTargetAgent && skillsField && skillsField.toLowerCase() !== "none") {
|
|
96488
96617
|
const skillPaths = _internals43.parseSkillPaths(skillsField);
|
|
@@ -96518,12 +96647,13 @@ _internals43.skillPropagationTransformScan = skillPropagationTransformScan;
|
|
|
96518
96647
|
_internals43.writeWarnEvent = writeWarnEvent2;
|
|
96519
96648
|
_internals43.discoverAvailableSkills = discoverAvailableSkills;
|
|
96520
96649
|
_internals43.parseDelegationArgs = parseDelegationArgs;
|
|
96650
|
+
_internals43.extractSkillsFieldFromPrompt = extractSkillsFieldFromPrompt;
|
|
96521
96651
|
_internals43.parseSkillPaths = parseSkillPaths;
|
|
96522
96652
|
_internals43.extractTaskIdFromPrompt = extractTaskIdFromPrompt;
|
|
96523
96653
|
_internals43.formatSkillIndexWithContext = formatSkillIndexWithContext;
|
|
96524
96654
|
|
|
96525
96655
|
// src/hooks/slop-detector.ts
|
|
96526
|
-
import * as
|
|
96656
|
+
import * as fs64 from "node:fs";
|
|
96527
96657
|
import * as path91 from "node:path";
|
|
96528
96658
|
var WRITE_EDIT_TOOLS = new Set([
|
|
96529
96659
|
"write",
|
|
@@ -96569,7 +96699,7 @@ function checkBoilerplateExplosion(content, taskDescription, threshold) {
|
|
|
96569
96699
|
function walkFiles(dir, exts, deadline) {
|
|
96570
96700
|
const results = [];
|
|
96571
96701
|
try {
|
|
96572
|
-
for (const entry of
|
|
96702
|
+
for (const entry of fs64.readdirSync(dir, { withFileTypes: true })) {
|
|
96573
96703
|
if (deadline !== undefined && Date.now() > deadline)
|
|
96574
96704
|
break;
|
|
96575
96705
|
if (entry.isSymbolicLink())
|
|
@@ -96589,7 +96719,7 @@ function walkFiles(dir, exts, deadline) {
|
|
|
96589
96719
|
return results;
|
|
96590
96720
|
}
|
|
96591
96721
|
function checkDeadExports(content, projectDir, startTime) {
|
|
96592
|
-
const hasPackageJson =
|
|
96722
|
+
const hasPackageJson = fs64.existsSync(path91.join(projectDir, "package.json"));
|
|
96593
96723
|
if (!hasPackageJson)
|
|
96594
96724
|
return null;
|
|
96595
96725
|
const exportMatches = content.matchAll(/^\+(?:export)\s+(?:function|class|const|type|interface)\s+(\w{3,})/gm);
|
|
@@ -96612,7 +96742,7 @@ function checkDeadExports(content, projectDir, startTime) {
|
|
|
96612
96742
|
if (found || Date.now() - startTime > 480)
|
|
96613
96743
|
break;
|
|
96614
96744
|
try {
|
|
96615
|
-
const text =
|
|
96745
|
+
const text = fs64.readFileSync(file3, "utf-8");
|
|
96616
96746
|
if (importPattern.test(text))
|
|
96617
96747
|
found = true;
|
|
96618
96748
|
importPattern.lastIndex = 0;
|
|
@@ -96704,7 +96834,7 @@ function checkDuplicateUtility(content, projectDir, startTime, targetFile) {
|
|
|
96704
96834
|
if (Date.now() > deadline)
|
|
96705
96835
|
break;
|
|
96706
96836
|
const utilPath = path91.join(projectDir, utilDir);
|
|
96707
|
-
if (!
|
|
96837
|
+
if (!fs64.existsSync(utilPath))
|
|
96708
96838
|
continue;
|
|
96709
96839
|
const files = walkFiles(utilPath, [".ts", ".tsx", ".js", ".jsx"], deadline);
|
|
96710
96840
|
for (const file3 of files) {
|
|
@@ -96713,7 +96843,7 @@ function checkDuplicateUtility(content, projectDir, startTime, targetFile) {
|
|
|
96713
96843
|
if (targetFile && path91.resolve(file3) === path91.resolve(targetFile))
|
|
96714
96844
|
continue;
|
|
96715
96845
|
try {
|
|
96716
|
-
const text =
|
|
96846
|
+
const text = fs64.readFileSync(file3, "utf-8");
|
|
96717
96847
|
for (const name2 of newExports) {
|
|
96718
96848
|
const exportPattern = new RegExp(`\\bexport\\s+(?:function|class|const|type|interface)\\s+${name2}\\b`);
|
|
96719
96849
|
if (exportPattern.test(text)) {
|
|
@@ -96796,7 +96926,7 @@ Review before proceeding.`;
|
|
|
96796
96926
|
// src/hooks/steering-consumed.ts
|
|
96797
96927
|
init_bun_compat();
|
|
96798
96928
|
init_utils2();
|
|
96799
|
-
import * as
|
|
96929
|
+
import * as fs65 from "node:fs";
|
|
96800
96930
|
function recordSteeringConsumed(directory, directiveId) {
|
|
96801
96931
|
try {
|
|
96802
96932
|
const eventsPath = validateSwarmPath(directory, "events.jsonl");
|
|
@@ -96805,7 +96935,7 @@ function recordSteeringConsumed(directory, directiveId) {
|
|
|
96805
96935
|
directiveId,
|
|
96806
96936
|
timestamp: new Date().toISOString()
|
|
96807
96937
|
};
|
|
96808
|
-
|
|
96938
|
+
fs65.appendFileSync(eventsPath, `${JSON.stringify(event)}
|
|
96809
96939
|
`, "utf-8");
|
|
96810
96940
|
} catch {}
|
|
96811
96941
|
}
|
|
@@ -96847,12 +96977,12 @@ function createSteeringConsumedHook(directory) {
|
|
|
96847
96977
|
|
|
96848
96978
|
// src/hooks/trajectory-logger.ts
|
|
96849
96979
|
init_manager2();
|
|
96850
|
-
import * as
|
|
96980
|
+
import * as fs67 from "node:fs/promises";
|
|
96851
96981
|
import * as path93 from "node:path";
|
|
96852
96982
|
|
|
96853
96983
|
// src/prm/trajectory-store.ts
|
|
96854
96984
|
init_utils2();
|
|
96855
|
-
import * as
|
|
96985
|
+
import * as fs66 from "node:fs/promises";
|
|
96856
96986
|
import * as path92 from "node:path";
|
|
96857
96987
|
function getTrajectoryPath(sessionId, directory) {
|
|
96858
96988
|
const relativePath = path92.join("trajectories", `${sessionId}.jsonl`);
|
|
@@ -96874,10 +97004,10 @@ async function appendTrajectoryEntry(sessionId, entry, directory, maxLines = 100
|
|
|
96874
97004
|
_inMemoryTrajectoryCache.set(sessionId, cached3);
|
|
96875
97005
|
}
|
|
96876
97006
|
const trajectoryPath = getTrajectoryPath(sessionId, directory);
|
|
96877
|
-
await
|
|
97007
|
+
await fs66.mkdir(path92.dirname(trajectoryPath), { recursive: true });
|
|
96878
97008
|
const line = `${JSON.stringify(entry)}
|
|
96879
97009
|
`;
|
|
96880
|
-
await
|
|
97010
|
+
await fs66.appendFile(trajectoryPath, line, "utf-8");
|
|
96881
97011
|
} catch (err2) {
|
|
96882
97012
|
console.warn(`[trajectory-store] Failed to append trajectory entry: ${err2}`);
|
|
96883
97013
|
}
|
|
@@ -96885,7 +97015,7 @@ async function appendTrajectoryEntry(sessionId, entry, directory, maxLines = 100
|
|
|
96885
97015
|
async function readTrajectory(sessionId, directory) {
|
|
96886
97016
|
try {
|
|
96887
97017
|
const trajectoryPath = getTrajectoryPath(sessionId, directory);
|
|
96888
|
-
const content = await
|
|
97018
|
+
const content = await fs66.readFile(trajectoryPath, "utf-8");
|
|
96889
97019
|
const lines = content.split(`
|
|
96890
97020
|
`).filter((line) => line.trim().length > 0);
|
|
96891
97021
|
const entries = [];
|
|
@@ -96909,15 +97039,15 @@ async function cleanupOldTrajectoryFiles(directory, maxAgeDays = 7) {
|
|
|
96909
97039
|
for (const subdir of ["trajectories", "replays"]) {
|
|
96910
97040
|
try {
|
|
96911
97041
|
const dirPath = validateSwarmPath(directory, subdir);
|
|
96912
|
-
const entries = await
|
|
97042
|
+
const entries = await fs66.readdir(dirPath, { withFileTypes: true });
|
|
96913
97043
|
for (const entry of entries) {
|
|
96914
97044
|
if (!entry.isFile())
|
|
96915
97045
|
continue;
|
|
96916
97046
|
const filePath = path92.join(dirPath, entry.name);
|
|
96917
97047
|
try {
|
|
96918
|
-
const stat8 = await
|
|
97048
|
+
const stat8 = await fs66.stat(filePath);
|
|
96919
97049
|
if (now - stat8.mtimeMs > cutoffMs) {
|
|
96920
|
-
await
|
|
97050
|
+
await fs66.unlink(filePath);
|
|
96921
97051
|
}
|
|
96922
97052
|
} catch {}
|
|
96923
97053
|
}
|
|
@@ -96967,7 +97097,7 @@ function isSensitiveKey(key) {
|
|
|
96967
97097
|
}
|
|
96968
97098
|
async function truncateTrajectoryFile(filePath, maxLines) {
|
|
96969
97099
|
try {
|
|
96970
|
-
const content = await
|
|
97100
|
+
const content = await fs67.readFile(filePath, "utf-8");
|
|
96971
97101
|
const lines = content.split(`
|
|
96972
97102
|
`).filter((line) => line.trim().length > 0);
|
|
96973
97103
|
if (lines.length <= maxLines) {
|
|
@@ -96975,7 +97105,7 @@ async function truncateTrajectoryFile(filePath, maxLines) {
|
|
|
96975
97105
|
}
|
|
96976
97106
|
const keepCount = Math.floor(maxLines / 2);
|
|
96977
97107
|
const keptLines = lines.slice(-keepCount);
|
|
96978
|
-
await
|
|
97108
|
+
await fs67.writeFile(filePath, `${keptLines.join(`
|
|
96979
97109
|
`)}
|
|
96980
97110
|
`, "utf-8");
|
|
96981
97111
|
} catch {}
|
|
@@ -97108,10 +97238,10 @@ function createTrajectoryLoggerHook(config3, _directory) {
|
|
|
97108
97238
|
const relativePath = path93.join("evidence", sanitized, "trajectory.jsonl");
|
|
97109
97239
|
const trajectoryPath = validateSwarmPath(_directory, relativePath);
|
|
97110
97240
|
try {
|
|
97111
|
-
await
|
|
97241
|
+
await fs67.mkdir(path93.dirname(trajectoryPath), { recursive: true });
|
|
97112
97242
|
const line = `${JSON.stringify(entry)}
|
|
97113
97243
|
`;
|
|
97114
|
-
await
|
|
97244
|
+
await fs67.appendFile(trajectoryPath, line, "utf-8");
|
|
97115
97245
|
await truncateTrajectoryFile(trajectoryPath, maxLines);
|
|
97116
97246
|
} catch {}
|
|
97117
97247
|
try {
|
|
@@ -97658,7 +97788,7 @@ init_state();
|
|
|
97658
97788
|
init_telemetry();
|
|
97659
97789
|
|
|
97660
97790
|
// src/prm/replay.ts
|
|
97661
|
-
import { promises as
|
|
97791
|
+
import { promises as fs68 } from "node:fs";
|
|
97662
97792
|
import path94 from "node:path";
|
|
97663
97793
|
function isPathSafe2(targetPath, basePath) {
|
|
97664
97794
|
const resolvedTarget = path94.resolve(targetPath);
|
|
@@ -97689,7 +97819,7 @@ async function startReplayRecording(sessionID, directory) {
|
|
|
97689
97819
|
console.warn(`[replay] Invalid path detected - path traversal attempt blocked for session ${sessionID}`);
|
|
97690
97820
|
return null;
|
|
97691
97821
|
}
|
|
97692
|
-
await
|
|
97822
|
+
await fs68.mkdir(replayDir, { recursive: true });
|
|
97693
97823
|
return filepath;
|
|
97694
97824
|
} catch (err2) {
|
|
97695
97825
|
console.warn(`[replay] Failed to start recording for session ${sessionID}: ${err2}`);
|
|
@@ -97709,7 +97839,7 @@ async function recordReplayEntry(artifactPath, sessionID, entry) {
|
|
|
97709
97839
|
};
|
|
97710
97840
|
const line = `${JSON.stringify(fullEntry)}
|
|
97711
97841
|
`;
|
|
97712
|
-
await
|
|
97842
|
+
await fs68.appendFile(artifactPath, line, "utf-8");
|
|
97713
97843
|
} catch (err2) {
|
|
97714
97844
|
console.warn(`[replay] Failed to record entry: ${err2}`);
|
|
97715
97845
|
}
|
|
@@ -98064,7 +98194,7 @@ init_telemetry();
|
|
|
98064
98194
|
// src/tools/batch-symbols.ts
|
|
98065
98195
|
init_dist();
|
|
98066
98196
|
init_create_tool();
|
|
98067
|
-
import * as
|
|
98197
|
+
import * as fs69 from "node:fs";
|
|
98068
98198
|
import * as path95 from "node:path";
|
|
98069
98199
|
init_path_security();
|
|
98070
98200
|
var WINDOWS_RESERVED_NAMES2 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
@@ -98083,11 +98213,11 @@ function containsWindowsAttacks2(str) {
|
|
|
98083
98213
|
function isPathInWorkspace2(filePath, workspace) {
|
|
98084
98214
|
try {
|
|
98085
98215
|
const resolvedPath = path95.resolve(workspace, filePath);
|
|
98086
|
-
if (!
|
|
98216
|
+
if (!fs69.existsSync(resolvedPath)) {
|
|
98087
98217
|
return true;
|
|
98088
98218
|
}
|
|
98089
|
-
const realWorkspace =
|
|
98090
|
-
const realResolvedPath =
|
|
98219
|
+
const realWorkspace = fs69.realpathSync(workspace);
|
|
98220
|
+
const realResolvedPath = fs69.realpathSync(resolvedPath);
|
|
98091
98221
|
const relativePath = path95.relative(realWorkspace, realResolvedPath);
|
|
98092
98222
|
if (relativePath.startsWith("..") || path95.isAbsolute(relativePath)) {
|
|
98093
98223
|
return false;
|
|
@@ -98132,7 +98262,7 @@ function processFile2(file3, cwd, exportedOnly) {
|
|
|
98132
98262
|
};
|
|
98133
98263
|
}
|
|
98134
98264
|
const fullPath = path95.join(cwd, file3);
|
|
98135
|
-
if (!
|
|
98265
|
+
if (!fs69.existsSync(fullPath)) {
|
|
98136
98266
|
return {
|
|
98137
98267
|
file: file3,
|
|
98138
98268
|
success: false,
|
|
@@ -98163,14 +98293,14 @@ function processFile2(file3, cwd, exportedOnly) {
|
|
|
98163
98293
|
}
|
|
98164
98294
|
let isEmptyFile = false;
|
|
98165
98295
|
try {
|
|
98166
|
-
const stats =
|
|
98296
|
+
const stats = fs69.statSync(fullPath);
|
|
98167
98297
|
if (stats.size === 0) {
|
|
98168
98298
|
isEmptyFile = true;
|
|
98169
98299
|
}
|
|
98170
98300
|
} catch {}
|
|
98171
98301
|
if (syms.length === 0) {
|
|
98172
98302
|
try {
|
|
98173
|
-
const content =
|
|
98303
|
+
const content = fs69.readFileSync(fullPath, "utf-8");
|
|
98174
98304
|
if (content.trim().length === 0) {
|
|
98175
98305
|
isEmptyFile = true;
|
|
98176
98306
|
}
|
|
@@ -98422,7 +98552,7 @@ init_manager2();
|
|
|
98422
98552
|
init_task_id();
|
|
98423
98553
|
init_create_tool();
|
|
98424
98554
|
init_resolve_working_directory();
|
|
98425
|
-
import * as
|
|
98555
|
+
import * as fs70 from "node:fs";
|
|
98426
98556
|
import * as path96 from "node:path";
|
|
98427
98557
|
var EVIDENCE_DIR = ".swarm/evidence";
|
|
98428
98558
|
function isValidTaskId3(taskId) {
|
|
@@ -98435,12 +98565,12 @@ function isPathWithinSwarm(filePath, workspaceRoot) {
|
|
|
98435
98565
|
return normalizedPath.startsWith(swarmPath);
|
|
98436
98566
|
}
|
|
98437
98567
|
function readEvidenceFile(evidencePath) {
|
|
98438
|
-
if (!
|
|
98568
|
+
if (!fs70.existsSync(evidencePath)) {
|
|
98439
98569
|
return null;
|
|
98440
98570
|
}
|
|
98441
98571
|
let content;
|
|
98442
98572
|
try {
|
|
98443
|
-
content =
|
|
98573
|
+
content = fs70.readFileSync(evidencePath, "utf-8");
|
|
98444
98574
|
} catch {
|
|
98445
98575
|
return null;
|
|
98446
98576
|
}
|
|
@@ -98608,7 +98738,7 @@ init_utils2();
|
|
|
98608
98738
|
init_state();
|
|
98609
98739
|
init_create_tool();
|
|
98610
98740
|
init_resolve_working_directory();
|
|
98611
|
-
import * as
|
|
98741
|
+
import * as fs71 from "node:fs";
|
|
98612
98742
|
import * as path97 from "node:path";
|
|
98613
98743
|
function extractMatches(regex, text) {
|
|
98614
98744
|
return Array.from(text.matchAll(regex));
|
|
@@ -98703,7 +98833,7 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
98703
98833
|
let plan;
|
|
98704
98834
|
try {
|
|
98705
98835
|
const planPath = validateSwarmPath(directory, "plan.json");
|
|
98706
|
-
const planRaw =
|
|
98836
|
+
const planRaw = fs71.readFileSync(planPath, "utf-8");
|
|
98707
98837
|
plan = JSON.parse(planRaw);
|
|
98708
98838
|
} catch {
|
|
98709
98839
|
const result2 = {
|
|
@@ -98777,7 +98907,7 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
98777
98907
|
}
|
|
98778
98908
|
let fileContent;
|
|
98779
98909
|
try {
|
|
98780
|
-
fileContent =
|
|
98910
|
+
fileContent = fs71.readFileSync(resolvedPath, "utf-8");
|
|
98781
98911
|
} catch {
|
|
98782
98912
|
blockedTasks.push({
|
|
98783
98913
|
task_id: task.id,
|
|
@@ -98821,7 +98951,7 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
98821
98951
|
try {
|
|
98822
98952
|
const evidenceDir = path97.join(directory, ".swarm", "evidence", `${phase}`);
|
|
98823
98953
|
const evidencePath = path97.join(evidenceDir, "completion-verify.json");
|
|
98824
|
-
|
|
98954
|
+
fs71.mkdirSync(evidenceDir, { recursive: true });
|
|
98825
98955
|
const evidenceBundle = {
|
|
98826
98956
|
schema_version: "1.0.0",
|
|
98827
98957
|
task_id: "completion-verify",
|
|
@@ -98842,7 +98972,7 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
98842
98972
|
}
|
|
98843
98973
|
]
|
|
98844
98974
|
};
|
|
98845
|
-
|
|
98975
|
+
fs71.writeFileSync(evidencePath, JSON.stringify(evidenceBundle, null, 2), "utf-8");
|
|
98846
98976
|
} catch {}
|
|
98847
98977
|
return JSON.stringify(result, null, 2);
|
|
98848
98978
|
}
|
|
@@ -98896,11 +99026,11 @@ var completion_verify = createSwarmTool({
|
|
|
98896
99026
|
});
|
|
98897
99027
|
// src/tools/complexity-hotspots.ts
|
|
98898
99028
|
init_zod();
|
|
98899
|
-
import * as
|
|
99029
|
+
import * as fs73 from "node:fs";
|
|
98900
99030
|
import * as path99 from "node:path";
|
|
98901
99031
|
|
|
98902
99032
|
// src/quality/metrics.ts
|
|
98903
|
-
import * as
|
|
99033
|
+
import * as fs72 from "node:fs";
|
|
98904
99034
|
import * as path98 from "node:path";
|
|
98905
99035
|
var MAX_FILE_SIZE_BYTES4 = 256 * 1024;
|
|
98906
99036
|
var MIN_DUPLICATION_LINES = 10;
|
|
@@ -98939,11 +99069,11 @@ function estimateCyclomaticComplexity(content) {
|
|
|
98939
99069
|
}
|
|
98940
99070
|
function getComplexityForFile(filePath) {
|
|
98941
99071
|
try {
|
|
98942
|
-
const stat8 =
|
|
99072
|
+
const stat8 = fs72.statSync(filePath);
|
|
98943
99073
|
if (stat8.size > MAX_FILE_SIZE_BYTES4) {
|
|
98944
99074
|
return null;
|
|
98945
99075
|
}
|
|
98946
|
-
const content =
|
|
99076
|
+
const content = fs72.readFileSync(filePath, "utf-8");
|
|
98947
99077
|
return estimateCyclomaticComplexity(content);
|
|
98948
99078
|
} catch {
|
|
98949
99079
|
return null;
|
|
@@ -98954,7 +99084,7 @@ async function computeComplexityDelta(files, workingDir) {
|
|
|
98954
99084
|
const analyzedFiles = [];
|
|
98955
99085
|
for (const file3 of files) {
|
|
98956
99086
|
const fullPath = path98.isAbsolute(file3) ? file3 : path98.join(workingDir, file3);
|
|
98957
|
-
if (!
|
|
99087
|
+
if (!fs72.existsSync(fullPath)) {
|
|
98958
99088
|
continue;
|
|
98959
99089
|
}
|
|
98960
99090
|
const complexity = getComplexityForFile(fullPath);
|
|
@@ -99075,7 +99205,7 @@ function countGoExports(content) {
|
|
|
99075
99205
|
}
|
|
99076
99206
|
function getExportCountForFile(filePath) {
|
|
99077
99207
|
try {
|
|
99078
|
-
const content =
|
|
99208
|
+
const content = fs72.readFileSync(filePath, "utf-8");
|
|
99079
99209
|
const ext = path98.extname(filePath).toLowerCase();
|
|
99080
99210
|
switch (ext) {
|
|
99081
99211
|
case ".ts":
|
|
@@ -99103,7 +99233,7 @@ async function computePublicApiDelta(files, workingDir) {
|
|
|
99103
99233
|
const analyzedFiles = [];
|
|
99104
99234
|
for (const file3 of files) {
|
|
99105
99235
|
const fullPath = path98.isAbsolute(file3) ? file3 : path98.join(workingDir, file3);
|
|
99106
|
-
if (!
|
|
99236
|
+
if (!fs72.existsSync(fullPath)) {
|
|
99107
99237
|
continue;
|
|
99108
99238
|
}
|
|
99109
99239
|
const exports = getExportCountForFile(fullPath);
|
|
@@ -99137,15 +99267,15 @@ async function computeDuplicationRatio(files, workingDir) {
|
|
|
99137
99267
|
const analyzedFiles = [];
|
|
99138
99268
|
for (const file3 of files) {
|
|
99139
99269
|
const fullPath = path98.isAbsolute(file3) ? file3 : path98.join(workingDir, file3);
|
|
99140
|
-
if (!
|
|
99270
|
+
if (!fs72.existsSync(fullPath)) {
|
|
99141
99271
|
continue;
|
|
99142
99272
|
}
|
|
99143
99273
|
try {
|
|
99144
|
-
const stat8 =
|
|
99274
|
+
const stat8 = fs72.statSync(fullPath);
|
|
99145
99275
|
if (stat8.size > MAX_FILE_SIZE_BYTES4) {
|
|
99146
99276
|
continue;
|
|
99147
99277
|
}
|
|
99148
|
-
const content =
|
|
99278
|
+
const content = fs72.readFileSync(fullPath, "utf-8");
|
|
99149
99279
|
const lines = content.split(`
|
|
99150
99280
|
`).filter((line) => line.trim().length > 0);
|
|
99151
99281
|
if (lines.length < MIN_DUPLICATION_LINES) {
|
|
@@ -99321,7 +99451,7 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
99321
99451
|
let testLines = 0;
|
|
99322
99452
|
let codeLines = 0;
|
|
99323
99453
|
const srcDir = path98.join(workingDir, "src");
|
|
99324
|
-
if (
|
|
99454
|
+
if (fs72.existsSync(srcDir)) {
|
|
99325
99455
|
await scanDirectoryForLines(srcDir, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
99326
99456
|
codeLines += lines;
|
|
99327
99457
|
});
|
|
@@ -99329,14 +99459,14 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
99329
99459
|
const possibleSrcDirs = ["lib", "app", "source", "core"];
|
|
99330
99460
|
for (const dir of possibleSrcDirs) {
|
|
99331
99461
|
const dirPath = path98.join(workingDir, dir);
|
|
99332
|
-
if (
|
|
99462
|
+
if (fs72.existsSync(dirPath)) {
|
|
99333
99463
|
await scanDirectoryForLines(dirPath, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
99334
99464
|
codeLines += lines;
|
|
99335
99465
|
});
|
|
99336
99466
|
}
|
|
99337
99467
|
}
|
|
99338
99468
|
const testsDir = path98.join(workingDir, "tests");
|
|
99339
|
-
if (
|
|
99469
|
+
if (fs72.existsSync(testsDir)) {
|
|
99340
99470
|
await scanDirectoryForLines(testsDir, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
99341
99471
|
testLines += lines;
|
|
99342
99472
|
});
|
|
@@ -99344,7 +99474,7 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
99344
99474
|
const possibleTestDirs = ["test", "__tests__", "specs"];
|
|
99345
99475
|
for (const dir of possibleTestDirs) {
|
|
99346
99476
|
const dirPath = path98.join(workingDir, dir);
|
|
99347
|
-
if (
|
|
99477
|
+
if (fs72.existsSync(dirPath) && dirPath !== testsDir) {
|
|
99348
99478
|
await scanDirectoryForLines(dirPath, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
99349
99479
|
testLines += lines;
|
|
99350
99480
|
});
|
|
@@ -99356,7 +99486,7 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
99356
99486
|
}
|
|
99357
99487
|
async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTestScan, callback) {
|
|
99358
99488
|
try {
|
|
99359
|
-
const entries =
|
|
99489
|
+
const entries = fs72.readdirSync(dirPath, { withFileTypes: true });
|
|
99360
99490
|
for (const entry of entries) {
|
|
99361
99491
|
const fullPath = path98.join(dirPath, entry.name);
|
|
99362
99492
|
if (entry.isDirectory()) {
|
|
@@ -99402,7 +99532,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
99402
99532
|
continue;
|
|
99403
99533
|
}
|
|
99404
99534
|
try {
|
|
99405
|
-
const content =
|
|
99535
|
+
const content = fs72.readFileSync(fullPath, "utf-8");
|
|
99406
99536
|
const lines = countCodeLines(content);
|
|
99407
99537
|
callback(lines);
|
|
99408
99538
|
} catch {}
|
|
@@ -99602,11 +99732,11 @@ async function getGitChurn(days, directory) {
|
|
|
99602
99732
|
}
|
|
99603
99733
|
function getComplexityForFile2(filePath) {
|
|
99604
99734
|
try {
|
|
99605
|
-
const stat8 =
|
|
99735
|
+
const stat8 = fs73.statSync(filePath);
|
|
99606
99736
|
if (stat8.size > MAX_FILE_SIZE_BYTES5) {
|
|
99607
99737
|
return null;
|
|
99608
99738
|
}
|
|
99609
|
-
const content =
|
|
99739
|
+
const content = fs73.readFileSync(filePath, "utf-8");
|
|
99610
99740
|
return estimateCyclomaticComplexity(content);
|
|
99611
99741
|
} catch {
|
|
99612
99742
|
return null;
|
|
@@ -99627,7 +99757,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
99627
99757
|
let analyzedFiles = 0;
|
|
99628
99758
|
for (const [file3, churnCount] of filteredChurn) {
|
|
99629
99759
|
let fullPath = file3;
|
|
99630
|
-
if (!
|
|
99760
|
+
if (!fs73.existsSync(fullPath)) {
|
|
99631
99761
|
fullPath = path99.join(cwd, file3);
|
|
99632
99762
|
}
|
|
99633
99763
|
const complexity = getComplexityForFile2(fullPath);
|
|
@@ -100368,7 +100498,7 @@ var submit_council_verdicts = createSwarmTool({
|
|
|
100368
100498
|
// src/tools/convene-general-council.ts
|
|
100369
100499
|
init_zod();
|
|
100370
100500
|
init_loader();
|
|
100371
|
-
import * as
|
|
100501
|
+
import * as fs74 from "node:fs";
|
|
100372
100502
|
import * as path100 from "node:path";
|
|
100373
100503
|
|
|
100374
100504
|
// src/council/general-council-advisory.ts
|
|
@@ -100802,8 +100932,8 @@ var convene_general_council = createSwarmTool({
|
|
|
100802
100932
|
const evidenceFile = `${safeTimestamp}-${input.mode}.json`;
|
|
100803
100933
|
const evidencePath = path100.join(evidenceDir, evidenceFile);
|
|
100804
100934
|
try {
|
|
100805
|
-
await
|
|
100806
|
-
await
|
|
100935
|
+
await fs74.promises.mkdir(evidenceDir, { recursive: true });
|
|
100936
|
+
await fs74.promises.writeFile(evidencePath, JSON.stringify(result, null, 2));
|
|
100807
100937
|
} catch (err2) {
|
|
100808
100938
|
const message = err2 instanceof Error ? err2.message : String(err2);
|
|
100809
100939
|
console.warn(`[convene_general_council] Failed to write evidence to ${evidencePath}: ${message}`);
|
|
@@ -101044,7 +101174,7 @@ init_scope_persistence();
|
|
|
101044
101174
|
init_state();
|
|
101045
101175
|
init_task_id();
|
|
101046
101176
|
init_create_tool();
|
|
101047
|
-
import * as
|
|
101177
|
+
import * as fs75 from "node:fs";
|
|
101048
101178
|
import * as path101 from "node:path";
|
|
101049
101179
|
function validateTaskIdFormat2(taskId) {
|
|
101050
101180
|
return validateTaskIdFormat(taskId);
|
|
@@ -101132,9 +101262,9 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
101132
101262
|
}
|
|
101133
101263
|
const resolvedDir = path101.resolve(normalizedDir);
|
|
101134
101264
|
try {
|
|
101135
|
-
const realPath =
|
|
101265
|
+
const realPath = fs75.realpathSync(resolvedDir);
|
|
101136
101266
|
const planPath2 = path101.join(realPath, ".swarm", "plan.json");
|
|
101137
|
-
if (!
|
|
101267
|
+
if (!fs75.existsSync(planPath2)) {
|
|
101138
101268
|
return {
|
|
101139
101269
|
success: false,
|
|
101140
101270
|
message: `Invalid working_directory: plan not found in "${realPath}"`,
|
|
@@ -101154,8 +101284,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
101154
101284
|
}
|
|
101155
101285
|
if (normalizedDir && fallbackDir) {
|
|
101156
101286
|
try {
|
|
101157
|
-
const canonicalWorkingDir =
|
|
101158
|
-
const canonicalProjectRoot =
|
|
101287
|
+
const canonicalWorkingDir = fs75.realpathSync(path101.resolve(normalizedDir));
|
|
101288
|
+
const canonicalProjectRoot = fs75.realpathSync(path101.resolve(fallbackDir));
|
|
101159
101289
|
if (canonicalWorkingDir.startsWith(canonicalProjectRoot + path101.sep)) {
|
|
101160
101290
|
return {
|
|
101161
101291
|
success: false,
|
|
@@ -101179,7 +101309,7 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
101179
101309
|
}
|
|
101180
101310
|
const directory = normalizedDir || fallbackDir;
|
|
101181
101311
|
const planPath = path101.resolve(directory, ".swarm", "plan.json");
|
|
101182
|
-
if (!
|
|
101312
|
+
if (!fs75.existsSync(planPath)) {
|
|
101183
101313
|
return {
|
|
101184
101314
|
success: false,
|
|
101185
101315
|
message: "No plan found",
|
|
@@ -101188,7 +101318,7 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
101188
101318
|
}
|
|
101189
101319
|
let planContent;
|
|
101190
101320
|
try {
|
|
101191
|
-
planContent = JSON.parse(
|
|
101321
|
+
planContent = JSON.parse(fs75.readFileSync(planPath, "utf-8"));
|
|
101192
101322
|
} catch {
|
|
101193
101323
|
return {
|
|
101194
101324
|
success: false,
|
|
@@ -101279,7 +101409,7 @@ var declare_scope = createSwarmTool({
|
|
|
101279
101409
|
// src/tools/diff.ts
|
|
101280
101410
|
init_zod();
|
|
101281
101411
|
import * as child_process7 from "node:child_process";
|
|
101282
|
-
import * as
|
|
101412
|
+
import * as fs76 from "node:fs";
|
|
101283
101413
|
import * as path102 from "node:path";
|
|
101284
101414
|
init_create_tool();
|
|
101285
101415
|
var MAX_DIFF_LINES = 500;
|
|
@@ -101471,7 +101601,7 @@ var diff = createSwarmTool({
|
|
|
101471
101601
|
} else if (base === "unstaged") {
|
|
101472
101602
|
const oldRef = `:${file3.path}`;
|
|
101473
101603
|
oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
|
|
101474
|
-
newContent =
|
|
101604
|
+
newContent = fs76.readFileSync(path102.join(directory, file3.path), "utf-8");
|
|
101475
101605
|
} else {
|
|
101476
101606
|
const oldRef = `${base}:${file3.path}`;
|
|
101477
101607
|
oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
|
|
@@ -101545,7 +101675,7 @@ var diff = createSwarmTool({
|
|
|
101545
101675
|
// src/tools/diff-summary.ts
|
|
101546
101676
|
init_zod();
|
|
101547
101677
|
import * as child_process8 from "node:child_process";
|
|
101548
|
-
import * as
|
|
101678
|
+
import * as fs77 from "node:fs";
|
|
101549
101679
|
import * as path103 from "node:path";
|
|
101550
101680
|
init_create_tool();
|
|
101551
101681
|
init_resolve_working_directory();
|
|
@@ -101599,7 +101729,7 @@ var diff_summary = createSwarmTool({
|
|
|
101599
101729
|
}
|
|
101600
101730
|
try {
|
|
101601
101731
|
let oldContent;
|
|
101602
|
-
const newContent =
|
|
101732
|
+
const newContent = fs77.readFileSync(path103.join(workingDir, filePath), "utf-8");
|
|
101603
101733
|
if (fileExistsInHead) {
|
|
101604
101734
|
oldContent = child_process8.execFileSync("git", ["show", `HEAD:${filePath}`], {
|
|
101605
101735
|
encoding: "utf-8",
|
|
@@ -101827,7 +101957,7 @@ Use these as DOMAIN values when delegating to @sme.`;
|
|
|
101827
101957
|
init_zod();
|
|
101828
101958
|
init_create_tool();
|
|
101829
101959
|
init_path_security();
|
|
101830
|
-
import * as
|
|
101960
|
+
import * as fs78 from "node:fs";
|
|
101831
101961
|
import * as path104 from "node:path";
|
|
101832
101962
|
var MAX_FILE_SIZE_BYTES6 = 1024 * 1024;
|
|
101833
101963
|
var MAX_EVIDENCE_FILES = 1000;
|
|
@@ -101873,12 +102003,12 @@ function parseCompletedTasks(planContent) {
|
|
|
101873
102003
|
}
|
|
101874
102004
|
function readEvidenceFiles(evidenceDir, _cwd) {
|
|
101875
102005
|
const evidence = [];
|
|
101876
|
-
if (!
|
|
102006
|
+
if (!fs78.existsSync(evidenceDir) || !fs78.statSync(evidenceDir).isDirectory()) {
|
|
101877
102007
|
return evidence;
|
|
101878
102008
|
}
|
|
101879
102009
|
let files;
|
|
101880
102010
|
try {
|
|
101881
|
-
files =
|
|
102011
|
+
files = fs78.readdirSync(evidenceDir);
|
|
101882
102012
|
} catch {
|
|
101883
102013
|
return evidence;
|
|
101884
102014
|
}
|
|
@@ -101894,7 +102024,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
101894
102024
|
if (!resolvedPath.startsWith(evidenceDirResolved)) {
|
|
101895
102025
|
continue;
|
|
101896
102026
|
}
|
|
101897
|
-
const stat8 =
|
|
102027
|
+
const stat8 = fs78.lstatSync(filePath);
|
|
101898
102028
|
if (!stat8.isFile()) {
|
|
101899
102029
|
continue;
|
|
101900
102030
|
}
|
|
@@ -101903,7 +102033,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
101903
102033
|
}
|
|
101904
102034
|
let fileStat;
|
|
101905
102035
|
try {
|
|
101906
|
-
fileStat =
|
|
102036
|
+
fileStat = fs78.statSync(filePath);
|
|
101907
102037
|
if (fileStat.size > MAX_FILE_SIZE_BYTES6) {
|
|
101908
102038
|
continue;
|
|
101909
102039
|
}
|
|
@@ -101912,7 +102042,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
101912
102042
|
}
|
|
101913
102043
|
let content;
|
|
101914
102044
|
try {
|
|
101915
|
-
content =
|
|
102045
|
+
content = fs78.readFileSync(filePath, "utf-8");
|
|
101916
102046
|
} catch {
|
|
101917
102047
|
continue;
|
|
101918
102048
|
}
|
|
@@ -102022,7 +102152,7 @@ var evidence_check = createSwarmTool({
|
|
|
102022
102152
|
}
|
|
102023
102153
|
let planContent;
|
|
102024
102154
|
try {
|
|
102025
|
-
planContent =
|
|
102155
|
+
planContent = fs78.readFileSync(planPath, "utf-8");
|
|
102026
102156
|
} catch {
|
|
102027
102157
|
const result2 = {
|
|
102028
102158
|
message: "No completed tasks found in plan.",
|
|
@@ -102057,7 +102187,7 @@ var evidence_check = createSwarmTool({
|
|
|
102057
102187
|
// src/tools/file-extractor.ts
|
|
102058
102188
|
init_zod();
|
|
102059
102189
|
init_create_tool();
|
|
102060
|
-
import * as
|
|
102190
|
+
import * as fs79 from "node:fs";
|
|
102061
102191
|
import * as path105 from "node:path";
|
|
102062
102192
|
var EXT_MAP = {
|
|
102063
102193
|
python: ".py",
|
|
@@ -102120,8 +102250,8 @@ var extract_code_blocks = createSwarmTool({
|
|
|
102120
102250
|
execute: async (args2, directory) => {
|
|
102121
102251
|
const { content, output_dir, prefix } = args2;
|
|
102122
102252
|
const targetDir = output_dir || directory;
|
|
102123
|
-
if (!
|
|
102124
|
-
|
|
102253
|
+
if (!fs79.existsSync(targetDir)) {
|
|
102254
|
+
fs79.mkdirSync(targetDir, { recursive: true });
|
|
102125
102255
|
}
|
|
102126
102256
|
if (!content) {
|
|
102127
102257
|
return "Error: content is required";
|
|
@@ -102143,12 +102273,12 @@ var extract_code_blocks = createSwarmTool({
|
|
|
102143
102273
|
const base = path105.basename(filepath, path105.extname(filepath));
|
|
102144
102274
|
const ext = path105.extname(filepath);
|
|
102145
102275
|
let counter = 1;
|
|
102146
|
-
while (
|
|
102276
|
+
while (fs79.existsSync(filepath)) {
|
|
102147
102277
|
filepath = path105.join(targetDir, `${base}_${counter}${ext}`);
|
|
102148
102278
|
counter++;
|
|
102149
102279
|
}
|
|
102150
102280
|
try {
|
|
102151
|
-
|
|
102281
|
+
fs79.writeFileSync(filepath, code.trim(), "utf-8");
|
|
102152
102282
|
savedFiles.push(filepath);
|
|
102153
102283
|
} catch (error93) {
|
|
102154
102284
|
errors5.push(`Failed to save ${filename}: ${error93 instanceof Error ? error93.message : String(error93)}`);
|
|
@@ -102314,7 +102444,7 @@ init_create_tool();
|
|
|
102314
102444
|
var GITINGEST_TIMEOUT_MS = 1e4;
|
|
102315
102445
|
var GITINGEST_MAX_RESPONSE_BYTES = 5242880;
|
|
102316
102446
|
var GITINGEST_MAX_RETRIES = 2;
|
|
102317
|
-
var delay = (ms) => new Promise((
|
|
102447
|
+
var delay = (ms) => new Promise((resolve36) => setTimeout(resolve36, ms));
|
|
102318
102448
|
async function fetchGitingest(args2) {
|
|
102319
102449
|
for (let attempt = 0;attempt <= GITINGEST_MAX_RETRIES; attempt++) {
|
|
102320
102450
|
try {
|
|
@@ -102401,7 +102531,7 @@ var gitingest = createSwarmTool({
|
|
|
102401
102531
|
init_zod();
|
|
102402
102532
|
init_create_tool();
|
|
102403
102533
|
init_path_security();
|
|
102404
|
-
import * as
|
|
102534
|
+
import * as fs80 from "node:fs";
|
|
102405
102535
|
import * as path106 from "node:path";
|
|
102406
102536
|
var MAX_FILE_PATH_LENGTH2 = 500;
|
|
102407
102537
|
var MAX_SYMBOL_LENGTH = 256;
|
|
@@ -102564,7 +102694,7 @@ var SKIP_DIRECTORIES4 = new Set([
|
|
|
102564
102694
|
function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFiles: 0, fileErrors: [] }) {
|
|
102565
102695
|
let entries;
|
|
102566
102696
|
try {
|
|
102567
|
-
entries =
|
|
102697
|
+
entries = fs80.readdirSync(dir);
|
|
102568
102698
|
} catch (e) {
|
|
102569
102699
|
stats.fileErrors.push({
|
|
102570
102700
|
path: dir,
|
|
@@ -102581,7 +102711,7 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
|
|
|
102581
102711
|
const fullPath = path106.join(dir, entry);
|
|
102582
102712
|
let stat8;
|
|
102583
102713
|
try {
|
|
102584
|
-
stat8 =
|
|
102714
|
+
stat8 = fs80.statSync(fullPath);
|
|
102585
102715
|
} catch (e) {
|
|
102586
102716
|
stats.fileErrors.push({
|
|
102587
102717
|
path: fullPath,
|
|
@@ -102650,7 +102780,7 @@ var imports = createSwarmTool({
|
|
|
102650
102780
|
}
|
|
102651
102781
|
try {
|
|
102652
102782
|
const targetFile = path106.resolve(file3);
|
|
102653
|
-
if (!
|
|
102783
|
+
if (!fs80.existsSync(targetFile)) {
|
|
102654
102784
|
const errorResult = {
|
|
102655
102785
|
error: `target file not found: ${file3}`,
|
|
102656
102786
|
target: file3,
|
|
@@ -102660,7 +102790,7 @@ var imports = createSwarmTool({
|
|
|
102660
102790
|
};
|
|
102661
102791
|
return JSON.stringify(errorResult, null, 2);
|
|
102662
102792
|
}
|
|
102663
|
-
const targetStat =
|
|
102793
|
+
const targetStat = fs80.statSync(targetFile);
|
|
102664
102794
|
if (!targetStat.isFile()) {
|
|
102665
102795
|
const errorResult = {
|
|
102666
102796
|
error: "target must be a file, not a directory",
|
|
@@ -102686,12 +102816,12 @@ var imports = createSwarmTool({
|
|
|
102686
102816
|
if (consumers.length >= MAX_CONSUMERS)
|
|
102687
102817
|
break;
|
|
102688
102818
|
try {
|
|
102689
|
-
const stat8 =
|
|
102819
|
+
const stat8 = fs80.statSync(filePath);
|
|
102690
102820
|
if (stat8.size > MAX_FILE_SIZE_BYTES7) {
|
|
102691
102821
|
skippedFileCount++;
|
|
102692
102822
|
continue;
|
|
102693
102823
|
}
|
|
102694
|
-
const buffer =
|
|
102824
|
+
const buffer = fs80.readFileSync(filePath);
|
|
102695
102825
|
if (isBinaryFile2(filePath, buffer)) {
|
|
102696
102826
|
skippedFileCount++;
|
|
102697
102827
|
continue;
|
|
@@ -103273,22 +103403,22 @@ init_config();
|
|
|
103273
103403
|
init_schema();
|
|
103274
103404
|
init_qa_gate_profile();
|
|
103275
103405
|
init_manager2();
|
|
103276
|
-
import * as
|
|
103406
|
+
import * as fs85 from "node:fs";
|
|
103277
103407
|
import * as path111 from "node:path";
|
|
103278
103408
|
|
|
103279
103409
|
// src/full-auto/phase-approval.ts
|
|
103280
103410
|
init_utils2();
|
|
103281
103411
|
init_logger();
|
|
103282
103412
|
init_state2();
|
|
103283
|
-
import * as
|
|
103413
|
+
import * as fs81 from "node:fs";
|
|
103284
103414
|
import * as path107 from "node:path";
|
|
103285
103415
|
var APPROVAL_TTL_MS = 24 * 60 * 60 * 1000;
|
|
103286
103416
|
function readEvidenceDir(directory, phase) {
|
|
103287
103417
|
try {
|
|
103288
103418
|
const dirPath = validateSwarmPath(directory, path107.posix.join("evidence", String(phase)));
|
|
103289
|
-
if (!
|
|
103419
|
+
if (!fs81.existsSync(dirPath))
|
|
103290
103420
|
return [];
|
|
103291
|
-
const entries =
|
|
103421
|
+
const entries = fs81.readdirSync(dirPath);
|
|
103292
103422
|
return entries.filter((e) => e.startsWith("full-auto-") && e.endsWith(".json")).map((e) => path107.join(dirPath, e));
|
|
103293
103423
|
} catch {
|
|
103294
103424
|
return [];
|
|
@@ -103296,7 +103426,7 @@ function readEvidenceDir(directory, phase) {
|
|
|
103296
103426
|
}
|
|
103297
103427
|
function parseEvidence(filePath) {
|
|
103298
103428
|
try {
|
|
103299
|
-
const raw =
|
|
103429
|
+
const raw = fs81.readFileSync(filePath, "utf-8");
|
|
103300
103430
|
const parsed = JSON.parse(raw);
|
|
103301
103431
|
return parsed;
|
|
103302
103432
|
} catch (error93) {
|
|
@@ -103385,9 +103515,9 @@ function verifyFullAutoPhaseApproval(directory, sessionID, phase, config3) {
|
|
|
103385
103515
|
function phaseIsExplicitlyNonCode(directory, phase) {
|
|
103386
103516
|
try {
|
|
103387
103517
|
const planPath = validateSwarmPath(directory, "plan.json");
|
|
103388
|
-
if (!
|
|
103518
|
+
if (!fs81.existsSync(planPath))
|
|
103389
103519
|
return false;
|
|
103390
|
-
const raw =
|
|
103520
|
+
const raw = fs81.readFileSync(planPath, "utf-8");
|
|
103391
103521
|
const plan = JSON.parse(raw);
|
|
103392
103522
|
const phases = Array.isArray(plan.phases) ? plan.phases : [];
|
|
103393
103523
|
const entry = phases.find((p) => p.id === phase || p.phase === phase);
|
|
@@ -103428,7 +103558,7 @@ init_file_locks();
|
|
|
103428
103558
|
init_plan_schema();
|
|
103429
103559
|
init_ledger();
|
|
103430
103560
|
init_manager();
|
|
103431
|
-
import * as
|
|
103561
|
+
import * as fs82 from "node:fs";
|
|
103432
103562
|
import * as path108 from "node:path";
|
|
103433
103563
|
async function writeCheckpoint(directory) {
|
|
103434
103564
|
try {
|
|
@@ -103436,12 +103566,12 @@ async function writeCheckpoint(directory) {
|
|
|
103436
103566
|
if (!plan)
|
|
103437
103567
|
return;
|
|
103438
103568
|
const swarmDir = path108.join(directory, ".swarm");
|
|
103439
|
-
|
|
103569
|
+
fs82.mkdirSync(swarmDir, { recursive: true });
|
|
103440
103570
|
const jsonPath = path108.join(swarmDir, "SWARM_PLAN.json");
|
|
103441
103571
|
const mdPath = path108.join(swarmDir, "SWARM_PLAN.md");
|
|
103442
|
-
|
|
103572
|
+
fs82.writeFileSync(jsonPath, JSON.stringify(plan, null, 2), "utf8");
|
|
103443
103573
|
const md = derivePlanMarkdown(plan);
|
|
103444
|
-
|
|
103574
|
+
fs82.writeFileSync(mdPath, md, "utf8");
|
|
103445
103575
|
} catch (error93) {
|
|
103446
103576
|
console.warn(`[checkpoint] Failed to write SWARM_PLAN checkpoint: ${error93 instanceof Error ? error93.message : String(error93)}`);
|
|
103447
103577
|
}
|
|
@@ -103456,13 +103586,13 @@ init_telemetry();
|
|
|
103456
103586
|
|
|
103457
103587
|
// src/turbo/lean/phase-ready.ts
|
|
103458
103588
|
init_file_locks();
|
|
103459
|
-
import * as
|
|
103589
|
+
import * as fs84 from "node:fs";
|
|
103460
103590
|
import * as path110 from "node:path";
|
|
103461
103591
|
|
|
103462
103592
|
// src/turbo/lean/evidence.ts
|
|
103463
103593
|
init_bun_compat();
|
|
103464
103594
|
import { rmSync as rmSync6 } from "node:fs";
|
|
103465
|
-
import * as
|
|
103595
|
+
import * as fs83 from "node:fs/promises";
|
|
103466
103596
|
import * as path109 from "node:path";
|
|
103467
103597
|
function leanTurboEvidenceDir(directory, phase) {
|
|
103468
103598
|
return path109.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
|
|
@@ -103497,11 +103627,11 @@ function laneEvidencePath(directory, phase, laneId) {
|
|
|
103497
103627
|
async function atomicWriteJson(filePath, data) {
|
|
103498
103628
|
const content = JSON.stringify(data, null, 2);
|
|
103499
103629
|
const dir = path109.dirname(filePath);
|
|
103500
|
-
await
|
|
103630
|
+
await fs83.mkdir(dir, { recursive: true });
|
|
103501
103631
|
const tempPath = `${filePath}.tmp.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
103502
103632
|
try {
|
|
103503
103633
|
await bunWrite(tempPath, content);
|
|
103504
|
-
await
|
|
103634
|
+
await fs83.rename(tempPath, filePath);
|
|
103505
103635
|
} catch (error93) {
|
|
103506
103636
|
try {
|
|
103507
103637
|
rmSync6(tempPath, { force: true });
|
|
@@ -103520,7 +103650,7 @@ async function readPhaseEvidence(directory, phase) {
|
|
|
103520
103650
|
const targetPath = phaseEvidencePath(directory, phase);
|
|
103521
103651
|
let content;
|
|
103522
103652
|
try {
|
|
103523
|
-
content = await
|
|
103653
|
+
content = await fs83.readFile(targetPath, "utf-8");
|
|
103524
103654
|
} catch (error93) {
|
|
103525
103655
|
const code = error93.code;
|
|
103526
103656
|
if (code === "ENOENT" || code === "ENOTDIR") {
|
|
@@ -103538,7 +103668,7 @@ async function listLaneEvidence(directory, phase) {
|
|
|
103538
103668
|
const evidenceDir = leanTurboEvidenceDir(directory, phase);
|
|
103539
103669
|
let entries;
|
|
103540
103670
|
try {
|
|
103541
|
-
entries = await
|
|
103671
|
+
entries = await fs83.readdir(evidenceDir);
|
|
103542
103672
|
} catch (error93) {
|
|
103543
103673
|
const code = error93.code;
|
|
103544
103674
|
if (code === "ENOENT" || code === "ENOTDIR") {
|
|
@@ -103557,7 +103687,7 @@ async function listLaneEvidence(directory, phase) {
|
|
|
103557
103687
|
const filePath = path109.join(evidenceDir, entry);
|
|
103558
103688
|
let content;
|
|
103559
103689
|
try {
|
|
103560
|
-
content = await
|
|
103690
|
+
content = await fs83.readFile(filePath, "utf-8");
|
|
103561
103691
|
} catch {
|
|
103562
103692
|
continue;
|
|
103563
103693
|
}
|
|
@@ -103579,9 +103709,9 @@ var DEFAULT_CONFIG2 = {
|
|
|
103579
103709
|
function defaultReadPlanJson(dir) {
|
|
103580
103710
|
try {
|
|
103581
103711
|
const planPath = path110.join(dir, ".swarm", "plan.json");
|
|
103582
|
-
if (!
|
|
103712
|
+
if (!fs84.existsSync(planPath))
|
|
103583
103713
|
return null;
|
|
103584
|
-
const raw =
|
|
103714
|
+
const raw = fs84.readFileSync(planPath, "utf-8");
|
|
103585
103715
|
const plan = JSON.parse(raw);
|
|
103586
103716
|
if (typeof plan !== "object" || plan === null || !Array.isArray(plan.phases)) {
|
|
103587
103717
|
return null;
|
|
@@ -103594,10 +103724,10 @@ function defaultReadPlanJson(dir) {
|
|
|
103594
103724
|
function readReviewerEvidenceFromFile(directory, phase) {
|
|
103595
103725
|
try {
|
|
103596
103726
|
const evidencePath = path110.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-reviewer.json");
|
|
103597
|
-
if (!
|
|
103727
|
+
if (!fs84.existsSync(evidencePath)) {
|
|
103598
103728
|
return null;
|
|
103599
103729
|
}
|
|
103600
|
-
const raw =
|
|
103730
|
+
const raw = fs84.readFileSync(evidencePath, "utf-8");
|
|
103601
103731
|
const parsed = JSON.parse(raw);
|
|
103602
103732
|
if (typeof parsed !== "object" || parsed === null || typeof parsed.verdict !== "string") {
|
|
103603
103733
|
return null;
|
|
@@ -103614,10 +103744,10 @@ function readReviewerEvidenceFromFile(directory, phase) {
|
|
|
103614
103744
|
function readCriticEvidenceFromFile(directory, phase) {
|
|
103615
103745
|
try {
|
|
103616
103746
|
const evidencePath = path110.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-critic.json");
|
|
103617
|
-
if (!
|
|
103747
|
+
if (!fs84.existsSync(evidencePath)) {
|
|
103618
103748
|
return null;
|
|
103619
103749
|
}
|
|
103620
|
-
const raw =
|
|
103750
|
+
const raw = fs84.readFileSync(evidencePath, "utf-8");
|
|
103621
103751
|
const parsed = JSON.parse(raw);
|
|
103622
103752
|
if (typeof parsed !== "object" || parsed === null || typeof parsed.verdict !== "string") {
|
|
103623
103753
|
return null;
|
|
@@ -103635,7 +103765,7 @@ function listLaneEvidenceSync(directory, phase) {
|
|
|
103635
103765
|
const evidenceDir = path110.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
|
|
103636
103766
|
let entries;
|
|
103637
103767
|
try {
|
|
103638
|
-
entries =
|
|
103768
|
+
entries = fs84.readdirSync(evidenceDir);
|
|
103639
103769
|
} catch {
|
|
103640
103770
|
return [];
|
|
103641
103771
|
}
|
|
@@ -103703,7 +103833,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
103703
103833
|
...actualConfig
|
|
103704
103834
|
};
|
|
103705
103835
|
const statePath = path110.join(directory, ".swarm", "turbo-state.json");
|
|
103706
|
-
if (!
|
|
103836
|
+
if (!fs84.existsSync(statePath)) {
|
|
103707
103837
|
return {
|
|
103708
103838
|
ok: false,
|
|
103709
103839
|
reason: "Lean Turbo state unreadable or missing"
|
|
@@ -103893,7 +104023,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
103893
104023
|
const evidencePath = path110.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-phase.json");
|
|
103894
104024
|
let hasDiff = false;
|
|
103895
104025
|
try {
|
|
103896
|
-
const content =
|
|
104026
|
+
const content = fs84.readFileSync(evidencePath, "utf-8");
|
|
103897
104027
|
const evidence = JSON.parse(content);
|
|
103898
104028
|
hasDiff = !!evidence.integratedDiffSummary;
|
|
103899
104029
|
} catch {}
|
|
@@ -104186,7 +104316,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
104186
104316
|
let driftHasSpecMd = false;
|
|
104187
104317
|
try {
|
|
104188
104318
|
const specMdPath = path111.join(dir, ".swarm", "spec.md");
|
|
104189
|
-
driftHasSpecMd =
|
|
104319
|
+
driftHasSpecMd = fs85.existsSync(specMdPath);
|
|
104190
104320
|
const gatePlan = await loadPlan(dir);
|
|
104191
104321
|
if (gatePlan) {
|
|
104192
104322
|
const gatePlanId = derivePlanId(gatePlan);
|
|
@@ -104207,8 +104337,8 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
104207
104337
|
let phaseType;
|
|
104208
104338
|
try {
|
|
104209
104339
|
const planPath = path111.join(dir, ".swarm", "plan.json");
|
|
104210
|
-
if (
|
|
104211
|
-
const planRaw =
|
|
104340
|
+
if (fs85.existsSync(planPath)) {
|
|
104341
|
+
const planRaw = fs85.readFileSync(planPath, "utf-8");
|
|
104212
104342
|
const plan = JSON.parse(planRaw);
|
|
104213
104343
|
const targetPhase = plan.phases?.find((p) => p.id === phase);
|
|
104214
104344
|
phaseType = targetPhase?.type;
|
|
@@ -104222,7 +104352,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
104222
104352
|
let driftVerdictFound = false;
|
|
104223
104353
|
let driftVerdictApproved = false;
|
|
104224
104354
|
try {
|
|
104225
|
-
const driftEvidenceContent =
|
|
104355
|
+
const driftEvidenceContent = fs85.readFileSync(driftEvidencePath, "utf-8");
|
|
104226
104356
|
const driftEvidence = JSON.parse(driftEvidenceContent);
|
|
104227
104357
|
const entries = driftEvidence.entries ?? [];
|
|
104228
104358
|
for (const entry of entries) {
|
|
@@ -104257,8 +104387,8 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
104257
104387
|
let planParseable = false;
|
|
104258
104388
|
try {
|
|
104259
104389
|
const planPath = path111.join(dir, ".swarm", "plan.json");
|
|
104260
|
-
if (
|
|
104261
|
-
const planRaw =
|
|
104390
|
+
if (fs85.existsSync(planPath)) {
|
|
104391
|
+
const planRaw = fs85.readFileSync(planPath, "utf-8");
|
|
104262
104392
|
const plan = JSON.parse(planRaw);
|
|
104263
104393
|
planParseable = true;
|
|
104264
104394
|
const planPhase = plan.phases?.find((p) => p.id === phase);
|
|
@@ -104327,7 +104457,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
104327
104457
|
let hgVerdictFound = false;
|
|
104328
104458
|
let hgVerdictApproved = false;
|
|
104329
104459
|
try {
|
|
104330
|
-
const hgContent =
|
|
104460
|
+
const hgContent = fs85.readFileSync(hgPath, "utf-8");
|
|
104331
104461
|
const hgBundle = JSON.parse(hgContent);
|
|
104332
104462
|
for (const entry of hgBundle.entries ?? []) {
|
|
104333
104463
|
if (typeof entry.type === "string" && entry.type.includes("hallucination") && typeof entry.verdict === "string") {
|
|
@@ -104399,7 +104529,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
104399
104529
|
let mgVerdictFound = false;
|
|
104400
104530
|
let mgVerdict;
|
|
104401
104531
|
try {
|
|
104402
|
-
const mgContent =
|
|
104532
|
+
const mgContent = fs85.readFileSync(mgPath, "utf-8");
|
|
104403
104533
|
const mgBundle = JSON.parse(mgContent);
|
|
104404
104534
|
for (const entry of mgBundle.entries ?? []) {
|
|
104405
104535
|
if (typeof entry.type === "string" && entry.type === "mutation-gate" && typeof entry.verdict === "string") {
|
|
@@ -104476,7 +104606,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
104476
104606
|
let pcTimestamp;
|
|
104477
104607
|
let pcPhaseNumber;
|
|
104478
104608
|
try {
|
|
104479
|
-
const pcContent =
|
|
104609
|
+
const pcContent = fs85.readFileSync(pcPath, "utf-8");
|
|
104480
104610
|
const pcBundle = JSON.parse(pcContent);
|
|
104481
104611
|
for (const entry of pcBundle.entries ?? []) {
|
|
104482
104612
|
if (typeof entry.type === "string" && entry.type === "phase-council" && typeof entry.verdict === "string") {
|
|
@@ -104681,7 +104811,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
104681
104811
|
let fcVerdictFound = false;
|
|
104682
104812
|
let _fcVerdict;
|
|
104683
104813
|
try {
|
|
104684
|
-
const fcContent =
|
|
104814
|
+
const fcContent = fs85.readFileSync(fcPath, "utf-8");
|
|
104685
104815
|
const fcBundle = JSON.parse(fcContent);
|
|
104686
104816
|
for (const entry of fcBundle.entries ?? []) {
|
|
104687
104817
|
if (typeof entry.type === "string" && entry.type === "final-council" && typeof entry.verdict === "string") {
|
|
@@ -104945,7 +105075,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
104945
105075
|
let phaseRequiredAgents;
|
|
104946
105076
|
try {
|
|
104947
105077
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
104948
|
-
const planRaw =
|
|
105078
|
+
const planRaw = fs85.readFileSync(planPath, "utf-8");
|
|
104949
105079
|
const plan = JSON.parse(planRaw);
|
|
104950
105080
|
const phaseObj = plan.phases.find((p) => p.id === phase);
|
|
104951
105081
|
phaseRequiredAgents = phaseObj?.required_agents;
|
|
@@ -104960,7 +105090,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
104960
105090
|
if (agentsMissing.length > 0) {
|
|
104961
105091
|
try {
|
|
104962
105092
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
104963
|
-
const planRaw =
|
|
105093
|
+
const planRaw = fs85.readFileSync(planPath, "utf-8");
|
|
104964
105094
|
const plan = JSON.parse(planRaw);
|
|
104965
105095
|
const targetPhase = plan.phases.find((p) => p.id === phase);
|
|
104966
105096
|
if (targetPhase && targetPhase.tasks.length > 0 && canInferMissingAgentsFromTaskGates(agentsMissing) && await allCompletedTasksHavePassedGateEvidence(dir, targetPhase.tasks)) {
|
|
@@ -105000,7 +105130,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
105000
105130
|
if (phaseCompleteConfig.regression_sweep?.enforce) {
|
|
105001
105131
|
try {
|
|
105002
105132
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
105003
|
-
const planRaw =
|
|
105133
|
+
const planRaw = fs85.readFileSync(planPath, "utf-8");
|
|
105004
105134
|
const plan = JSON.parse(planRaw);
|
|
105005
105135
|
const targetPhase = plan.phases.find((p) => p.id === phase);
|
|
105006
105136
|
if (targetPhase) {
|
|
@@ -105054,7 +105184,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
105054
105184
|
}
|
|
105055
105185
|
try {
|
|
105056
105186
|
const eventsPath = validateSwarmPath(dir, "events.jsonl");
|
|
105057
|
-
|
|
105187
|
+
fs85.appendFileSync(eventsPath, `${JSON.stringify(event)}
|
|
105058
105188
|
`, "utf-8");
|
|
105059
105189
|
} catch (writeError) {
|
|
105060
105190
|
warnings.push(`Warning: failed to write phase complete event: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
|
|
@@ -105129,12 +105259,12 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
105129
105259
|
warnings.push(`Warning: failed to update plan.json phase status`);
|
|
105130
105260
|
try {
|
|
105131
105261
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
105132
|
-
const planRaw =
|
|
105262
|
+
const planRaw = fs85.readFileSync(planPath, "utf-8");
|
|
105133
105263
|
const plan2 = JSON.parse(planRaw);
|
|
105134
105264
|
const phaseObj = plan2.phases.find((p) => p.id === phase);
|
|
105135
105265
|
if (phaseObj) {
|
|
105136
105266
|
phaseObj.status = "complete";
|
|
105137
|
-
|
|
105267
|
+
fs85.writeFileSync(planPath, JSON.stringify(plan2, null, 2), "utf-8");
|
|
105138
105268
|
}
|
|
105139
105269
|
} catch {}
|
|
105140
105270
|
} else if (plan) {
|
|
@@ -105171,12 +105301,12 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
105171
105301
|
warnings.push(`Warning: failed to update plan.json phase status`);
|
|
105172
105302
|
try {
|
|
105173
105303
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
105174
|
-
const planRaw =
|
|
105304
|
+
const planRaw = fs85.readFileSync(planPath, "utf-8");
|
|
105175
105305
|
const plan = JSON.parse(planRaw);
|
|
105176
105306
|
const phaseObj = plan.phases.find((p) => p.id === phase);
|
|
105177
105307
|
if (phaseObj) {
|
|
105178
105308
|
phaseObj.status = "complete";
|
|
105179
|
-
|
|
105309
|
+
fs85.writeFileSync(planPath, JSON.stringify(plan, null, 2), "utf-8");
|
|
105180
105310
|
}
|
|
105181
105311
|
} catch {}
|
|
105182
105312
|
}
|
|
@@ -105234,7 +105364,7 @@ init_discovery();
|
|
|
105234
105364
|
init_utils();
|
|
105235
105365
|
init_bun_compat();
|
|
105236
105366
|
init_create_tool();
|
|
105237
|
-
import * as
|
|
105367
|
+
import * as fs86 from "node:fs";
|
|
105238
105368
|
import * as path112 from "node:path";
|
|
105239
105369
|
var MAX_OUTPUT_BYTES5 = 52428800;
|
|
105240
105370
|
var AUDIT_TIMEOUT_MS = 120000;
|
|
@@ -105263,31 +105393,31 @@ function validateArgs3(args2) {
|
|
|
105263
105393
|
function detectEcosystems(directory) {
|
|
105264
105394
|
const ecosystems = [];
|
|
105265
105395
|
const cwd = directory;
|
|
105266
|
-
if (
|
|
105396
|
+
if (fs86.existsSync(path112.join(cwd, "package.json"))) {
|
|
105267
105397
|
ecosystems.push("npm");
|
|
105268
105398
|
}
|
|
105269
|
-
if (
|
|
105399
|
+
if (fs86.existsSync(path112.join(cwd, "pyproject.toml")) || fs86.existsSync(path112.join(cwd, "requirements.txt"))) {
|
|
105270
105400
|
ecosystems.push("pip");
|
|
105271
105401
|
}
|
|
105272
|
-
if (
|
|
105402
|
+
if (fs86.existsSync(path112.join(cwd, "Cargo.toml"))) {
|
|
105273
105403
|
ecosystems.push("cargo");
|
|
105274
105404
|
}
|
|
105275
|
-
if (
|
|
105405
|
+
if (fs86.existsSync(path112.join(cwd, "go.mod"))) {
|
|
105276
105406
|
ecosystems.push("go");
|
|
105277
105407
|
}
|
|
105278
105408
|
try {
|
|
105279
|
-
const files =
|
|
105409
|
+
const files = fs86.readdirSync(cwd);
|
|
105280
105410
|
if (files.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"))) {
|
|
105281
105411
|
ecosystems.push("dotnet");
|
|
105282
105412
|
}
|
|
105283
105413
|
} catch {}
|
|
105284
|
-
if (
|
|
105414
|
+
if (fs86.existsSync(path112.join(cwd, "Gemfile")) || fs86.existsSync(path112.join(cwd, "Gemfile.lock"))) {
|
|
105285
105415
|
ecosystems.push("ruby");
|
|
105286
105416
|
}
|
|
105287
|
-
if (
|
|
105417
|
+
if (fs86.existsSync(path112.join(cwd, "pubspec.yaml"))) {
|
|
105288
105418
|
ecosystems.push("dart");
|
|
105289
105419
|
}
|
|
105290
|
-
if (
|
|
105420
|
+
if (fs86.existsSync(path112.join(cwd, "composer.lock"))) {
|
|
105291
105421
|
ecosystems.push("composer");
|
|
105292
105422
|
}
|
|
105293
105423
|
return ecosystems;
|
|
@@ -105300,7 +105430,7 @@ async function runNpmAudit(directory) {
|
|
|
105300
105430
|
stderr: "pipe",
|
|
105301
105431
|
cwd: directory
|
|
105302
105432
|
});
|
|
105303
|
-
const timeoutPromise = new Promise((
|
|
105433
|
+
const timeoutPromise = new Promise((resolve38) => setTimeout(() => resolve38("timeout"), AUDIT_TIMEOUT_MS));
|
|
105304
105434
|
const result = await Promise.race([
|
|
105305
105435
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr2]) => ({ stdout: stdout2, stderr: stderr2 })),
|
|
105306
105436
|
timeoutPromise
|
|
@@ -105420,7 +105550,7 @@ async function runPipAudit(directory) {
|
|
|
105420
105550
|
stderr: "pipe",
|
|
105421
105551
|
cwd: directory
|
|
105422
105552
|
});
|
|
105423
|
-
const timeoutPromise = new Promise((
|
|
105553
|
+
const timeoutPromise = new Promise((resolve38) => setTimeout(() => resolve38("timeout"), AUDIT_TIMEOUT_MS));
|
|
105424
105554
|
const result = await Promise.race([
|
|
105425
105555
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr2]) => ({ stdout: stdout2, stderr: stderr2 })),
|
|
105426
105556
|
timeoutPromise
|
|
@@ -105548,7 +105678,7 @@ async function runCargoAudit(directory) {
|
|
|
105548
105678
|
stderr: "pipe",
|
|
105549
105679
|
cwd: directory
|
|
105550
105680
|
});
|
|
105551
|
-
const timeoutPromise = new Promise((
|
|
105681
|
+
const timeoutPromise = new Promise((resolve38) => setTimeout(() => resolve38("timeout"), AUDIT_TIMEOUT_MS));
|
|
105552
105682
|
const result = await Promise.race([
|
|
105553
105683
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
105554
105684
|
timeoutPromise
|
|
@@ -105672,7 +105802,7 @@ async function runGoAudit(directory) {
|
|
|
105672
105802
|
stderr: "pipe",
|
|
105673
105803
|
cwd: directory
|
|
105674
105804
|
});
|
|
105675
|
-
const timeoutPromise = new Promise((
|
|
105805
|
+
const timeoutPromise = new Promise((resolve38) => setTimeout(() => resolve38("timeout"), AUDIT_TIMEOUT_MS));
|
|
105676
105806
|
const result = await Promise.race([
|
|
105677
105807
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
105678
105808
|
timeoutPromise
|
|
@@ -105805,7 +105935,7 @@ async function runDotnetAudit(directory) {
|
|
|
105805
105935
|
stderr: "pipe",
|
|
105806
105936
|
cwd: directory
|
|
105807
105937
|
});
|
|
105808
|
-
const timeoutPromise = new Promise((
|
|
105938
|
+
const timeoutPromise = new Promise((resolve38) => setTimeout(() => resolve38("timeout"), AUDIT_TIMEOUT_MS));
|
|
105809
105939
|
const result = await Promise.race([
|
|
105810
105940
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
105811
105941
|
timeoutPromise
|
|
@@ -105921,7 +106051,7 @@ async function runBundleAudit(directory) {
|
|
|
105921
106051
|
stderr: "pipe",
|
|
105922
106052
|
cwd: directory
|
|
105923
106053
|
});
|
|
105924
|
-
const timeoutPromise = new Promise((
|
|
106054
|
+
const timeoutPromise = new Promise((resolve38) => setTimeout(() => resolve38("timeout"), AUDIT_TIMEOUT_MS));
|
|
105925
106055
|
const result = await Promise.race([
|
|
105926
106056
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
105927
106057
|
timeoutPromise
|
|
@@ -106066,7 +106196,7 @@ async function runDartAudit(directory) {
|
|
|
106066
106196
|
stderr: "pipe",
|
|
106067
106197
|
cwd: directory
|
|
106068
106198
|
});
|
|
106069
|
-
const timeoutPromise = new Promise((
|
|
106199
|
+
const timeoutPromise = new Promise((resolve38) => setTimeout(() => resolve38("timeout"), AUDIT_TIMEOUT_MS));
|
|
106070
106200
|
const result = await Promise.race([
|
|
106071
106201
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
106072
106202
|
timeoutPromise
|
|
@@ -106181,7 +106311,7 @@ async function runComposerAudit(directory) {
|
|
|
106181
106311
|
stderr: "pipe",
|
|
106182
106312
|
cwd: directory
|
|
106183
106313
|
});
|
|
106184
|
-
const timeoutPromise = new Promise((
|
|
106314
|
+
const timeoutPromise = new Promise((resolve38) => setTimeout(() => resolve38("timeout"), AUDIT_TIMEOUT_MS));
|
|
106185
106315
|
const result = await Promise.race([
|
|
106186
106316
|
Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
|
|
106187
106317
|
timeoutPromise
|
|
@@ -106422,7 +106552,7 @@ var pkg_audit = createSwarmTool({
|
|
|
106422
106552
|
// src/tools/placeholder-scan.ts
|
|
106423
106553
|
init_zod();
|
|
106424
106554
|
init_manager2();
|
|
106425
|
-
import * as
|
|
106555
|
+
import * as fs87 from "node:fs";
|
|
106426
106556
|
import * as path113 from "node:path";
|
|
106427
106557
|
init_utils();
|
|
106428
106558
|
init_create_tool();
|
|
@@ -106824,7 +106954,7 @@ async function placeholderScan(input, directory) {
|
|
|
106824
106954
|
if (!fullPath.startsWith(resolvedDirectory + path113.sep) && fullPath !== resolvedDirectory) {
|
|
106825
106955
|
continue;
|
|
106826
106956
|
}
|
|
106827
|
-
if (!
|
|
106957
|
+
if (!fs87.existsSync(fullPath)) {
|
|
106828
106958
|
continue;
|
|
106829
106959
|
}
|
|
106830
106960
|
if (isAllowedByGlobs(filePath, allow_globs)) {
|
|
@@ -106836,11 +106966,11 @@ async function placeholderScan(input, directory) {
|
|
|
106836
106966
|
}
|
|
106837
106967
|
let content;
|
|
106838
106968
|
try {
|
|
106839
|
-
const stat8 =
|
|
106969
|
+
const stat8 = fs87.statSync(fullPath);
|
|
106840
106970
|
if (stat8.size > MAX_FILE_SIZE) {
|
|
106841
106971
|
continue;
|
|
106842
106972
|
}
|
|
106843
|
-
content =
|
|
106973
|
+
content = fs87.readFileSync(fullPath, "utf-8");
|
|
106844
106974
|
} catch {
|
|
106845
106975
|
continue;
|
|
106846
106976
|
}
|
|
@@ -106901,7 +107031,7 @@ var placeholder_scan = createSwarmTool({
|
|
|
106901
107031
|
}
|
|
106902
107032
|
});
|
|
106903
107033
|
// src/tools/pre-check-batch.ts
|
|
106904
|
-
import * as
|
|
107034
|
+
import * as fs91 from "node:fs";
|
|
106905
107035
|
import * as path117 from "node:path";
|
|
106906
107036
|
init_zod();
|
|
106907
107037
|
init_manager2();
|
|
@@ -107042,7 +107172,7 @@ var _internals45 = {
|
|
|
107042
107172
|
init_zod();
|
|
107043
107173
|
init_manager2();
|
|
107044
107174
|
init_detector();
|
|
107045
|
-
import * as
|
|
107175
|
+
import * as fs90 from "node:fs";
|
|
107046
107176
|
import * as path116 from "node:path";
|
|
107047
107177
|
import { extname as extname20 } from "node:path";
|
|
107048
107178
|
|
|
@@ -107758,7 +107888,7 @@ function executeRulesSync(filePath, content, language) {
|
|
|
107758
107888
|
|
|
107759
107889
|
// src/sast/semgrep.ts
|
|
107760
107890
|
import * as child_process9 from "node:child_process";
|
|
107761
|
-
import * as
|
|
107891
|
+
import * as fs88 from "node:fs";
|
|
107762
107892
|
import * as path114 from "node:path";
|
|
107763
107893
|
var semgrepAvailableCache = null;
|
|
107764
107894
|
var DEFAULT_RULES_DIR = ".swarm/semgrep-rules";
|
|
@@ -107840,7 +107970,7 @@ function mapSemgrepSeverity(severity) {
|
|
|
107840
107970
|
}
|
|
107841
107971
|
}
|
|
107842
107972
|
async function executeWithTimeout(command, args2, options) {
|
|
107843
|
-
return new Promise((
|
|
107973
|
+
return new Promise((resolve40) => {
|
|
107844
107974
|
const child = child_process9.spawn(command, args2, {
|
|
107845
107975
|
shell: false,
|
|
107846
107976
|
cwd: options.cwd
|
|
@@ -107849,7 +107979,7 @@ async function executeWithTimeout(command, args2, options) {
|
|
|
107849
107979
|
let stderr = "";
|
|
107850
107980
|
const timeout = setTimeout(() => {
|
|
107851
107981
|
child.kill("SIGTERM");
|
|
107852
|
-
|
|
107982
|
+
resolve40({
|
|
107853
107983
|
stdout,
|
|
107854
107984
|
stderr: "Process timed out",
|
|
107855
107985
|
exitCode: 124
|
|
@@ -107863,7 +107993,7 @@ async function executeWithTimeout(command, args2, options) {
|
|
|
107863
107993
|
});
|
|
107864
107994
|
child.on("close", (code) => {
|
|
107865
107995
|
clearTimeout(timeout);
|
|
107866
|
-
|
|
107996
|
+
resolve40({
|
|
107867
107997
|
stdout,
|
|
107868
107998
|
stderr,
|
|
107869
107999
|
exitCode: code ?? 0
|
|
@@ -107871,7 +108001,7 @@ async function executeWithTimeout(command, args2, options) {
|
|
|
107871
108001
|
});
|
|
107872
108002
|
child.on("error", (err2) => {
|
|
107873
108003
|
clearTimeout(timeout);
|
|
107874
|
-
|
|
108004
|
+
resolve40({
|
|
107875
108005
|
stdout,
|
|
107876
108006
|
stderr: err2.message,
|
|
107877
108007
|
exitCode: 1
|
|
@@ -107953,7 +108083,7 @@ function getRulesDirectory(projectRoot) {
|
|
|
107953
108083
|
function hasBundledRules(projectRoot) {
|
|
107954
108084
|
const rulesDir = getRulesDirectory(projectRoot);
|
|
107955
108085
|
try {
|
|
107956
|
-
return
|
|
108086
|
+
return fs88.existsSync(rulesDir);
|
|
107957
108087
|
} catch {
|
|
107958
108088
|
return false;
|
|
107959
108089
|
}
|
|
@@ -107966,7 +108096,7 @@ init_create_tool();
|
|
|
107966
108096
|
// src/tools/sast-baseline.ts
|
|
107967
108097
|
init_utils2();
|
|
107968
108098
|
import * as crypto10 from "node:crypto";
|
|
107969
|
-
import * as
|
|
108099
|
+
import * as fs89 from "node:fs";
|
|
107970
108100
|
import * as path115 from "node:path";
|
|
107971
108101
|
var BASELINE_SCHEMA_VERSION = "1.0.0";
|
|
107972
108102
|
var MAX_BASELINE_FINDINGS = 2000;
|
|
@@ -108001,7 +108131,7 @@ function fingerprintFinding(finding, directory, occurrenceIndex) {
|
|
|
108001
108131
|
}
|
|
108002
108132
|
const lineNum = finding.location.line;
|
|
108003
108133
|
try {
|
|
108004
|
-
const content =
|
|
108134
|
+
const content = fs89.readFileSync(finding.location.file, "utf-8");
|
|
108005
108135
|
const lines = content.split(`
|
|
108006
108136
|
`);
|
|
108007
108137
|
const idx = lineNum - 1;
|
|
@@ -108032,7 +108162,7 @@ function assignOccurrenceIndices(findings, directory) {
|
|
|
108032
108162
|
try {
|
|
108033
108163
|
if (relFile.startsWith(".."))
|
|
108034
108164
|
throw new Error("escapes workspace");
|
|
108035
|
-
const content =
|
|
108165
|
+
const content = fs89.readFileSync(finding.location.file, "utf-8");
|
|
108036
108166
|
const lines = content.split(`
|
|
108037
108167
|
`);
|
|
108038
108168
|
const idx = lineNum - 1;
|
|
@@ -108061,16 +108191,16 @@ function assignOccurrenceIndices(findings, directory) {
|
|
|
108061
108191
|
async function acquireLock2(lockPath) {
|
|
108062
108192
|
for (let attempt = 0;attempt <= LOCK_RETRY_DELAYS_MS.length; attempt++) {
|
|
108063
108193
|
try {
|
|
108064
|
-
const fd =
|
|
108065
|
-
|
|
108194
|
+
const fd = fs89.openSync(lockPath, "wx");
|
|
108195
|
+
fs89.closeSync(fd);
|
|
108066
108196
|
return () => {
|
|
108067
108197
|
try {
|
|
108068
|
-
|
|
108198
|
+
fs89.unlinkSync(lockPath);
|
|
108069
108199
|
} catch {}
|
|
108070
108200
|
};
|
|
108071
108201
|
} catch {
|
|
108072
108202
|
if (attempt < LOCK_RETRY_DELAYS_MS.length) {
|
|
108073
|
-
await new Promise((
|
|
108203
|
+
await new Promise((resolve41) => setTimeout(resolve41, LOCK_RETRY_DELAYS_MS[attempt]));
|
|
108074
108204
|
}
|
|
108075
108205
|
}
|
|
108076
108206
|
}
|
|
@@ -108105,13 +108235,13 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
|
|
|
108105
108235
|
message: e instanceof Error ? e.message : "Path validation failed"
|
|
108106
108236
|
};
|
|
108107
108237
|
}
|
|
108108
|
-
|
|
108109
|
-
|
|
108238
|
+
fs89.mkdirSync(path115.dirname(baselinePath), { recursive: true });
|
|
108239
|
+
fs89.mkdirSync(path115.dirname(tempPath), { recursive: true });
|
|
108110
108240
|
const releaseLock = await acquireLock2(lockPath);
|
|
108111
108241
|
try {
|
|
108112
108242
|
let existing = null;
|
|
108113
108243
|
try {
|
|
108114
|
-
const raw =
|
|
108244
|
+
const raw = fs89.readFileSync(baselinePath, "utf-8");
|
|
108115
108245
|
const parsed = JSON.parse(raw);
|
|
108116
108246
|
if (parsed.schema_version === BASELINE_SCHEMA_VERSION) {
|
|
108117
108247
|
existing = parsed;
|
|
@@ -108171,8 +108301,8 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
|
|
|
108171
108301
|
message: `Baseline would exceed size cap (${json4.length} bytes > ${MAX_BASELINE_BYTES})`
|
|
108172
108302
|
};
|
|
108173
108303
|
}
|
|
108174
|
-
|
|
108175
|
-
|
|
108304
|
+
fs89.writeFileSync(tempPath, json4, "utf-8");
|
|
108305
|
+
fs89.renameSync(tempPath, baselinePath);
|
|
108176
108306
|
return {
|
|
108177
108307
|
status: "merged",
|
|
108178
108308
|
path: baselinePath,
|
|
@@ -108203,8 +108333,8 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
|
|
|
108203
108333
|
message: `Baseline would exceed size cap (${json3.length} bytes > ${MAX_BASELINE_BYTES})`
|
|
108204
108334
|
};
|
|
108205
108335
|
}
|
|
108206
|
-
|
|
108207
|
-
|
|
108336
|
+
fs89.writeFileSync(tempPath, json3, "utf-8");
|
|
108337
|
+
fs89.renameSync(tempPath, baselinePath);
|
|
108208
108338
|
return {
|
|
108209
108339
|
status: "written",
|
|
108210
108340
|
path: baselinePath,
|
|
@@ -108229,7 +108359,7 @@ function loadBaseline(directory, phase) {
|
|
|
108229
108359
|
};
|
|
108230
108360
|
}
|
|
108231
108361
|
try {
|
|
108232
|
-
const raw =
|
|
108362
|
+
const raw = fs89.readFileSync(baselinePath, "utf-8");
|
|
108233
108363
|
const parsed = JSON.parse(raw);
|
|
108234
108364
|
if (parsed.schema_version !== BASELINE_SCHEMA_VERSION) {
|
|
108235
108365
|
return {
|
|
@@ -108277,17 +108407,17 @@ var SEVERITY_ORDER = {
|
|
|
108277
108407
|
};
|
|
108278
108408
|
function shouldSkipFile(filePath) {
|
|
108279
108409
|
try {
|
|
108280
|
-
const stats =
|
|
108410
|
+
const stats = fs90.statSync(filePath);
|
|
108281
108411
|
if (stats.size > MAX_FILE_SIZE_BYTES8) {
|
|
108282
108412
|
return { skip: true, reason: "file too large" };
|
|
108283
108413
|
}
|
|
108284
108414
|
if (stats.size === 0) {
|
|
108285
108415
|
return { skip: true, reason: "empty file" };
|
|
108286
108416
|
}
|
|
108287
|
-
const fd =
|
|
108417
|
+
const fd = fs90.openSync(filePath, "r");
|
|
108288
108418
|
const buffer = Buffer.alloc(8192);
|
|
108289
|
-
const bytesRead =
|
|
108290
|
-
|
|
108419
|
+
const bytesRead = fs90.readSync(fd, buffer, 0, 8192, 0);
|
|
108420
|
+
fs90.closeSync(fd);
|
|
108291
108421
|
if (bytesRead > 0) {
|
|
108292
108422
|
let nullCount = 0;
|
|
108293
108423
|
for (let i2 = 0;i2 < bytesRead; i2++) {
|
|
@@ -108326,7 +108456,7 @@ function countBySeverity(findings) {
|
|
|
108326
108456
|
}
|
|
108327
108457
|
function scanFileWithTierA(filePath, language) {
|
|
108328
108458
|
try {
|
|
108329
|
-
const content =
|
|
108459
|
+
const content = fs90.readFileSync(filePath, "utf-8");
|
|
108330
108460
|
const findings = executeRulesSync(filePath, content, language);
|
|
108331
108461
|
return findings.map((f) => ({
|
|
108332
108462
|
rule_id: f.rule_id,
|
|
@@ -108385,7 +108515,7 @@ async function sastScan(input, directory, config3) {
|
|
|
108385
108515
|
_filesSkipped++;
|
|
108386
108516
|
continue;
|
|
108387
108517
|
}
|
|
108388
|
-
if (!
|
|
108518
|
+
if (!fs90.existsSync(resolvedPath)) {
|
|
108389
108519
|
_filesSkipped++;
|
|
108390
108520
|
continue;
|
|
108391
108521
|
}
|
|
@@ -108954,7 +109084,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
108954
109084
|
}
|
|
108955
109085
|
let stat8;
|
|
108956
109086
|
try {
|
|
108957
|
-
stat8 =
|
|
109087
|
+
stat8 = fs91.statSync(file3);
|
|
108958
109088
|
} catch {
|
|
108959
109089
|
skippedFiles++;
|
|
108960
109090
|
continue;
|
|
@@ -108965,7 +109095,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
108965
109095
|
}
|
|
108966
109096
|
let content;
|
|
108967
109097
|
try {
|
|
108968
|
-
const buffer =
|
|
109098
|
+
const buffer = fs91.readFileSync(file3);
|
|
108969
109099
|
if (buffer.includes(0)) {
|
|
108970
109100
|
skippedFiles++;
|
|
108971
109101
|
continue;
|
|
@@ -109664,7 +109794,7 @@ var repo_map = createSwarmTool({
|
|
|
109664
109794
|
// src/tools/req-coverage.ts
|
|
109665
109795
|
init_zod();
|
|
109666
109796
|
init_create_tool();
|
|
109667
|
-
import * as
|
|
109797
|
+
import * as fs92 from "node:fs";
|
|
109668
109798
|
import * as path119 from "node:path";
|
|
109669
109799
|
var SPEC_FILE = ".swarm/spec.md";
|
|
109670
109800
|
var EVIDENCE_DIR4 = ".swarm/evidence";
|
|
@@ -109724,19 +109854,19 @@ function extractObligationAndText(id, lineText) {
|
|
|
109724
109854
|
var PHASE_TASK_ID_REGEX = /^\d+\.\d+(\.\d+)*$/;
|
|
109725
109855
|
function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
109726
109856
|
const touchedFiles = new Set;
|
|
109727
|
-
if (!
|
|
109857
|
+
if (!fs92.existsSync(evidenceDir) || !fs92.statSync(evidenceDir).isDirectory()) {
|
|
109728
109858
|
return [];
|
|
109729
109859
|
}
|
|
109730
109860
|
let entries;
|
|
109731
109861
|
try {
|
|
109732
|
-
entries =
|
|
109862
|
+
entries = fs92.readdirSync(evidenceDir);
|
|
109733
109863
|
} catch {
|
|
109734
109864
|
return [];
|
|
109735
109865
|
}
|
|
109736
109866
|
for (const entry of entries) {
|
|
109737
109867
|
const entryPath = path119.join(evidenceDir, entry);
|
|
109738
109868
|
try {
|
|
109739
|
-
const stat8 =
|
|
109869
|
+
const stat8 = fs92.statSync(entryPath);
|
|
109740
109870
|
if (!stat8.isDirectory()) {
|
|
109741
109871
|
continue;
|
|
109742
109872
|
}
|
|
@@ -109757,7 +109887,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
109757
109887
|
if (!resolvedPath.startsWith(evidenceDirResolved + path119.sep)) {
|
|
109758
109888
|
continue;
|
|
109759
109889
|
}
|
|
109760
|
-
const stat8 =
|
|
109890
|
+
const stat8 = fs92.lstatSync(evidenceFilePath);
|
|
109761
109891
|
if (!stat8.isFile()) {
|
|
109762
109892
|
continue;
|
|
109763
109893
|
}
|
|
@@ -109769,7 +109899,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
109769
109899
|
}
|
|
109770
109900
|
let content;
|
|
109771
109901
|
try {
|
|
109772
|
-
content =
|
|
109902
|
+
content = fs92.readFileSync(evidenceFilePath, "utf-8");
|
|
109773
109903
|
} catch {
|
|
109774
109904
|
continue;
|
|
109775
109905
|
}
|
|
@@ -109806,7 +109936,7 @@ function searchFileForKeywords(filePath, keywords, cwd) {
|
|
|
109806
109936
|
if (!resolvedPath.startsWith(cwdResolved)) {
|
|
109807
109937
|
return false;
|
|
109808
109938
|
}
|
|
109809
|
-
const content =
|
|
109939
|
+
const content = fs92.readFileSync(resolvedPath, "utf-8");
|
|
109810
109940
|
for (const keyword of keywords) {
|
|
109811
109941
|
const regex = new RegExp(`\\b${keyword}\\b`, "i");
|
|
109812
109942
|
if (regex.test(content)) {
|
|
@@ -109939,7 +110069,7 @@ var req_coverage = createSwarmTool({
|
|
|
109939
110069
|
const specPath = path119.join(cwd, SPEC_FILE);
|
|
109940
110070
|
let specContent;
|
|
109941
110071
|
try {
|
|
109942
|
-
specContent =
|
|
110072
|
+
specContent = fs92.readFileSync(specPath, "utf-8");
|
|
109943
110073
|
} catch (readError) {
|
|
109944
110074
|
return JSON.stringify({
|
|
109945
110075
|
success: false,
|
|
@@ -109991,10 +110121,10 @@ var req_coverage = createSwarmTool({
|
|
|
109991
110121
|
const reportFilename = `req-coverage-phase-${phase}.json`;
|
|
109992
110122
|
const reportPath = path119.join(evidenceDir, reportFilename);
|
|
109993
110123
|
try {
|
|
109994
|
-
if (!
|
|
109995
|
-
|
|
110124
|
+
if (!fs92.existsSync(evidenceDir)) {
|
|
110125
|
+
fs92.mkdirSync(evidenceDir, { recursive: true });
|
|
109996
110126
|
}
|
|
109997
|
-
|
|
110127
|
+
fs92.writeFileSync(reportPath, JSON.stringify(result, null, 2), "utf-8");
|
|
109998
110128
|
} catch (writeError) {
|
|
109999
110129
|
console.warn(`Failed to write coverage report: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
|
|
110000
110130
|
}
|
|
@@ -110076,7 +110206,7 @@ init_plan_schema();
|
|
|
110076
110206
|
init_qa_gate_profile();
|
|
110077
110207
|
init_file_locks();
|
|
110078
110208
|
import * as crypto11 from "node:crypto";
|
|
110079
|
-
import * as
|
|
110209
|
+
import * as fs93 from "node:fs";
|
|
110080
110210
|
import * as path120 from "node:path";
|
|
110081
110211
|
init_ledger();
|
|
110082
110212
|
init_manager();
|
|
@@ -110159,7 +110289,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
110159
110289
|
const resolvedRoot = path120.resolve(fallbackDir);
|
|
110160
110290
|
let fallbackExists = false;
|
|
110161
110291
|
try {
|
|
110162
|
-
|
|
110292
|
+
fs93.accessSync(resolvedRoot, fs93.constants.F_OK);
|
|
110163
110293
|
fallbackExists = true;
|
|
110164
110294
|
} catch {
|
|
110165
110295
|
fallbackExists = false;
|
|
@@ -110183,9 +110313,9 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
110183
110313
|
if (process.env.SWARM_SKIP_SPEC_GATE !== "1") {
|
|
110184
110314
|
const specPath = path120.join(targetWorkspace, ".swarm", "spec.md");
|
|
110185
110315
|
try {
|
|
110186
|
-
const stat8 = await
|
|
110316
|
+
const stat8 = await fs93.promises.stat(specPath);
|
|
110187
110317
|
specMtime = stat8.mtime.toISOString();
|
|
110188
|
-
const content = await
|
|
110318
|
+
const content = await fs93.promises.readFile(specPath, "utf8");
|
|
110189
110319
|
specHash = crypto11.createHash("sha256").update(content).digest("hex");
|
|
110190
110320
|
} catch {
|
|
110191
110321
|
return {
|
|
@@ -110200,7 +110330,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
110200
110330
|
const contextPath = path120.join(targetWorkspace, ".swarm", "context.md");
|
|
110201
110331
|
let contextContent = "";
|
|
110202
110332
|
try {
|
|
110203
|
-
contextContent = await
|
|
110333
|
+
contextContent = await fs93.promises.readFile(contextPath, "utf8");
|
|
110204
110334
|
} catch {}
|
|
110205
110335
|
const hasPendingSection = contextContent.includes("## Pending QA Gate Selection");
|
|
110206
110336
|
if (!hasPendingSection) {
|
|
@@ -110461,7 +110591,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
110461
110591
|
phases_count: plan.phases.length,
|
|
110462
110592
|
tasks_count: tasksCount
|
|
110463
110593
|
});
|
|
110464
|
-
await
|
|
110594
|
+
await fs93.promises.writeFile(markerPath, marker, "utf8");
|
|
110465
110595
|
} catch {}
|
|
110466
110596
|
const warnings = [];
|
|
110467
110597
|
let criticReviewFound = false;
|
|
@@ -110541,7 +110671,7 @@ var save_plan = createSwarmTool({
|
|
|
110541
110671
|
// src/tools/sbom-generate.ts
|
|
110542
110672
|
init_zod();
|
|
110543
110673
|
init_manager2();
|
|
110544
|
-
import * as
|
|
110674
|
+
import * as fs94 from "node:fs";
|
|
110545
110675
|
import * as path121 from "node:path";
|
|
110546
110676
|
|
|
110547
110677
|
// src/sbom/detectors/index.ts
|
|
@@ -111390,7 +111520,7 @@ function findManifestFiles(rootDir) {
|
|
|
111390
111520
|
const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
|
|
111391
111521
|
function searchDir(dir) {
|
|
111392
111522
|
try {
|
|
111393
|
-
const entries =
|
|
111523
|
+
const entries = fs94.readdirSync(dir, { withFileTypes: true });
|
|
111394
111524
|
for (const entry of entries) {
|
|
111395
111525
|
const fullPath = path121.join(dir, entry.name);
|
|
111396
111526
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
|
|
@@ -111417,7 +111547,7 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
111417
111547
|
const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
|
|
111418
111548
|
for (const dir of directories) {
|
|
111419
111549
|
try {
|
|
111420
|
-
const entries =
|
|
111550
|
+
const entries = fs94.readdirSync(dir, { withFileTypes: true });
|
|
111421
111551
|
for (const entry of entries) {
|
|
111422
111552
|
const fullPath = path121.join(dir, entry.name);
|
|
111423
111553
|
if (entry.isFile()) {
|
|
@@ -111454,7 +111584,7 @@ function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
|
|
|
111454
111584
|
}
|
|
111455
111585
|
function ensureOutputDir(outputDir) {
|
|
111456
111586
|
try {
|
|
111457
|
-
|
|
111587
|
+
fs94.mkdirSync(outputDir, { recursive: true });
|
|
111458
111588
|
} catch (error93) {
|
|
111459
111589
|
if (!error93 || error93.code !== "EEXIST") {
|
|
111460
111590
|
throw error93;
|
|
@@ -111548,10 +111678,10 @@ var sbom_generate = createSwarmTool({
|
|
|
111548
111678
|
for (const manifestFile of manifestFiles) {
|
|
111549
111679
|
try {
|
|
111550
111680
|
const fullPath = path121.isAbsolute(manifestFile) ? manifestFile : path121.join(workingDir, manifestFile);
|
|
111551
|
-
if (!
|
|
111681
|
+
if (!fs94.existsSync(fullPath)) {
|
|
111552
111682
|
continue;
|
|
111553
111683
|
}
|
|
111554
|
-
const content =
|
|
111684
|
+
const content = fs94.readFileSync(fullPath, "utf-8");
|
|
111555
111685
|
const components = detectComponents(manifestFile, content);
|
|
111556
111686
|
processedFiles.push(manifestFile);
|
|
111557
111687
|
if (components.length > 0) {
|
|
@@ -111565,7 +111695,7 @@ var sbom_generate = createSwarmTool({
|
|
|
111565
111695
|
const bomJson = serializeCycloneDX(bom);
|
|
111566
111696
|
const filename = generateSbomFilename();
|
|
111567
111697
|
const outputPath = path121.join(outputDir, filename);
|
|
111568
|
-
|
|
111698
|
+
fs94.writeFileSync(outputPath, bomJson, "utf-8");
|
|
111569
111699
|
const verdict = processedFiles.length > 0 ? "pass" : "pass";
|
|
111570
111700
|
try {
|
|
111571
111701
|
const timestamp = new Date().toISOString();
|
|
@@ -111607,7 +111737,7 @@ var sbom_generate = createSwarmTool({
|
|
|
111607
111737
|
// src/tools/schema-drift.ts
|
|
111608
111738
|
init_zod();
|
|
111609
111739
|
init_create_tool();
|
|
111610
|
-
import * as
|
|
111740
|
+
import * as fs95 from "node:fs";
|
|
111611
111741
|
import * as path122 from "node:path";
|
|
111612
111742
|
var SPEC_CANDIDATES = [
|
|
111613
111743
|
"openapi.json",
|
|
@@ -111649,19 +111779,19 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
111649
111779
|
if (!ALLOWED_EXTENSIONS.includes(ext)) {
|
|
111650
111780
|
throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
|
|
111651
111781
|
}
|
|
111652
|
-
const stats =
|
|
111782
|
+
const stats = fs95.statSync(resolvedPath);
|
|
111653
111783
|
if (stats.size > MAX_SPEC_SIZE) {
|
|
111654
111784
|
throw new Error(`Invalid spec_file: file exceeds ${MAX_SPEC_SIZE / 1024 / 1024}MB limit`);
|
|
111655
111785
|
}
|
|
111656
|
-
if (!
|
|
111786
|
+
if (!fs95.existsSync(resolvedPath)) {
|
|
111657
111787
|
throw new Error(`Spec file not found: ${resolvedPath}`);
|
|
111658
111788
|
}
|
|
111659
111789
|
return resolvedPath;
|
|
111660
111790
|
}
|
|
111661
111791
|
for (const candidate of SPEC_CANDIDATES) {
|
|
111662
111792
|
const candidatePath = path122.resolve(cwd, candidate);
|
|
111663
|
-
if (
|
|
111664
|
-
const stats =
|
|
111793
|
+
if (fs95.existsSync(candidatePath)) {
|
|
111794
|
+
const stats = fs95.statSync(candidatePath);
|
|
111665
111795
|
if (stats.size <= MAX_SPEC_SIZE) {
|
|
111666
111796
|
return candidatePath;
|
|
111667
111797
|
}
|
|
@@ -111670,7 +111800,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
111670
111800
|
return null;
|
|
111671
111801
|
}
|
|
111672
111802
|
function parseSpec(specFile) {
|
|
111673
|
-
const content =
|
|
111803
|
+
const content = fs95.readFileSync(specFile, "utf-8");
|
|
111674
111804
|
const ext = path122.extname(specFile).toLowerCase();
|
|
111675
111805
|
if (ext === ".json") {
|
|
111676
111806
|
return parseJsonSpec(content);
|
|
@@ -111742,7 +111872,7 @@ function extractRoutes(cwd) {
|
|
|
111742
111872
|
function walkDir(dir) {
|
|
111743
111873
|
let entries;
|
|
111744
111874
|
try {
|
|
111745
|
-
entries =
|
|
111875
|
+
entries = fs95.readdirSync(dir, { withFileTypes: true });
|
|
111746
111876
|
} catch {
|
|
111747
111877
|
return;
|
|
111748
111878
|
}
|
|
@@ -111775,7 +111905,7 @@ function extractRoutes(cwd) {
|
|
|
111775
111905
|
}
|
|
111776
111906
|
function extractRoutesFromFile(filePath) {
|
|
111777
111907
|
const routes = [];
|
|
111778
|
-
const content =
|
|
111908
|
+
const content = fs95.readFileSync(filePath, "utf-8");
|
|
111779
111909
|
const lines = content.split(/\r?\n/);
|
|
111780
111910
|
const expressRegex = /(?:app|router|server|express)\.(get|post|put|patch|delete|options|head)\s*\(\s*['"`]([^'"`]+)['"`]/g;
|
|
111781
111911
|
const flaskRegex = /@(?:app|blueprint|bp)\.route\s*\(\s*['"]([^'"]+)['"]/g;
|
|
@@ -111924,7 +112054,7 @@ init_zod();
|
|
|
111924
112054
|
init_bun_compat();
|
|
111925
112055
|
init_path_security();
|
|
111926
112056
|
init_create_tool();
|
|
111927
|
-
import * as
|
|
112057
|
+
import * as fs96 from "node:fs";
|
|
111928
112058
|
import * as path123 from "node:path";
|
|
111929
112059
|
var DEFAULT_MAX_RESULTS = 100;
|
|
111930
112060
|
var DEFAULT_MAX_LINES = 200;
|
|
@@ -111962,8 +112092,8 @@ function containsWindowsAttacks3(str) {
|
|
|
111962
112092
|
function isPathInWorkspace3(filePath, workspace) {
|
|
111963
112093
|
try {
|
|
111964
112094
|
const resolvedPath = path123.resolve(workspace, filePath);
|
|
111965
|
-
const realWorkspace =
|
|
111966
|
-
const realResolvedPath =
|
|
112095
|
+
const realWorkspace = fs96.realpathSync(workspace);
|
|
112096
|
+
const realResolvedPath = fs96.realpathSync(resolvedPath);
|
|
111967
112097
|
const relativePath = path123.relative(realWorkspace, realResolvedPath);
|
|
111968
112098
|
if (relativePath.startsWith("..") || path123.isAbsolute(relativePath)) {
|
|
111969
112099
|
return false;
|
|
@@ -111983,7 +112113,7 @@ function findRgInEnvPath() {
|
|
|
111983
112113
|
continue;
|
|
111984
112114
|
const isWindows = process.platform === "win32";
|
|
111985
112115
|
const candidate = path123.join(dir, isWindows ? "rg.exe" : "rg");
|
|
111986
|
-
if (
|
|
112116
|
+
if (fs96.existsSync(candidate))
|
|
111987
112117
|
return candidate;
|
|
111988
112118
|
}
|
|
111989
112119
|
return null;
|
|
@@ -112037,7 +112167,7 @@ async function ripgrepSearch(opts) {
|
|
|
112037
112167
|
stderr: "pipe",
|
|
112038
112168
|
cwd: opts.workspace
|
|
112039
112169
|
});
|
|
112040
|
-
const timeout = new Promise((
|
|
112170
|
+
const timeout = new Promise((resolve47) => setTimeout(() => resolve47("timeout"), REGEX_TIMEOUT_MS));
|
|
112041
112171
|
const exitPromise = proc.exited;
|
|
112042
112172
|
const result = await Promise.race([exitPromise, timeout]);
|
|
112043
112173
|
if (result === "timeout") {
|
|
@@ -112110,7 +112240,7 @@ function collectFiles(dir, workspace, includeGlobs, excludeGlobs) {
|
|
|
112110
112240
|
return files;
|
|
112111
112241
|
}
|
|
112112
112242
|
try {
|
|
112113
|
-
const entries =
|
|
112243
|
+
const entries = fs96.readdirSync(dir, { withFileTypes: true });
|
|
112114
112244
|
for (const entry of entries) {
|
|
112115
112245
|
const fullPath = path123.join(dir, entry.name);
|
|
112116
112246
|
const relativePath = path123.relative(workspace, fullPath);
|
|
@@ -112160,7 +112290,7 @@ async function fallbackSearch(opts) {
|
|
|
112160
112290
|
}
|
|
112161
112291
|
let stats;
|
|
112162
112292
|
try {
|
|
112163
|
-
stats =
|
|
112293
|
+
stats = fs96.statSync(fullPath);
|
|
112164
112294
|
if (stats.size > MAX_FILE_SIZE_BYTES10) {
|
|
112165
112295
|
continue;
|
|
112166
112296
|
}
|
|
@@ -112169,7 +112299,7 @@ async function fallbackSearch(opts) {
|
|
|
112169
112299
|
}
|
|
112170
112300
|
let content;
|
|
112171
112301
|
try {
|
|
112172
|
-
content =
|
|
112302
|
+
content = fs96.readFileSync(fullPath, "utf-8");
|
|
112173
112303
|
} catch {
|
|
112174
112304
|
continue;
|
|
112175
112305
|
}
|
|
@@ -112281,7 +112411,7 @@ var search = createSwarmTool({
|
|
|
112281
112411
|
message: "Exclude pattern contains invalid Windows-specific sequence"
|
|
112282
112412
|
}, null, 2);
|
|
112283
112413
|
}
|
|
112284
|
-
if (!
|
|
112414
|
+
if (!fs96.existsSync(directory)) {
|
|
112285
112415
|
return JSON.stringify({
|
|
112286
112416
|
error: true,
|
|
112287
112417
|
type: "unknown",
|
|
@@ -112569,8 +112699,8 @@ var spec_write = createSwarmTool({
|
|
|
112569
112699
|
let finalContent = content;
|
|
112570
112700
|
if (mode === "append") {
|
|
112571
112701
|
try {
|
|
112572
|
-
const
|
|
112573
|
-
const prior = await
|
|
112702
|
+
const fs97 = await import("node:fs/promises");
|
|
112703
|
+
const prior = await fs97.readFile(target, "utf-8");
|
|
112574
112704
|
finalContent = `${prior.replace(/\s+$/, "")}
|
|
112575
112705
|
|
|
112576
112706
|
${content}
|
|
@@ -112878,7 +113008,7 @@ function createSwarmCommandTool(agents) {
|
|
|
112878
113008
|
init_zod();
|
|
112879
113009
|
init_path_security();
|
|
112880
113010
|
init_create_tool();
|
|
112881
|
-
import * as
|
|
113011
|
+
import * as fs97 from "node:fs";
|
|
112882
113012
|
import * as path126 from "node:path";
|
|
112883
113013
|
var WINDOWS_RESERVED_NAMES4 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
112884
113014
|
function containsWindowsAttacks4(str) {
|
|
@@ -112894,11 +113024,11 @@ function containsWindowsAttacks4(str) {
|
|
|
112894
113024
|
function isPathInWorkspace4(filePath, workspace) {
|
|
112895
113025
|
try {
|
|
112896
113026
|
const resolvedPath = path126.resolve(workspace, filePath);
|
|
112897
|
-
if (!
|
|
113027
|
+
if (!fs97.existsSync(resolvedPath)) {
|
|
112898
113028
|
return true;
|
|
112899
113029
|
}
|
|
112900
|
-
const realWorkspace =
|
|
112901
|
-
const realResolvedPath =
|
|
113030
|
+
const realWorkspace = fs97.realpathSync(workspace);
|
|
113031
|
+
const realResolvedPath = fs97.realpathSync(resolvedPath);
|
|
112902
113032
|
const relativePath = path126.relative(realWorkspace, realResolvedPath);
|
|
112903
113033
|
if (relativePath.startsWith("..") || path126.isAbsolute(relativePath)) {
|
|
112904
113034
|
return false;
|
|
@@ -113072,7 +113202,7 @@ var suggestPatch = createSwarmTool({
|
|
|
113072
113202
|
message: "changes cannot be empty"
|
|
113073
113203
|
}, null, 2);
|
|
113074
113204
|
}
|
|
113075
|
-
if (!
|
|
113205
|
+
if (!fs97.existsSync(directory)) {
|
|
113076
113206
|
return JSON.stringify({
|
|
113077
113207
|
success: false,
|
|
113078
113208
|
error: true,
|
|
@@ -113109,7 +113239,7 @@ var suggestPatch = createSwarmTool({
|
|
|
113109
113239
|
continue;
|
|
113110
113240
|
}
|
|
113111
113241
|
const fullPath = path126.resolve(directory, change.file);
|
|
113112
|
-
if (!
|
|
113242
|
+
if (!fs97.existsSync(fullPath)) {
|
|
113113
113243
|
errors5.push({
|
|
113114
113244
|
success: false,
|
|
113115
113245
|
error: true,
|
|
@@ -113123,7 +113253,7 @@ var suggestPatch = createSwarmTool({
|
|
|
113123
113253
|
}
|
|
113124
113254
|
let content;
|
|
113125
113255
|
try {
|
|
113126
|
-
content =
|
|
113256
|
+
content = fs97.readFileSync(fullPath, "utf-8");
|
|
113127
113257
|
} catch (err3) {
|
|
113128
113258
|
errors5.push({
|
|
113129
113259
|
success: false,
|
|
@@ -113411,11 +113541,11 @@ var lean_turbo_acquire_locks = createSwarmTool({
|
|
|
113411
113541
|
// src/tools/lean-turbo-plan-lanes.ts
|
|
113412
113542
|
init_zod();
|
|
113413
113543
|
init_constants();
|
|
113414
|
-
import * as
|
|
113544
|
+
import * as fs99 from "node:fs";
|
|
113415
113545
|
import * as path128 from "node:path";
|
|
113416
113546
|
|
|
113417
113547
|
// src/turbo/lean/conflicts.ts
|
|
113418
|
-
import * as
|
|
113548
|
+
import * as fs98 from "node:fs";
|
|
113419
113549
|
import * as path127 from "node:path";
|
|
113420
113550
|
var DEFAULT_GLOBAL_FILES = [
|
|
113421
113551
|
"package.json",
|
|
@@ -113545,10 +113675,10 @@ function isProtectedPath2(normalizedPath) {
|
|
|
113545
113675
|
function readTaskScopes(directory, taskId) {
|
|
113546
113676
|
const scopePath = path127.join(directory, ".swarm", "scopes", `scope-${taskId}.json`);
|
|
113547
113677
|
try {
|
|
113548
|
-
if (!
|
|
113678
|
+
if (!fs98.existsSync(scopePath)) {
|
|
113549
113679
|
return null;
|
|
113550
113680
|
}
|
|
113551
|
-
const raw =
|
|
113681
|
+
const raw = fs98.readFileSync(scopePath, "utf-8");
|
|
113552
113682
|
const parsed = JSON.parse(raw);
|
|
113553
113683
|
if (!parsed || !Array.isArray(parsed.files)) {
|
|
113554
113684
|
return null;
|
|
@@ -113932,11 +114062,11 @@ function createEmptyPlan(phaseNumber, planId) {
|
|
|
113932
114062
|
init_create_tool();
|
|
113933
114063
|
function readPlanJson(directory) {
|
|
113934
114064
|
const planPath = path128.join(directory, ".swarm", "plan.json");
|
|
113935
|
-
if (!
|
|
114065
|
+
if (!fs99.existsSync(planPath)) {
|
|
113936
114066
|
return null;
|
|
113937
114067
|
}
|
|
113938
114068
|
try {
|
|
113939
|
-
return JSON.parse(
|
|
114069
|
+
return JSON.parse(fs99.readFileSync(planPath, "utf-8"));
|
|
113940
114070
|
} catch {
|
|
113941
114071
|
return null;
|
|
113942
114072
|
}
|
|
@@ -113985,7 +114115,7 @@ init_config();
|
|
|
113985
114115
|
|
|
113986
114116
|
// src/turbo/lean/reviewer.ts
|
|
113987
114117
|
init_state();
|
|
113988
|
-
import * as
|
|
114118
|
+
import * as fs100 from "node:fs/promises";
|
|
113989
114119
|
import * as path129 from "node:path";
|
|
113990
114120
|
init_state3();
|
|
113991
114121
|
var DEFAULT_CONFIG3 = {
|
|
@@ -114103,7 +114233,7 @@ function parseReviewerVerdict(responseText) {
|
|
|
114103
114233
|
}
|
|
114104
114234
|
async function writeReviewerEvidence(directory, phase, verdict, reason) {
|
|
114105
114235
|
const evidenceDir = path129.join(directory, ".swarm", "evidence", String(phase));
|
|
114106
|
-
await
|
|
114236
|
+
await fs100.mkdir(evidenceDir, { recursive: true });
|
|
114107
114237
|
const evidencePath = path129.join(evidenceDir, "lean-turbo-reviewer.json");
|
|
114108
114238
|
const content = JSON.stringify({
|
|
114109
114239
|
phase,
|
|
@@ -114113,11 +114243,11 @@ async function writeReviewerEvidence(directory, phase, verdict, reason) {
|
|
|
114113
114243
|
}, null, 2);
|
|
114114
114244
|
const tempPath = `${evidencePath}.tmp.${process.pid}.${Date.now()}`;
|
|
114115
114245
|
try {
|
|
114116
|
-
await
|
|
114117
|
-
await
|
|
114246
|
+
await fs100.writeFile(tempPath, content, "utf-8");
|
|
114247
|
+
await fs100.rename(tempPath, evidencePath);
|
|
114118
114248
|
} catch (error93) {
|
|
114119
114249
|
try {
|
|
114120
|
-
await
|
|
114250
|
+
await fs100.unlink(tempPath);
|
|
114121
114251
|
} catch {}
|
|
114122
114252
|
throw error93;
|
|
114123
114253
|
}
|
|
@@ -114908,7 +115038,7 @@ var lean_turbo_status = createSwarmTool({
|
|
|
114908
115038
|
// src/tools/lint-spec.ts
|
|
114909
115039
|
init_spec_schema();
|
|
114910
115040
|
init_create_tool();
|
|
114911
|
-
import * as
|
|
115041
|
+
import * as fs101 from "node:fs";
|
|
114912
115042
|
import * as path130 from "node:path";
|
|
114913
115043
|
var SPEC_FILE_NAME = "spec.md";
|
|
114914
115044
|
var SWARM_DIR2 = ".swarm";
|
|
@@ -114963,7 +115093,7 @@ var lint_spec = createSwarmTool({
|
|
|
114963
115093
|
const errors5 = [];
|
|
114964
115094
|
const warnings = [];
|
|
114965
115095
|
const specPath = path130.join(directory, SWARM_DIR2, SPEC_FILE_NAME);
|
|
114966
|
-
if (!
|
|
115096
|
+
if (!fs101.existsSync(specPath)) {
|
|
114967
115097
|
const result2 = {
|
|
114968
115098
|
valid: false,
|
|
114969
115099
|
specMtime: null,
|
|
@@ -114982,12 +115112,12 @@ var lint_spec = createSwarmTool({
|
|
|
114982
115112
|
}
|
|
114983
115113
|
let specMtime = null;
|
|
114984
115114
|
try {
|
|
114985
|
-
const stats =
|
|
115115
|
+
const stats = fs101.statSync(specPath);
|
|
114986
115116
|
specMtime = stats.mtime.toISOString();
|
|
114987
115117
|
} catch {}
|
|
114988
115118
|
let content;
|
|
114989
115119
|
try {
|
|
114990
|
-
content =
|
|
115120
|
+
content = fs101.readFileSync(specPath, "utf-8");
|
|
114991
115121
|
} catch (e) {
|
|
114992
115122
|
const result2 = {
|
|
114993
115123
|
valid: false,
|
|
@@ -115032,7 +115162,7 @@ var lint_spec = createSwarmTool({
|
|
|
115032
115162
|
});
|
|
115033
115163
|
// src/tools/mutation-test.ts
|
|
115034
115164
|
init_zod();
|
|
115035
|
-
import * as
|
|
115165
|
+
import * as fs102 from "node:fs";
|
|
115036
115166
|
import * as path132 from "node:path";
|
|
115037
115167
|
|
|
115038
115168
|
// src/mutation/engine.ts
|
|
@@ -115589,7 +115719,7 @@ var mutation_test = createSwarmTool({
|
|
|
115589
115719
|
for (const filePath of uniquePaths) {
|
|
115590
115720
|
try {
|
|
115591
115721
|
const resolvedPath = path132.resolve(cwd, filePath);
|
|
115592
|
-
sourceFiles.set(filePath,
|
|
115722
|
+
sourceFiles.set(filePath, fs102.readFileSync(resolvedPath, "utf-8"));
|
|
115593
115723
|
} catch {}
|
|
115594
115724
|
}
|
|
115595
115725
|
const report = await executeMutationSuite(typedArgs.patches, typedArgs.test_command, typedArgs.files, cwd, undefined, undefined, sourceFiles.size > 0 ? sourceFiles : undefined);
|
|
@@ -115607,7 +115737,7 @@ var mutation_test = createSwarmTool({
|
|
|
115607
115737
|
init_zod();
|
|
115608
115738
|
init_manager2();
|
|
115609
115739
|
init_detector();
|
|
115610
|
-
import * as
|
|
115740
|
+
import * as fs103 from "node:fs";
|
|
115611
115741
|
import * as path133 from "node:path";
|
|
115612
115742
|
init_create_tool();
|
|
115613
115743
|
var MAX_FILE_SIZE2 = 2 * 1024 * 1024;
|
|
@@ -115717,7 +115847,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
115717
115847
|
}
|
|
115718
115848
|
let content;
|
|
115719
115849
|
try {
|
|
115720
|
-
content =
|
|
115850
|
+
content = fs103.readFileSync(fullPath, "utf8");
|
|
115721
115851
|
} catch {
|
|
115722
115852
|
result.skipped_reason = "file_read_error";
|
|
115723
115853
|
skippedCount++;
|
|
@@ -115833,7 +115963,7 @@ init_zod();
|
|
|
115833
115963
|
init_utils();
|
|
115834
115964
|
init_create_tool();
|
|
115835
115965
|
init_path_security();
|
|
115836
|
-
import * as
|
|
115966
|
+
import * as fs104 from "node:fs";
|
|
115837
115967
|
import * as path134 from "node:path";
|
|
115838
115968
|
var MAX_TEXT_LENGTH = 200;
|
|
115839
115969
|
var MAX_FILE_SIZE_BYTES11 = 1024 * 1024;
|
|
@@ -115924,7 +116054,7 @@ function isSupportedExtension(filePath) {
|
|
|
115924
116054
|
function findSourceFiles3(dir, files = []) {
|
|
115925
116055
|
let entries;
|
|
115926
116056
|
try {
|
|
115927
|
-
entries =
|
|
116057
|
+
entries = fs104.readdirSync(dir);
|
|
115928
116058
|
} catch {
|
|
115929
116059
|
return files;
|
|
115930
116060
|
}
|
|
@@ -115936,7 +116066,7 @@ function findSourceFiles3(dir, files = []) {
|
|
|
115936
116066
|
const fullPath = path134.join(dir, entry);
|
|
115937
116067
|
let stat8;
|
|
115938
116068
|
try {
|
|
115939
|
-
stat8 =
|
|
116069
|
+
stat8 = fs104.statSync(fullPath);
|
|
115940
116070
|
} catch {
|
|
115941
116071
|
continue;
|
|
115942
116072
|
}
|
|
@@ -116029,7 +116159,7 @@ var todo_extract = createSwarmTool({
|
|
|
116029
116159
|
return JSON.stringify(errorResult, null, 2);
|
|
116030
116160
|
}
|
|
116031
116161
|
const scanPath = resolvedPath;
|
|
116032
|
-
if (!
|
|
116162
|
+
if (!fs104.existsSync(scanPath)) {
|
|
116033
116163
|
const errorResult = {
|
|
116034
116164
|
error: `path not found: ${pathsInput}`,
|
|
116035
116165
|
total: 0,
|
|
@@ -116039,7 +116169,7 @@ var todo_extract = createSwarmTool({
|
|
|
116039
116169
|
return JSON.stringify(errorResult, null, 2);
|
|
116040
116170
|
}
|
|
116041
116171
|
const filesToScan = [];
|
|
116042
|
-
const stat8 =
|
|
116172
|
+
const stat8 = fs104.statSync(scanPath);
|
|
116043
116173
|
if (stat8.isFile()) {
|
|
116044
116174
|
if (isSupportedExtension(scanPath)) {
|
|
116045
116175
|
filesToScan.push(scanPath);
|
|
@@ -116058,11 +116188,11 @@ var todo_extract = createSwarmTool({
|
|
|
116058
116188
|
const allEntries = [];
|
|
116059
116189
|
for (const filePath of filesToScan) {
|
|
116060
116190
|
try {
|
|
116061
|
-
const fileStat =
|
|
116191
|
+
const fileStat = fs104.statSync(filePath);
|
|
116062
116192
|
if (fileStat.size > MAX_FILE_SIZE_BYTES11) {
|
|
116063
116193
|
continue;
|
|
116064
116194
|
}
|
|
116065
|
-
const content =
|
|
116195
|
+
const content = fs104.readFileSync(filePath, "utf-8");
|
|
116066
116196
|
const entries = parseTodoComments(content, filePath, tagsSet);
|
|
116067
116197
|
allEntries.push(...entries);
|
|
116068
116198
|
} catch {}
|
|
@@ -116093,17 +116223,17 @@ init_loader();
|
|
|
116093
116223
|
init_schema();
|
|
116094
116224
|
init_qa_gate_profile();
|
|
116095
116225
|
init_gate_evidence();
|
|
116096
|
-
import * as
|
|
116226
|
+
import * as fs108 from "node:fs";
|
|
116097
116227
|
import * as path138 from "node:path";
|
|
116098
116228
|
|
|
116099
116229
|
// src/hooks/diff-scope.ts
|
|
116100
116230
|
init_bun_compat();
|
|
116101
|
-
import * as
|
|
116231
|
+
import * as fs106 from "node:fs";
|
|
116102
116232
|
import * as path136 from "node:path";
|
|
116103
116233
|
|
|
116104
116234
|
// src/utils/gitignore-warning.ts
|
|
116105
116235
|
init_bun_compat();
|
|
116106
|
-
import * as
|
|
116236
|
+
import * as fs105 from "node:fs";
|
|
116107
116237
|
import * as path135 from "node:path";
|
|
116108
116238
|
var _internals54 = { bunSpawn };
|
|
116109
116239
|
var _swarmGitExcludedChecked = false;
|
|
@@ -116181,13 +116311,13 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
116181
116311
|
const excludePath = path135.isAbsolute(excludeRelPath) ? excludeRelPath : path135.join(directory, excludeRelPath);
|
|
116182
116312
|
if (checkIgnoreExitCode !== 0) {
|
|
116183
116313
|
try {
|
|
116184
|
-
|
|
116314
|
+
fs105.mkdirSync(path135.dirname(excludePath), { recursive: true });
|
|
116185
116315
|
let existing = "";
|
|
116186
116316
|
try {
|
|
116187
|
-
existing =
|
|
116317
|
+
existing = fs105.readFileSync(excludePath, "utf8");
|
|
116188
116318
|
} catch {}
|
|
116189
116319
|
if (!fileCoversSwarm(existing)) {
|
|
116190
|
-
|
|
116320
|
+
fs105.appendFileSync(excludePath, `
|
|
116191
116321
|
# opencode-swarm local runtime state
|
|
116192
116322
|
.swarm/
|
|
116193
116323
|
`, "utf8");
|
|
@@ -116226,9 +116356,9 @@ var _internals55 = { bunSpawn };
|
|
|
116226
116356
|
function getDeclaredScope(taskId, directory) {
|
|
116227
116357
|
try {
|
|
116228
116358
|
const planPath = path136.join(directory, ".swarm", "plan.json");
|
|
116229
|
-
if (!
|
|
116359
|
+
if (!fs106.existsSync(planPath))
|
|
116230
116360
|
return null;
|
|
116231
|
-
const raw =
|
|
116361
|
+
const raw = fs106.readFileSync(planPath, "utf-8");
|
|
116232
116362
|
const plan = JSON.parse(raw);
|
|
116233
116363
|
for (const phase of plan.phases ?? []) {
|
|
116234
116364
|
for (const task of phase.tasks ?? []) {
|
|
@@ -116330,7 +116460,7 @@ init_telemetry();
|
|
|
116330
116460
|
|
|
116331
116461
|
// src/turbo/lean/task-completion.ts
|
|
116332
116462
|
init_file_locks();
|
|
116333
|
-
import * as
|
|
116463
|
+
import * as fs107 from "node:fs";
|
|
116334
116464
|
import * as path137 from "node:path";
|
|
116335
116465
|
var _internals56 = {
|
|
116336
116466
|
listActiveLocks,
|
|
@@ -116363,13 +116493,13 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
|
116363
116493
|
let persisted = null;
|
|
116364
116494
|
try {
|
|
116365
116495
|
const statePath = path137.join(directory, ".swarm", "turbo-state.json");
|
|
116366
|
-
if (!
|
|
116496
|
+
if (!fs107.existsSync(statePath)) {
|
|
116367
116497
|
return {
|
|
116368
116498
|
ok: false,
|
|
116369
116499
|
reason: "Lean Turbo state file not found"
|
|
116370
116500
|
};
|
|
116371
116501
|
}
|
|
116372
|
-
const raw =
|
|
116502
|
+
const raw = fs107.readFileSync(statePath, "utf-8");
|
|
116373
116503
|
persisted = JSON.parse(raw);
|
|
116374
116504
|
} catch {
|
|
116375
116505
|
return {
|
|
@@ -116462,7 +116592,7 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
|
116462
116592
|
}
|
|
116463
116593
|
};
|
|
116464
116594
|
}
|
|
116465
|
-
if (!
|
|
116595
|
+
if (!fs107.existsSync(evidencePath)) {
|
|
116466
116596
|
return {
|
|
116467
116597
|
ok: false,
|
|
116468
116598
|
reason: `Lane ${lane.laneId} evidence file not found: ${evidencePath}`,
|
|
@@ -116491,7 +116621,7 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
|
116491
116621
|
let filesTouched = [];
|
|
116492
116622
|
try {
|
|
116493
116623
|
const planPath = path137.join(directory, ".swarm", "plan.json");
|
|
116494
|
-
const planRaw =
|
|
116624
|
+
const planRaw = fs107.readFileSync(planPath, "utf-8");
|
|
116495
116625
|
const plan = JSON.parse(planRaw);
|
|
116496
116626
|
for (const planPhase of plan.phases ?? []) {
|
|
116497
116627
|
for (const task of planPhase.tasks ?? []) {
|
|
@@ -116614,7 +116744,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
116614
116744
|
const resolvedDir2 = workingDirectory;
|
|
116615
116745
|
try {
|
|
116616
116746
|
const planPath = path138.join(resolvedDir2, ".swarm", "plan.json");
|
|
116617
|
-
const planRaw =
|
|
116747
|
+
const planRaw = fs108.readFileSync(planPath, "utf-8");
|
|
116618
116748
|
const plan = JSON.parse(planRaw);
|
|
116619
116749
|
for (const planPhase of plan.phases ?? []) {
|
|
116620
116750
|
for (const task of planPhase.tasks ?? []) {
|
|
@@ -116692,7 +116822,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
116692
116822
|
if (resolvedDir) {
|
|
116693
116823
|
try {
|
|
116694
116824
|
const planPath = path138.join(resolvedDir, ".swarm", "plan.json");
|
|
116695
|
-
const planRaw =
|
|
116825
|
+
const planRaw = fs108.readFileSync(planPath, "utf-8");
|
|
116696
116826
|
const plan = JSON.parse(planRaw);
|
|
116697
116827
|
for (const planPhase of plan.phases ?? []) {
|
|
116698
116828
|
for (const task of planPhase.tasks ?? []) {
|
|
@@ -116941,9 +117071,9 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
116941
117071
|
}
|
|
116942
117072
|
const resolvedDir = path138.resolve(normalizedDir);
|
|
116943
117073
|
try {
|
|
116944
|
-
const realPath =
|
|
117074
|
+
const realPath = fs108.realpathSync(resolvedDir);
|
|
116945
117075
|
const planPath = path138.join(realPath, ".swarm", "plan.json");
|
|
116946
|
-
if (!
|
|
117076
|
+
if (!fs108.existsSync(planPath)) {
|
|
116947
117077
|
return {
|
|
116948
117078
|
success: false,
|
|
116949
117079
|
message: `Invalid working_directory: plan not found in "${realPath}"`,
|
|
@@ -116973,8 +117103,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
116973
117103
|
directory = fallbackDir;
|
|
116974
117104
|
}
|
|
116975
117105
|
if (fallbackDir && directory !== fallbackDir) {
|
|
116976
|
-
const canonicalDir =
|
|
116977
|
-
const canonicalRoot =
|
|
117106
|
+
const canonicalDir = fs108.realpathSync(path138.resolve(directory));
|
|
117107
|
+
const canonicalRoot = fs108.realpathSync(path138.resolve(fallbackDir));
|
|
116978
117108
|
if (canonicalDir.startsWith(canonicalRoot + path138.sep)) {
|
|
116979
117109
|
return {
|
|
116980
117110
|
success: false,
|
|
@@ -116988,21 +117118,21 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
116988
117118
|
if (args2.status === "in_progress") {
|
|
116989
117119
|
try {
|
|
116990
117120
|
const evidencePath = path138.join(directory, ".swarm", "evidence", `${args2.task_id}.json`);
|
|
116991
|
-
|
|
116992
|
-
const fd =
|
|
117121
|
+
fs108.mkdirSync(path138.dirname(evidencePath), { recursive: true });
|
|
117122
|
+
const fd = fs108.openSync(evidencePath, "wx");
|
|
116993
117123
|
let writeOk = false;
|
|
116994
117124
|
try {
|
|
116995
|
-
|
|
117125
|
+
fs108.writeSync(fd, JSON.stringify({
|
|
116996
117126
|
taskId: args2.task_id,
|
|
116997
117127
|
required_gates: [],
|
|
116998
117128
|
gates: {}
|
|
116999
117129
|
}, null, 2));
|
|
117000
117130
|
writeOk = true;
|
|
117001
117131
|
} finally {
|
|
117002
|
-
|
|
117132
|
+
fs108.closeSync(fd);
|
|
117003
117133
|
if (!writeOk) {
|
|
117004
117134
|
try {
|
|
117005
|
-
|
|
117135
|
+
fs108.unlinkSync(evidencePath);
|
|
117006
117136
|
} catch {}
|
|
117007
117137
|
}
|
|
117008
117138
|
}
|
|
@@ -117013,7 +117143,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
117013
117143
|
let phaseRequiresReviewer = true;
|
|
117014
117144
|
try {
|
|
117015
117145
|
const planPath = path138.join(directory, ".swarm", "plan.json");
|
|
117016
|
-
const planRaw =
|
|
117146
|
+
const planRaw = fs108.readFileSync(planPath, "utf-8");
|
|
117017
117147
|
const plan = JSON.parse(planRaw);
|
|
117018
117148
|
const taskPhase = plan.phases.find((p) => p.tasks.some((t) => t.id === args2.task_id));
|
|
117019
117149
|
if (taskPhase?.required_agents && !taskPhase.required_agents.includes("reviewer")) {
|
|
@@ -117323,7 +117453,7 @@ init_utils2();
|
|
|
117323
117453
|
init_ledger();
|
|
117324
117454
|
init_manager();
|
|
117325
117455
|
init_create_tool();
|
|
117326
|
-
import
|
|
117456
|
+
import fs109 from "node:fs";
|
|
117327
117457
|
import path139 from "node:path";
|
|
117328
117458
|
function normalizeVerdict(verdict) {
|
|
117329
117459
|
switch (verdict) {
|
|
@@ -117385,10 +117515,10 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
117385
117515
|
}
|
|
117386
117516
|
const evidenceDir = path139.dirname(validatedPath);
|
|
117387
117517
|
try {
|
|
117388
|
-
await
|
|
117518
|
+
await fs109.promises.mkdir(evidenceDir, { recursive: true });
|
|
117389
117519
|
const tempPath = path139.join(evidenceDir, `.${filename}.tmp`);
|
|
117390
|
-
await
|
|
117391
|
-
await
|
|
117520
|
+
await fs109.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
117521
|
+
await fs109.promises.rename(tempPath, validatedPath);
|
|
117392
117522
|
let snapshotInfo;
|
|
117393
117523
|
let snapshotError;
|
|
117394
117524
|
let qaProfileLocked;
|
|
@@ -117481,7 +117611,7 @@ var write_drift_evidence = createSwarmTool({
|
|
|
117481
117611
|
// src/tools/write-final-council-evidence.ts
|
|
117482
117612
|
init_zod();
|
|
117483
117613
|
init_loader();
|
|
117484
|
-
import
|
|
117614
|
+
import fs110 from "node:fs";
|
|
117485
117615
|
import path140 from "node:path";
|
|
117486
117616
|
init_utils2();
|
|
117487
117617
|
init_manager();
|
|
@@ -117586,10 +117716,10 @@ async function executeWriteFinalCouncilEvidence(args2, directory) {
|
|
|
117586
117716
|
};
|
|
117587
117717
|
const evidenceDir = path140.dirname(validatedPath);
|
|
117588
117718
|
try {
|
|
117589
|
-
await
|
|
117719
|
+
await fs110.promises.mkdir(evidenceDir, { recursive: true });
|
|
117590
117720
|
const tempPath = path140.join(evidenceDir, `.${filename}.tmp`);
|
|
117591
|
-
await
|
|
117592
|
-
await
|
|
117721
|
+
await fs110.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
117722
|
+
await fs110.promises.rename(tempPath, validatedPath);
|
|
117593
117723
|
return JSON.stringify({
|
|
117594
117724
|
success: true,
|
|
117595
117725
|
phase: input.phase,
|
|
@@ -117645,7 +117775,7 @@ var write_final_council_evidence = createSwarmTool({
|
|
|
117645
117775
|
init_zod();
|
|
117646
117776
|
init_utils2();
|
|
117647
117777
|
init_create_tool();
|
|
117648
|
-
import
|
|
117778
|
+
import fs111 from "node:fs";
|
|
117649
117779
|
import path141 from "node:path";
|
|
117650
117780
|
function normalizeVerdict2(verdict) {
|
|
117651
117781
|
switch (verdict) {
|
|
@@ -117707,10 +117837,10 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
117707
117837
|
}
|
|
117708
117838
|
const evidenceDir = path141.dirname(validatedPath);
|
|
117709
117839
|
try {
|
|
117710
|
-
await
|
|
117840
|
+
await fs111.promises.mkdir(evidenceDir, { recursive: true });
|
|
117711
117841
|
const tempPath = path141.join(evidenceDir, `.${filename}.tmp`);
|
|
117712
|
-
await
|
|
117713
|
-
await
|
|
117842
|
+
await fs111.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
117843
|
+
await fs111.promises.rename(tempPath, validatedPath);
|
|
117714
117844
|
return JSON.stringify({
|
|
117715
117845
|
success: true,
|
|
117716
117846
|
phase,
|
|
@@ -117756,7 +117886,7 @@ var write_hallucination_evidence = createSwarmTool({
|
|
|
117756
117886
|
init_zod();
|
|
117757
117887
|
init_utils2();
|
|
117758
117888
|
init_create_tool();
|
|
117759
|
-
import
|
|
117889
|
+
import fs112 from "node:fs";
|
|
117760
117890
|
import path142 from "node:path";
|
|
117761
117891
|
function normalizeVerdict3(verdict) {
|
|
117762
117892
|
switch (verdict) {
|
|
@@ -117844,10 +117974,10 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
117844
117974
|
}
|
|
117845
117975
|
const evidenceDir = path142.dirname(validatedPath);
|
|
117846
117976
|
try {
|
|
117847
|
-
await
|
|
117977
|
+
await fs112.promises.mkdir(evidenceDir, { recursive: true });
|
|
117848
117978
|
const tempPath = path142.join(evidenceDir, `.${filename}.tmp`);
|
|
117849
|
-
await
|
|
117850
|
-
await
|
|
117979
|
+
await fs112.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
117980
|
+
await fs112.promises.rename(tempPath, validatedPath);
|
|
117851
117981
|
return JSON.stringify({
|
|
117852
117982
|
success: true,
|
|
117853
117983
|
phase,
|