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