opencode-swarm 6.29.1 → 6.29.3
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/README.md +40 -5
- package/dist/cli/index.js +2 -2
- package/dist/config/schema.d.ts +2 -2
- package/dist/hooks/incremental-verify.d.ts +16 -0
- package/dist/hooks/spawn-helper.d.ts +5 -0
- package/dist/hooks/spawn-helper.test.d.ts +1 -0
- package/dist/index.js +515 -328
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14217,7 +14217,7 @@ var init_evidence_schema = __esm(() => {
|
|
|
14217
14217
|
});
|
|
14218
14218
|
RetrospectiveEvidenceSchema = BaseEvidenceSchema.extend({
|
|
14219
14219
|
type: exports_external.literal("retrospective"),
|
|
14220
|
-
phase_number: exports_external.number().int().min(
|
|
14220
|
+
phase_number: exports_external.number().int().min(1).max(99),
|
|
14221
14221
|
total_tool_calls: exports_external.number().int().min(0).max(9999),
|
|
14222
14222
|
coder_revisions: exports_external.number().int().min(0).max(999),
|
|
14223
14223
|
reviewer_rejections: exports_external.number().int().min(0).max(999),
|
|
@@ -14882,7 +14882,7 @@ var init_schema = __esm(() => {
|
|
|
14882
14882
|
});
|
|
14883
14883
|
IncrementalVerifyConfigSchema = exports_external.object({
|
|
14884
14884
|
enabled: exports_external.boolean().default(true),
|
|
14885
|
-
command: exports_external.string().nullable().default(null),
|
|
14885
|
+
command: exports_external.union([exports_external.string(), exports_external.array(exports_external.string())]).nullable().default(null),
|
|
14886
14886
|
timeoutMs: exports_external.number().int().min(1000).max(300000).default(30000),
|
|
14887
14887
|
triggerAgents: exports_external.array(exports_external.string()).default(["coder"])
|
|
14888
14888
|
});
|
|
@@ -37601,11 +37601,11 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
37601
37601
|
throw toThrow;
|
|
37602
37602
|
}, "quit_");
|
|
37603
37603
|
var scriptDirectory = "";
|
|
37604
|
-
function locateFile(
|
|
37604
|
+
function locateFile(path46) {
|
|
37605
37605
|
if (Module["locateFile"]) {
|
|
37606
|
-
return Module["locateFile"](
|
|
37606
|
+
return Module["locateFile"](path46, scriptDirectory);
|
|
37607
37607
|
}
|
|
37608
|
-
return scriptDirectory +
|
|
37608
|
+
return scriptDirectory + path46;
|
|
37609
37609
|
}
|
|
37610
37610
|
__name(locateFile, "locateFile");
|
|
37611
37611
|
var readAsync, readBinary;
|
|
@@ -39353,7 +39353,7 @@ var init_runtime = __esm(() => {
|
|
|
39353
39353
|
});
|
|
39354
39354
|
|
|
39355
39355
|
// src/index.ts
|
|
39356
|
-
import * as
|
|
39356
|
+
import * as path56 from "path";
|
|
39357
39357
|
|
|
39358
39358
|
// src/agents/index.ts
|
|
39359
39359
|
init_config();
|
|
@@ -40183,6 +40183,7 @@ Activates when: user asks to "specify", "define requirements", "write a spec", o
|
|
|
40183
40183
|
- Refine \u2192 delegate to MODE: CLARIFY-SPEC
|
|
40184
40184
|
- If NO: proceed to generation (step 2)
|
|
40185
40185
|
- If this is called from the stale spec archival path (MODE: PLAN option 1) \u2014 archival was already completed; skip this check and proceed directly to generation (step 2)
|
|
40186
|
+
1b. Run CODEBASE REALITY CHECK for any codebase references mentioned by the user or implied by the feature. Skip if work is purely greenfield (no existing codebase to check). Report discrepancies before proceeding to explorer.
|
|
40186
40187
|
2. Delegate to \`{{AGENT_PREFIX}}explorer\` to scan the codebase for relevant context (existing patterns, related code, affected areas).
|
|
40187
40188
|
3. Delegate to \`{{AGENT_PREFIX}}sme\` for domain research on the feature area to surface known constraints, best practices, and integration concerns.
|
|
40188
40189
|
4. Generate \`.swarm/spec.md\` capturing:
|
|
@@ -40209,22 +40210,23 @@ Each requirement must be independently testable.
|
|
|
40209
40210
|
Prefer informed defaults over asking the user \u2014 use \`[NEEDS CLARIFICATION]\` only when uncertainty could change scope, security, or core behavior.
|
|
40210
40211
|
|
|
40211
40212
|
EXTERNAL PLAN IMPORT PATH \u2014 when the user provides an existing implementation plan (markdown content, pasted text, or a reference to a file):
|
|
40212
|
-
1.
|
|
40213
|
-
2.
|
|
40213
|
+
1. Run CODEBASE REALITY CHECK scoped to every file, function, API, and behavioral assumption in the provided plan. Report discrepancies to user before proceeding.
|
|
40214
|
+
2. Read and parse the provided plan content.
|
|
40215
|
+
3. Reverse-engineer \`.swarm/spec.md\` from the plan:
|
|
40214
40216
|
- Derive FR-### functional requirements from task descriptions
|
|
40215
40217
|
- Derive SC-### success criteria from acceptance criteria in tasks
|
|
40216
40218
|
- Identify user scenarios from the plan's phase/feature groupings
|
|
40217
40219
|
- Surface implicit assumptions as \`[NEEDS CLARIFICATION]\` markers
|
|
40218
|
-
|
|
40220
|
+
4. Validate the provided plan against swarm task format requirements:
|
|
40219
40221
|
- Every task should have FILE, TASK, CONSTRAINT, and ACCEPTANCE fields
|
|
40220
40222
|
- No task should touch more than 2 files
|
|
40221
40223
|
- No compound verbs in TASK lines ("implement X and add Y" = 2 tasks)
|
|
40222
40224
|
- Dependencies should be declared explicitly
|
|
40223
40225
|
- Phase structure should match \`.swarm/plan.md\` format
|
|
40224
|
-
|
|
40225
|
-
|
|
40226
|
+
5. Report gaps, format issues, and improvement suggestions to the user.
|
|
40227
|
+
6. Ask: "Should I also flesh out any areas that seem underspecified?"
|
|
40226
40228
|
- If yes: delegate to \`{{AGENT_PREFIX}}sme\` for targeted research on weak areas, then propose specific improvements.
|
|
40227
|
-
|
|
40229
|
+
7. Output: both a \`.swarm/spec.md\` (extracted from the plan) and a validated version of the user's plan.
|
|
40228
40230
|
|
|
40229
40231
|
EXTERNAL PLAN RULES:
|
|
40230
40232
|
- Surface ALL changes as suggestions \u2014 do not silently rewrite the user's plan.
|
|
@@ -40327,6 +40329,34 @@ User directives carried forward: {list any persistent directives}
|
|
|
40327
40329
|
|
|
40328
40330
|
This briefing is a HARD REQUIREMENT for ALL phases. Skipping it is a process violation.
|
|
40329
40331
|
|
|
40332
|
+
### CODEBASE REALITY CHECK (Required Before Speccing or Planning)
|
|
40333
|
+
|
|
40334
|
+
Before any spec generation, plan creation, or plan ingestion begins, the Architect must dispatch the Explorer agent in targeted, scoped chunks \u2014 one per logical area of the codebase referenced by the work (e.g., per module, per hook, per config surface). Each chunk must be explored with full depth rather than a broad surface pass.
|
|
40335
|
+
|
|
40336
|
+
For each scoped chunk, Explorer must determine:
|
|
40337
|
+
- Does this file/module/function already exist?
|
|
40338
|
+
- If it exists, what is its current state? Does it already implement any part of what the plan or spec describes?
|
|
40339
|
+
- Is the plan's or user's assumption about the current state accurate? Flag any discrepancy between what is expected and what actually exists.
|
|
40340
|
+
- Has any portion of this work already been applied (partially or fully) in a prior session or commit?
|
|
40341
|
+
|
|
40342
|
+
Explorer outputs a CODEBASE REALITY REPORT before any other agent proceeds. The report must list every referenced item with one of:
|
|
40343
|
+
NOT STARTED | PARTIALLY DONE | ALREADY COMPLETE | ASSUMPTION INCORRECT
|
|
40344
|
+
|
|
40345
|
+
Format:
|
|
40346
|
+
REALITY CHECK: [N] references verified, [M] discrepancies found.
|
|
40347
|
+
\u2713 src/hooks/incremental-verify.ts \u2014 exists, line 69 confirmed Bun.spawn
|
|
40348
|
+
\u2717 src/services/status-service.ts \u2014 ASSUMPTION INCORRECT: compactionCount is no longer hardcoded (fixed in v6.29.1)
|
|
40349
|
+
\u2713 src/config/evidence-schema.ts:107 \u2014 confirmed phase_number min(0)
|
|
40350
|
+
|
|
40351
|
+
No implementation agent (coder, reviewer, test-engineer) may begin until this report is finalized.
|
|
40352
|
+
|
|
40353
|
+
This check fires automatically in:
|
|
40354
|
+
- MODE: SPECIFY \u2014 before explorer dispatch for context (step 2)
|
|
40355
|
+
- MODE: PLAN \u2014 before plan generation or validation
|
|
40356
|
+
- EXTERNAL PLAN IMPORT PATH \u2014 before parsing the provided plan
|
|
40357
|
+
|
|
40358
|
+
GREENFIELD EXEMPTION: If the work is purely greenfield (new project, no existing codebase references), skip this check.
|
|
40359
|
+
|
|
40330
40360
|
### MODE: PLAN
|
|
40331
40361
|
|
|
40332
40362
|
SPEC GATE (soft \u2014 check before planning):
|
|
@@ -40356,6 +40386,8 @@ SPEC GATE (soft \u2014 check before planning):
|
|
|
40356
40386
|
|
|
40357
40387
|
This is a SOFT gate. When the user chooses "Skip and plan directly", proceed to the steps below exactly as before \u2014 do NOT modify any planning behavior.
|
|
40358
40388
|
|
|
40389
|
+
Run CODEBASE REALITY CHECK scoped to codebase elements referenced in spec.md or user constraints. Discrepancies must be reflected in the generated plan.
|
|
40390
|
+
|
|
40359
40391
|
Use the \`save_plan\` tool to create the implementation plan. Required parameters:
|
|
40360
40392
|
- \`title\`: The real project name from the spec (NOT a placeholder like [Project])
|
|
40361
40393
|
- \`swarm_id\`: The swarm identifier (e.g. "mega", "local", "paid")
|
|
@@ -45509,6 +45541,58 @@ async function checkSteeringDirectives(directory) {
|
|
|
45509
45541
|
};
|
|
45510
45542
|
}
|
|
45511
45543
|
}
|
|
45544
|
+
async function checkCurator(directory) {
|
|
45545
|
+
try {
|
|
45546
|
+
const config3 = loadPluginConfig(directory);
|
|
45547
|
+
if (!config3.curator?.enabled) {
|
|
45548
|
+
return {
|
|
45549
|
+
name: "Curator",
|
|
45550
|
+
status: "\u2705",
|
|
45551
|
+
detail: "Disabled (enable via curator.enabled)"
|
|
45552
|
+
};
|
|
45553
|
+
}
|
|
45554
|
+
const summaryPath = path16.join(directory, ".swarm/curator-summary.json");
|
|
45555
|
+
if (!existsSync6(summaryPath)) {
|
|
45556
|
+
return {
|
|
45557
|
+
name: "Curator",
|
|
45558
|
+
status: "\u2705",
|
|
45559
|
+
detail: "Enabled, no summary yet (waiting for first phase)"
|
|
45560
|
+
};
|
|
45561
|
+
}
|
|
45562
|
+
try {
|
|
45563
|
+
const content = readFileSync4(summaryPath, "utf-8");
|
|
45564
|
+
const parsed = JSON.parse(content);
|
|
45565
|
+
if (typeof parsed.schema_version !== "number" || parsed.schema_version !== 1) {
|
|
45566
|
+
return {
|
|
45567
|
+
name: "Curator",
|
|
45568
|
+
status: "\u274C",
|
|
45569
|
+
detail: `curator-summary.json has invalid schema_version (expected 1, got ${JSON.stringify(parsed.schema_version)})`
|
|
45570
|
+
};
|
|
45571
|
+
}
|
|
45572
|
+
const phaseInfo = parsed.last_phase_covered !== undefined ? `phase ${parsed.last_phase_covered}` : "unknown phase";
|
|
45573
|
+
const timeInfo = parsed.last_updated ? `, updated ${parsed.last_updated}` : "";
|
|
45574
|
+
return {
|
|
45575
|
+
name: "Curator",
|
|
45576
|
+
status: "\u2705",
|
|
45577
|
+
detail: `Summary present \u2014 covering ${phaseInfo}${timeInfo}`
|
|
45578
|
+
};
|
|
45579
|
+
} catch (err2) {
|
|
45580
|
+
const message = err2 instanceof Error ? err2.message : "Unknown error";
|
|
45581
|
+
return {
|
|
45582
|
+
name: "Curator",
|
|
45583
|
+
status: "\u274C",
|
|
45584
|
+
detail: `curator-summary.json is corrupt or invalid: ${message}`
|
|
45585
|
+
};
|
|
45586
|
+
}
|
|
45587
|
+
} catch (err2) {
|
|
45588
|
+
const message = err2 instanceof Error ? err2.message : "Unknown error";
|
|
45589
|
+
return {
|
|
45590
|
+
name: "Curator",
|
|
45591
|
+
status: "\u274C",
|
|
45592
|
+
detail: `Could not check curator state: ${message}`
|
|
45593
|
+
};
|
|
45594
|
+
}
|
|
45595
|
+
}
|
|
45512
45596
|
async function getDiagnoseData(directory) {
|
|
45513
45597
|
const checks5 = [];
|
|
45514
45598
|
const plan = await loadPlanJsonOnly(directory);
|
|
@@ -45613,6 +45697,7 @@ async function getDiagnoseData(directory) {
|
|
|
45613
45697
|
checks5.push(await checkCheckpointManifest(directory));
|
|
45614
45698
|
checks5.push(await checkEventStreamIntegrity(directory));
|
|
45615
45699
|
checks5.push(await checkSteeringDirectives(directory));
|
|
45700
|
+
checks5.push(await checkCurator(directory));
|
|
45616
45701
|
const passCount = checks5.filter((c) => c.status === "\u2705").length;
|
|
45617
45702
|
const totalCount = checks5.length;
|
|
45618
45703
|
const allPassed = passCount === totalCount;
|
|
@@ -52432,53 +52517,111 @@ function createDarkMatterDetectorHook(directory) {
|
|
|
52432
52517
|
// src/hooks/incremental-verify.ts
|
|
52433
52518
|
import * as fs20 from "fs";
|
|
52434
52519
|
import * as path32 from "path";
|
|
52520
|
+
|
|
52521
|
+
// src/hooks/spawn-helper.ts
|
|
52522
|
+
import { spawn } from "child_process";
|
|
52523
|
+
function spawnAsync(command, cwd, timeoutMs) {
|
|
52524
|
+
return new Promise((resolve11) => {
|
|
52525
|
+
try {
|
|
52526
|
+
const [cmd, ...args2] = command;
|
|
52527
|
+
const proc = spawn(cmd, args2, { cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
52528
|
+
let stdout = "";
|
|
52529
|
+
let stderr = "";
|
|
52530
|
+
let done = false;
|
|
52531
|
+
proc.stdout.on("data", (d) => {
|
|
52532
|
+
stdout += d;
|
|
52533
|
+
});
|
|
52534
|
+
proc.stderr.on("data", (d) => {
|
|
52535
|
+
stderr += d;
|
|
52536
|
+
});
|
|
52537
|
+
const timer = setTimeout(() => {
|
|
52538
|
+
if (done)
|
|
52539
|
+
return;
|
|
52540
|
+
done = true;
|
|
52541
|
+
try {
|
|
52542
|
+
proc.stdout.destroy();
|
|
52543
|
+
} catch {}
|
|
52544
|
+
try {
|
|
52545
|
+
proc.stderr.destroy();
|
|
52546
|
+
} catch {}
|
|
52547
|
+
try {
|
|
52548
|
+
proc.kill();
|
|
52549
|
+
} catch {}
|
|
52550
|
+
resolve11(null);
|
|
52551
|
+
}, timeoutMs);
|
|
52552
|
+
proc.on("close", (code) => {
|
|
52553
|
+
if (done)
|
|
52554
|
+
return;
|
|
52555
|
+
done = true;
|
|
52556
|
+
clearTimeout(timer);
|
|
52557
|
+
resolve11({ exitCode: code ?? 1, stdout, stderr });
|
|
52558
|
+
});
|
|
52559
|
+
proc.on("error", () => {
|
|
52560
|
+
if (done)
|
|
52561
|
+
return;
|
|
52562
|
+
done = true;
|
|
52563
|
+
clearTimeout(timer);
|
|
52564
|
+
resolve11(null);
|
|
52565
|
+
});
|
|
52566
|
+
} catch {
|
|
52567
|
+
resolve11(null);
|
|
52568
|
+
}
|
|
52569
|
+
});
|
|
52570
|
+
}
|
|
52571
|
+
|
|
52572
|
+
// src/hooks/incremental-verify.ts
|
|
52573
|
+
var emittedSkipAdvisories = new Set;
|
|
52435
52574
|
function detectTypecheckCommand(projectDir) {
|
|
52436
52575
|
const pkgPath = path32.join(projectDir, "package.json");
|
|
52437
|
-
if (
|
|
52438
|
-
|
|
52439
|
-
|
|
52440
|
-
|
|
52441
|
-
|
|
52442
|
-
|
|
52443
|
-
|
|
52444
|
-
|
|
52445
|
-
|
|
52446
|
-
|
|
52447
|
-
|
|
52448
|
-
|
|
52449
|
-
|
|
52450
|
-
|
|
52576
|
+
if (fs20.existsSync(pkgPath)) {
|
|
52577
|
+
try {
|
|
52578
|
+
const pkg = JSON.parse(fs20.readFileSync(pkgPath, "utf8"));
|
|
52579
|
+
const scripts = pkg.scripts;
|
|
52580
|
+
if (scripts?.typecheck)
|
|
52581
|
+
return { command: ["bun", "run", "typecheck"], language: "typescript" };
|
|
52582
|
+
if (scripts?.["type-check"])
|
|
52583
|
+
return {
|
|
52584
|
+
command: ["bun", "run", "type-check"],
|
|
52585
|
+
language: "typescript"
|
|
52586
|
+
};
|
|
52587
|
+
const deps = {
|
|
52588
|
+
...pkg.dependencies,
|
|
52589
|
+
...pkg.devDependencies
|
|
52590
|
+
};
|
|
52591
|
+
if (!deps?.typescript && !fs20.existsSync(path32.join(projectDir, "tsconfig.json"))) {}
|
|
52592
|
+
const hasTSMarkers = deps?.typescript || fs20.existsSync(path32.join(projectDir, "tsconfig.json"));
|
|
52593
|
+
if (hasTSMarkers) {
|
|
52594
|
+
return { command: ["npx", "tsc", "--noEmit"], language: "typescript" };
|
|
52595
|
+
}
|
|
52596
|
+
} catch {
|
|
52451
52597
|
return null;
|
|
52452
52598
|
}
|
|
52453
|
-
return ["npx", "tsc", "--noEmit"];
|
|
52454
|
-
} catch {
|
|
52455
|
-
return null;
|
|
52456
52599
|
}
|
|
52457
|
-
|
|
52458
|
-
|
|
52600
|
+
if (fs20.existsSync(path32.join(projectDir, "go.mod"))) {
|
|
52601
|
+
return { command: ["go", "vet", "./..."], language: "go" };
|
|
52602
|
+
}
|
|
52603
|
+
if (fs20.existsSync(path32.join(projectDir, "Cargo.toml"))) {
|
|
52604
|
+
return { command: ["cargo", "check"], language: "rust" };
|
|
52605
|
+
}
|
|
52606
|
+
if (fs20.existsSync(path32.join(projectDir, "pyproject.toml")) || fs20.existsSync(path32.join(projectDir, "requirements.txt")) || fs20.existsSync(path32.join(projectDir, "setup.py"))) {
|
|
52607
|
+
return { command: null, language: "python" };
|
|
52608
|
+
}
|
|
52459
52609
|
try {
|
|
52460
|
-
const
|
|
52461
|
-
|
|
52462
|
-
|
|
52463
|
-
|
|
52464
|
-
|
|
52465
|
-
|
|
52466
|
-
try {
|
|
52467
|
-
proc.kill();
|
|
52468
|
-
} catch {}
|
|
52469
|
-
}, timeoutMs);
|
|
52470
|
-
try {
|
|
52471
|
-
const [exitCode, stderr] = await Promise.all([
|
|
52472
|
-
proc.exited,
|
|
52473
|
-
new Response(proc.stderr).text()
|
|
52474
|
-
]);
|
|
52475
|
-
return { exitCode, stderr };
|
|
52476
|
-
} finally {
|
|
52477
|
-
clearTimeout(timeoutHandle);
|
|
52610
|
+
const entries = fs20.readdirSync(projectDir);
|
|
52611
|
+
if (entries.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"))) {
|
|
52612
|
+
return {
|
|
52613
|
+
command: ["dotnet", "build", "--no-restore"],
|
|
52614
|
+
language: "csharp"
|
|
52615
|
+
};
|
|
52478
52616
|
}
|
|
52479
|
-
} catch {
|
|
52617
|
+
} catch {}
|
|
52618
|
+
return null;
|
|
52619
|
+
}
|
|
52620
|
+
async function runWithTimeout(command, cwd, timeoutMs) {
|
|
52621
|
+
const result = await spawnAsync(command, cwd, timeoutMs);
|
|
52622
|
+
if (result === null)
|
|
52480
52623
|
return null;
|
|
52481
|
-
}
|
|
52624
|
+
return { exitCode: result.exitCode, stderr: result.stderr };
|
|
52482
52625
|
}
|
|
52483
52626
|
function createIncrementalVerifyHook(config3, projectDir, injectMessage) {
|
|
52484
52627
|
return {
|
|
@@ -52493,10 +52636,27 @@ function createIncrementalVerifyHook(config3, projectDir, injectMessage) {
|
|
|
52493
52636
|
if (!config3.triggerAgents.includes(agentName) && !config3.triggerAgents.includes(subagentType)) {
|
|
52494
52637
|
return;
|
|
52495
52638
|
}
|
|
52496
|
-
|
|
52497
|
-
if (
|
|
52639
|
+
let commandToRun = null;
|
|
52640
|
+
if (config3.command != null) {
|
|
52641
|
+
commandToRun = Array.isArray(config3.command) ? config3.command : config3.command.split(" ");
|
|
52642
|
+
} else {
|
|
52643
|
+
const detected = detectTypecheckCommand(projectDir);
|
|
52644
|
+
if (detected === null) {
|
|
52645
|
+
return;
|
|
52646
|
+
}
|
|
52647
|
+
if (detected.command === null) {
|
|
52648
|
+
const dedupKey = `${input.sessionID}:${detected.language}`;
|
|
52649
|
+
if (!emittedSkipAdvisories.has(dedupKey)) {
|
|
52650
|
+
emittedSkipAdvisories.add(dedupKey);
|
|
52651
|
+
injectMessage(input.sessionID, `POST-CODER CHECK SKIPPED: ${detected.language} project detected but no default checker available. Set incremental_verify.command in .swarm/config.json to enable.`);
|
|
52652
|
+
}
|
|
52653
|
+
return;
|
|
52654
|
+
}
|
|
52655
|
+
commandToRun = detected.command;
|
|
52656
|
+
}
|
|
52657
|
+
if (commandToRun === null)
|
|
52498
52658
|
return;
|
|
52499
|
-
const result = await runWithTimeout(
|
|
52659
|
+
const result = await runWithTimeout(commandToRun, projectDir, config3.timeoutMs);
|
|
52500
52660
|
if (result === null) {
|
|
52501
52661
|
return;
|
|
52502
52662
|
}
|
|
@@ -53422,6 +53582,8 @@ ${cachedInjectionText}`;
|
|
|
53422
53582
|
}
|
|
53423
53583
|
|
|
53424
53584
|
// src/hooks/slop-detector.ts
|
|
53585
|
+
import * as fs22 from "fs";
|
|
53586
|
+
import * as path35 from "path";
|
|
53425
53587
|
var WRITE_EDIT_TOOLS = new Set([
|
|
53426
53588
|
"write",
|
|
53427
53589
|
"edit",
|
|
@@ -53432,7 +53594,7 @@ function countMatches(text, pattern) {
|
|
|
53432
53594
|
return (text.match(pattern) ?? []).length;
|
|
53433
53595
|
}
|
|
53434
53596
|
function checkAbstractionBloat(content, threshold) {
|
|
53435
|
-
const newClasses = countMatches(content, /^\+.*\
|
|
53597
|
+
const newClasses = countMatches(content, /^\+.*\b(?:class|struct|impl)\s+\w+/gm);
|
|
53436
53598
|
if (newClasses >= threshold) {
|
|
53437
53599
|
return {
|
|
53438
53600
|
type: "abstraction_bloat",
|
|
@@ -53442,8 +53604,8 @@ function checkAbstractionBloat(content, threshold) {
|
|
|
53442
53604
|
return null;
|
|
53443
53605
|
}
|
|
53444
53606
|
function checkCommentStrip(content, threshold) {
|
|
53445
|
-
const removedComments = countMatches(content, /^-\s
|
|
53446
|
-
const addedComments = countMatches(content, /^\+\s
|
|
53607
|
+
const removedComments = countMatches(content, /^-\s*(?:\/[/*]|#|--)/gm);
|
|
53608
|
+
const addedComments = countMatches(content, /^\+\s*(?:\/[/*]|#|--)/gm);
|
|
53447
53609
|
if (removedComments >= threshold && addedComments === 0) {
|
|
53448
53610
|
return {
|
|
53449
53611
|
type: "comment_strip",
|
|
@@ -53463,8 +53625,33 @@ function checkBoilerplateExplosion(content, taskDescription, threshold) {
|
|
|
53463
53625
|
}
|
|
53464
53626
|
return null;
|
|
53465
53627
|
}
|
|
53466
|
-
|
|
53467
|
-
const
|
|
53628
|
+
function walkFiles(dir, exts, deadline) {
|
|
53629
|
+
const results = [];
|
|
53630
|
+
try {
|
|
53631
|
+
for (const entry of fs22.readdirSync(dir, { withFileTypes: true })) {
|
|
53632
|
+
if (deadline !== undefined && Date.now() > deadline)
|
|
53633
|
+
break;
|
|
53634
|
+
if (entry.isSymbolicLink())
|
|
53635
|
+
continue;
|
|
53636
|
+
const full = path35.join(dir, entry.name);
|
|
53637
|
+
if (entry.isDirectory()) {
|
|
53638
|
+
if (entry.name === "node_modules" || entry.name === ".git")
|
|
53639
|
+
continue;
|
|
53640
|
+
results.push(...walkFiles(full, exts, deadline));
|
|
53641
|
+
} else if (entry.isFile()) {
|
|
53642
|
+
if (exts.some((ext) => entry.name.endsWith(ext))) {
|
|
53643
|
+
results.push(full);
|
|
53644
|
+
}
|
|
53645
|
+
}
|
|
53646
|
+
}
|
|
53647
|
+
} catch {}
|
|
53648
|
+
return results;
|
|
53649
|
+
}
|
|
53650
|
+
function checkDeadExports(content, projectDir, startTime) {
|
|
53651
|
+
const hasPackageJson = fs22.existsSync(path35.join(projectDir, "package.json"));
|
|
53652
|
+
if (!hasPackageJson)
|
|
53653
|
+
return null;
|
|
53654
|
+
const exportMatches = content.matchAll(/^\+(?:export)\s+(?:function|class|const|type|interface)\s+(\w{3,})/gm);
|
|
53468
53655
|
const newExports = [];
|
|
53469
53656
|
for (const match of exportMatches) {
|
|
53470
53657
|
if (match[1])
|
|
@@ -53472,19 +53659,19 @@ async function checkDeadExports(content, projectDir, startTime) {
|
|
|
53472
53659
|
}
|
|
53473
53660
|
if (newExports.length === 0)
|
|
53474
53661
|
return null;
|
|
53662
|
+
const files = walkFiles(projectDir, [".ts", ".tsx", ".js", ".jsx"], startTime + 480);
|
|
53475
53663
|
const deadExports = [];
|
|
53476
53664
|
for (const name2 of newExports) {
|
|
53477
53665
|
if (Date.now() - startTime > 480)
|
|
53478
53666
|
break;
|
|
53479
53667
|
try {
|
|
53480
53668
|
const importPattern = new RegExp(`\\bimport\\b[^;]*\\b${name2}\\b`, "g");
|
|
53481
|
-
const glob = new Bun.Glob(`src/**/*.ts`);
|
|
53482
53669
|
let found = false;
|
|
53483
|
-
for
|
|
53670
|
+
for (const file3 of files) {
|
|
53484
53671
|
if (found || Date.now() - startTime > 480)
|
|
53485
53672
|
break;
|
|
53486
53673
|
try {
|
|
53487
|
-
const text =
|
|
53674
|
+
const text = fs22.readFileSync(file3, "utf-8");
|
|
53488
53675
|
if (importPattern.test(text))
|
|
53489
53676
|
found = true;
|
|
53490
53677
|
importPattern.lastIndex = 0;
|
|
@@ -53538,7 +53725,7 @@ function createSlopDetectorHook(config3, projectDir, injectSystemMessage) {
|
|
|
53538
53725
|
} catch {}
|
|
53539
53726
|
if (Date.now() - startTime < 400) {
|
|
53540
53727
|
try {
|
|
53541
|
-
const dead =
|
|
53728
|
+
const dead = checkDeadExports(content, projectDir, startTime);
|
|
53542
53729
|
if (dead)
|
|
53543
53730
|
findings.push(dead);
|
|
53544
53731
|
} catch {}
|
|
@@ -53557,7 +53744,7 @@ Review before proceeding.`;
|
|
|
53557
53744
|
|
|
53558
53745
|
// src/hooks/steering-consumed.ts
|
|
53559
53746
|
init_utils2();
|
|
53560
|
-
import * as
|
|
53747
|
+
import * as fs23 from "fs";
|
|
53561
53748
|
function recordSteeringConsumed(directory, directiveId) {
|
|
53562
53749
|
try {
|
|
53563
53750
|
const eventsPath = validateSwarmPath(directory, "events.jsonl");
|
|
@@ -53566,7 +53753,7 @@ function recordSteeringConsumed(directory, directiveId) {
|
|
|
53566
53753
|
directiveId,
|
|
53567
53754
|
timestamp: new Date().toISOString()
|
|
53568
53755
|
};
|
|
53569
|
-
|
|
53756
|
+
fs23.appendFileSync(eventsPath, `${JSON.stringify(event)}
|
|
53570
53757
|
`, "utf-8");
|
|
53571
53758
|
} catch {}
|
|
53572
53759
|
}
|
|
@@ -53611,7 +53798,7 @@ init_config_doctor();
|
|
|
53611
53798
|
|
|
53612
53799
|
// src/session/snapshot-reader.ts
|
|
53613
53800
|
init_utils2();
|
|
53614
|
-
import
|
|
53801
|
+
import path36 from "path";
|
|
53615
53802
|
var VALID_TASK_WORKFLOW_STATES = [
|
|
53616
53803
|
"idle",
|
|
53617
53804
|
"coder_delegated",
|
|
@@ -53736,7 +53923,7 @@ function rehydrateState(snapshot) {
|
|
|
53736
53923
|
async function reconcileTaskStatesFromPlan(directory) {
|
|
53737
53924
|
let raw;
|
|
53738
53925
|
try {
|
|
53739
|
-
raw = await Bun.file(
|
|
53926
|
+
raw = await Bun.file(path36.join(directory, ".swarm/plan.json")).text();
|
|
53740
53927
|
} catch {
|
|
53741
53928
|
return;
|
|
53742
53929
|
}
|
|
@@ -53958,8 +54145,8 @@ var build_check = createSwarmTool({
|
|
|
53958
54145
|
// src/tools/check-gate-status.ts
|
|
53959
54146
|
init_dist();
|
|
53960
54147
|
init_create_tool();
|
|
53961
|
-
import * as
|
|
53962
|
-
import * as
|
|
54148
|
+
import * as fs24 from "fs";
|
|
54149
|
+
import * as path37 from "path";
|
|
53963
54150
|
var EVIDENCE_DIR = ".swarm/evidence";
|
|
53964
54151
|
var TASK_ID_PATTERN2 = /^\d+\.\d+(\.\d+)*$/;
|
|
53965
54152
|
function isValidTaskId3(taskId) {
|
|
@@ -53976,18 +54163,18 @@ function isValidTaskId3(taskId) {
|
|
|
53976
54163
|
return TASK_ID_PATTERN2.test(taskId);
|
|
53977
54164
|
}
|
|
53978
54165
|
function isPathWithinSwarm(filePath, workspaceRoot) {
|
|
53979
|
-
const normalizedWorkspace =
|
|
53980
|
-
const swarmPath =
|
|
53981
|
-
const normalizedPath =
|
|
54166
|
+
const normalizedWorkspace = path37.resolve(workspaceRoot);
|
|
54167
|
+
const swarmPath = path37.join(normalizedWorkspace, ".swarm", "evidence");
|
|
54168
|
+
const normalizedPath = path37.resolve(filePath);
|
|
53982
54169
|
return normalizedPath.startsWith(swarmPath);
|
|
53983
54170
|
}
|
|
53984
54171
|
function readEvidenceFile(evidencePath) {
|
|
53985
|
-
if (!
|
|
54172
|
+
if (!fs24.existsSync(evidencePath)) {
|
|
53986
54173
|
return null;
|
|
53987
54174
|
}
|
|
53988
54175
|
let content;
|
|
53989
54176
|
try {
|
|
53990
|
-
content =
|
|
54177
|
+
content = fs24.readFileSync(evidencePath, "utf-8");
|
|
53991
54178
|
} catch {
|
|
53992
54179
|
return null;
|
|
53993
54180
|
}
|
|
@@ -54039,7 +54226,7 @@ var check_gate_status = createSwarmTool({
|
|
|
54039
54226
|
};
|
|
54040
54227
|
return JSON.stringify(errorResult, null, 2);
|
|
54041
54228
|
}
|
|
54042
|
-
const evidencePath =
|
|
54229
|
+
const evidencePath = path37.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
|
|
54043
54230
|
if (!isPathWithinSwarm(evidencePath, directory)) {
|
|
54044
54231
|
const errorResult = {
|
|
54045
54232
|
taskId: taskIdInput,
|
|
@@ -54099,8 +54286,8 @@ var check_gate_status = createSwarmTool({
|
|
|
54099
54286
|
init_tool();
|
|
54100
54287
|
init_create_tool();
|
|
54101
54288
|
import { spawnSync } from "child_process";
|
|
54102
|
-
import * as
|
|
54103
|
-
import * as
|
|
54289
|
+
import * as fs25 from "fs";
|
|
54290
|
+
import * as path38 from "path";
|
|
54104
54291
|
var CHECKPOINT_LOG_PATH = ".swarm/checkpoints.json";
|
|
54105
54292
|
var MAX_LABEL_LENGTH = 100;
|
|
54106
54293
|
var GIT_TIMEOUT_MS = 30000;
|
|
@@ -54151,13 +54338,13 @@ function validateLabel(label) {
|
|
|
54151
54338
|
return null;
|
|
54152
54339
|
}
|
|
54153
54340
|
function getCheckpointLogPath(directory) {
|
|
54154
|
-
return
|
|
54341
|
+
return path38.join(directory, CHECKPOINT_LOG_PATH);
|
|
54155
54342
|
}
|
|
54156
54343
|
function readCheckpointLog(directory) {
|
|
54157
54344
|
const logPath = getCheckpointLogPath(directory);
|
|
54158
54345
|
try {
|
|
54159
|
-
if (
|
|
54160
|
-
const content =
|
|
54346
|
+
if (fs25.existsSync(logPath)) {
|
|
54347
|
+
const content = fs25.readFileSync(logPath, "utf-8");
|
|
54161
54348
|
const parsed = JSON.parse(content);
|
|
54162
54349
|
if (!parsed.checkpoints || !Array.isArray(parsed.checkpoints)) {
|
|
54163
54350
|
return { version: 1, checkpoints: [] };
|
|
@@ -54169,13 +54356,13 @@ function readCheckpointLog(directory) {
|
|
|
54169
54356
|
}
|
|
54170
54357
|
function writeCheckpointLog(log2, directory) {
|
|
54171
54358
|
const logPath = getCheckpointLogPath(directory);
|
|
54172
|
-
const dir =
|
|
54173
|
-
if (!
|
|
54174
|
-
|
|
54359
|
+
const dir = path38.dirname(logPath);
|
|
54360
|
+
if (!fs25.existsSync(dir)) {
|
|
54361
|
+
fs25.mkdirSync(dir, { recursive: true });
|
|
54175
54362
|
}
|
|
54176
54363
|
const tempPath = `${logPath}.tmp`;
|
|
54177
|
-
|
|
54178
|
-
|
|
54364
|
+
fs25.writeFileSync(tempPath, JSON.stringify(log2, null, 2), "utf-8");
|
|
54365
|
+
fs25.renameSync(tempPath, logPath);
|
|
54179
54366
|
}
|
|
54180
54367
|
function gitExec(args2) {
|
|
54181
54368
|
const result = spawnSync("git", args2, {
|
|
@@ -54376,8 +54563,8 @@ var checkpoint = createSwarmTool({
|
|
|
54376
54563
|
// src/tools/complexity-hotspots.ts
|
|
54377
54564
|
init_dist();
|
|
54378
54565
|
init_create_tool();
|
|
54379
|
-
import * as
|
|
54380
|
-
import * as
|
|
54566
|
+
import * as fs26 from "fs";
|
|
54567
|
+
import * as path39 from "path";
|
|
54381
54568
|
var MAX_FILE_SIZE_BYTES2 = 256 * 1024;
|
|
54382
54569
|
var DEFAULT_DAYS = 90;
|
|
54383
54570
|
var DEFAULT_TOP_N = 20;
|
|
@@ -54506,11 +54693,11 @@ function estimateComplexity(content) {
|
|
|
54506
54693
|
}
|
|
54507
54694
|
function getComplexityForFile(filePath) {
|
|
54508
54695
|
try {
|
|
54509
|
-
const stat2 =
|
|
54696
|
+
const stat2 = fs26.statSync(filePath);
|
|
54510
54697
|
if (stat2.size > MAX_FILE_SIZE_BYTES2) {
|
|
54511
54698
|
return null;
|
|
54512
54699
|
}
|
|
54513
|
-
const content =
|
|
54700
|
+
const content = fs26.readFileSync(filePath, "utf-8");
|
|
54514
54701
|
return estimateComplexity(content);
|
|
54515
54702
|
} catch {
|
|
54516
54703
|
return null;
|
|
@@ -54521,7 +54708,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
54521
54708
|
const extSet = new Set(extensions.map((e) => e.startsWith(".") ? e : `.${e}`));
|
|
54522
54709
|
const filteredChurn = new Map;
|
|
54523
54710
|
for (const [file3, count] of churnMap) {
|
|
54524
|
-
const ext =
|
|
54711
|
+
const ext = path39.extname(file3).toLowerCase();
|
|
54525
54712
|
if (extSet.has(ext)) {
|
|
54526
54713
|
filteredChurn.set(file3, count);
|
|
54527
54714
|
}
|
|
@@ -54531,8 +54718,8 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
54531
54718
|
let analyzedFiles = 0;
|
|
54532
54719
|
for (const [file3, churnCount] of filteredChurn) {
|
|
54533
54720
|
let fullPath = file3;
|
|
54534
|
-
if (!
|
|
54535
|
-
fullPath =
|
|
54721
|
+
if (!fs26.existsSync(fullPath)) {
|
|
54722
|
+
fullPath = path39.join(cwd, file3);
|
|
54536
54723
|
}
|
|
54537
54724
|
const complexity = getComplexityForFile(fullPath);
|
|
54538
54725
|
if (complexity !== null) {
|
|
@@ -54679,8 +54866,8 @@ var complexity_hotspots = createSwarmTool({
|
|
|
54679
54866
|
});
|
|
54680
54867
|
// src/tools/declare-scope.ts
|
|
54681
54868
|
init_tool();
|
|
54682
|
-
import * as
|
|
54683
|
-
import * as
|
|
54869
|
+
import * as fs27 from "fs";
|
|
54870
|
+
import * as path40 from "path";
|
|
54684
54871
|
init_create_tool();
|
|
54685
54872
|
function validateTaskIdFormat(taskId) {
|
|
54686
54873
|
const taskIdPattern = /^\d+\.\d+(\.\d+)*$/;
|
|
@@ -54759,8 +54946,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
54759
54946
|
};
|
|
54760
54947
|
}
|
|
54761
54948
|
}
|
|
54762
|
-
normalizedDir =
|
|
54763
|
-
const pathParts = normalizedDir.split(
|
|
54949
|
+
normalizedDir = path40.normalize(args2.working_directory);
|
|
54950
|
+
const pathParts = normalizedDir.split(path40.sep);
|
|
54764
54951
|
if (pathParts.includes("..")) {
|
|
54765
54952
|
return {
|
|
54766
54953
|
success: false,
|
|
@@ -54770,11 +54957,11 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
54770
54957
|
]
|
|
54771
54958
|
};
|
|
54772
54959
|
}
|
|
54773
|
-
const resolvedDir =
|
|
54960
|
+
const resolvedDir = path40.resolve(normalizedDir);
|
|
54774
54961
|
try {
|
|
54775
|
-
const realPath =
|
|
54776
|
-
const planPath2 =
|
|
54777
|
-
if (!
|
|
54962
|
+
const realPath = fs27.realpathSync(resolvedDir);
|
|
54963
|
+
const planPath2 = path40.join(realPath, ".swarm", "plan.json");
|
|
54964
|
+
if (!fs27.existsSync(planPath2)) {
|
|
54778
54965
|
return {
|
|
54779
54966
|
success: false,
|
|
54780
54967
|
message: `Invalid working_directory: plan not found in "${realPath}"`,
|
|
@@ -54794,8 +54981,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
54794
54981
|
}
|
|
54795
54982
|
}
|
|
54796
54983
|
const directory = normalizedDir ?? fallbackDir ?? process.cwd();
|
|
54797
|
-
const planPath =
|
|
54798
|
-
if (!
|
|
54984
|
+
const planPath = path40.resolve(directory, ".swarm", "plan.json");
|
|
54985
|
+
if (!fs27.existsSync(planPath)) {
|
|
54799
54986
|
return {
|
|
54800
54987
|
success: false,
|
|
54801
54988
|
message: "No plan found",
|
|
@@ -54804,7 +54991,7 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
54804
54991
|
}
|
|
54805
54992
|
let planContent;
|
|
54806
54993
|
try {
|
|
54807
|
-
planContent = JSON.parse(
|
|
54994
|
+
planContent = JSON.parse(fs27.readFileSync(planPath, "utf-8"));
|
|
54808
54995
|
} catch {
|
|
54809
54996
|
return {
|
|
54810
54997
|
success: false,
|
|
@@ -54884,20 +55071,20 @@ function validateBase(base) {
|
|
|
54884
55071
|
function validatePaths(paths) {
|
|
54885
55072
|
if (!paths)
|
|
54886
55073
|
return null;
|
|
54887
|
-
for (const
|
|
54888
|
-
if (!
|
|
55074
|
+
for (const path41 of paths) {
|
|
55075
|
+
if (!path41 || path41.length === 0) {
|
|
54889
55076
|
return "empty path not allowed";
|
|
54890
55077
|
}
|
|
54891
|
-
if (
|
|
55078
|
+
if (path41.length > MAX_PATH_LENGTH) {
|
|
54892
55079
|
return `path exceeds maximum length of ${MAX_PATH_LENGTH}`;
|
|
54893
55080
|
}
|
|
54894
|
-
if (SHELL_METACHARACTERS2.test(
|
|
55081
|
+
if (SHELL_METACHARACTERS2.test(path41)) {
|
|
54895
55082
|
return "path contains shell metacharacters";
|
|
54896
55083
|
}
|
|
54897
|
-
if (
|
|
55084
|
+
if (path41.startsWith("-")) {
|
|
54898
55085
|
return 'path cannot start with "-" (option-like arguments not allowed)';
|
|
54899
55086
|
}
|
|
54900
|
-
if (CONTROL_CHAR_PATTERN2.test(
|
|
55087
|
+
if (CONTROL_CHAR_PATTERN2.test(path41)) {
|
|
54901
55088
|
return "path contains control characters";
|
|
54902
55089
|
}
|
|
54903
55090
|
}
|
|
@@ -54977,8 +55164,8 @@ var diff = tool({
|
|
|
54977
55164
|
if (parts2.length >= 3) {
|
|
54978
55165
|
const additions = parseInt(parts2[0], 10) || 0;
|
|
54979
55166
|
const deletions = parseInt(parts2[1], 10) || 0;
|
|
54980
|
-
const
|
|
54981
|
-
files.push({ path:
|
|
55167
|
+
const path41 = parts2[2];
|
|
55168
|
+
files.push({ path: path41, additions, deletions });
|
|
54982
55169
|
}
|
|
54983
55170
|
}
|
|
54984
55171
|
const contractChanges = [];
|
|
@@ -55207,8 +55394,8 @@ Use these as DOMAIN values when delegating to @sme.`;
|
|
|
55207
55394
|
// src/tools/evidence-check.ts
|
|
55208
55395
|
init_dist();
|
|
55209
55396
|
init_create_tool();
|
|
55210
|
-
import * as
|
|
55211
|
-
import * as
|
|
55397
|
+
import * as fs28 from "fs";
|
|
55398
|
+
import * as path41 from "path";
|
|
55212
55399
|
var MAX_FILE_SIZE_BYTES3 = 1024 * 1024;
|
|
55213
55400
|
var MAX_EVIDENCE_FILES = 1000;
|
|
55214
55401
|
var EVIDENCE_DIR2 = ".swarm/evidence";
|
|
@@ -55238,9 +55425,9 @@ function validateRequiredTypes(input) {
|
|
|
55238
55425
|
return null;
|
|
55239
55426
|
}
|
|
55240
55427
|
function isPathWithinSwarm2(filePath, cwd) {
|
|
55241
|
-
const normalizedCwd =
|
|
55242
|
-
const swarmPath =
|
|
55243
|
-
const normalizedPath =
|
|
55428
|
+
const normalizedCwd = path41.resolve(cwd);
|
|
55429
|
+
const swarmPath = path41.join(normalizedCwd, ".swarm");
|
|
55430
|
+
const normalizedPath = path41.resolve(filePath);
|
|
55244
55431
|
return normalizedPath.startsWith(swarmPath);
|
|
55245
55432
|
}
|
|
55246
55433
|
function parseCompletedTasks(planContent) {
|
|
@@ -55256,12 +55443,12 @@ function parseCompletedTasks(planContent) {
|
|
|
55256
55443
|
}
|
|
55257
55444
|
function readEvidenceFiles(evidenceDir, _cwd) {
|
|
55258
55445
|
const evidence = [];
|
|
55259
|
-
if (!
|
|
55446
|
+
if (!fs28.existsSync(evidenceDir) || !fs28.statSync(evidenceDir).isDirectory()) {
|
|
55260
55447
|
return evidence;
|
|
55261
55448
|
}
|
|
55262
55449
|
let files;
|
|
55263
55450
|
try {
|
|
55264
|
-
files =
|
|
55451
|
+
files = fs28.readdirSync(evidenceDir);
|
|
55265
55452
|
} catch {
|
|
55266
55453
|
return evidence;
|
|
55267
55454
|
}
|
|
@@ -55270,14 +55457,14 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
55270
55457
|
if (!VALID_EVIDENCE_FILENAME_REGEX.test(filename)) {
|
|
55271
55458
|
continue;
|
|
55272
55459
|
}
|
|
55273
|
-
const filePath =
|
|
55460
|
+
const filePath = path41.join(evidenceDir, filename);
|
|
55274
55461
|
try {
|
|
55275
|
-
const resolvedPath =
|
|
55276
|
-
const evidenceDirResolved =
|
|
55462
|
+
const resolvedPath = path41.resolve(filePath);
|
|
55463
|
+
const evidenceDirResolved = path41.resolve(evidenceDir);
|
|
55277
55464
|
if (!resolvedPath.startsWith(evidenceDirResolved)) {
|
|
55278
55465
|
continue;
|
|
55279
55466
|
}
|
|
55280
|
-
const stat2 =
|
|
55467
|
+
const stat2 = fs28.lstatSync(filePath);
|
|
55281
55468
|
if (!stat2.isFile()) {
|
|
55282
55469
|
continue;
|
|
55283
55470
|
}
|
|
@@ -55286,7 +55473,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
55286
55473
|
}
|
|
55287
55474
|
let fileStat;
|
|
55288
55475
|
try {
|
|
55289
|
-
fileStat =
|
|
55476
|
+
fileStat = fs28.statSync(filePath);
|
|
55290
55477
|
if (fileStat.size > MAX_FILE_SIZE_BYTES3) {
|
|
55291
55478
|
continue;
|
|
55292
55479
|
}
|
|
@@ -55295,7 +55482,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
55295
55482
|
}
|
|
55296
55483
|
let content;
|
|
55297
55484
|
try {
|
|
55298
|
-
content =
|
|
55485
|
+
content = fs28.readFileSync(filePath, "utf-8");
|
|
55299
55486
|
} catch {
|
|
55300
55487
|
continue;
|
|
55301
55488
|
}
|
|
@@ -55391,7 +55578,7 @@ var evidence_check = createSwarmTool({
|
|
|
55391
55578
|
return JSON.stringify(errorResult, null, 2);
|
|
55392
55579
|
}
|
|
55393
55580
|
const requiredTypes = requiredTypesValue.split(",").map((t) => t.trim()).filter((t) => t.length > 0).map(normalizeEvidenceType);
|
|
55394
|
-
const planPath =
|
|
55581
|
+
const planPath = path41.join(cwd, PLAN_FILE);
|
|
55395
55582
|
if (!isPathWithinSwarm2(planPath, cwd)) {
|
|
55396
55583
|
const errorResult = {
|
|
55397
55584
|
error: "plan file path validation failed",
|
|
@@ -55405,7 +55592,7 @@ var evidence_check = createSwarmTool({
|
|
|
55405
55592
|
}
|
|
55406
55593
|
let planContent;
|
|
55407
55594
|
try {
|
|
55408
|
-
planContent =
|
|
55595
|
+
planContent = fs28.readFileSync(planPath, "utf-8");
|
|
55409
55596
|
} catch {
|
|
55410
55597
|
const result2 = {
|
|
55411
55598
|
message: "No completed tasks found in plan.",
|
|
@@ -55423,7 +55610,7 @@ var evidence_check = createSwarmTool({
|
|
|
55423
55610
|
};
|
|
55424
55611
|
return JSON.stringify(result2, null, 2);
|
|
55425
55612
|
}
|
|
55426
|
-
const evidenceDir =
|
|
55613
|
+
const evidenceDir = path41.join(cwd, EVIDENCE_DIR2);
|
|
55427
55614
|
const evidence = readEvidenceFiles(evidenceDir, cwd);
|
|
55428
55615
|
const { tasksWithFullEvidence, gaps } = analyzeGaps(completedTasks, evidence, requiredTypes);
|
|
55429
55616
|
const completeness = completedTasks.length > 0 ? Math.round(tasksWithFullEvidence.length / completedTasks.length * 100) / 100 : 1;
|
|
@@ -55440,8 +55627,8 @@ var evidence_check = createSwarmTool({
|
|
|
55440
55627
|
// src/tools/file-extractor.ts
|
|
55441
55628
|
init_tool();
|
|
55442
55629
|
init_create_tool();
|
|
55443
|
-
import * as
|
|
55444
|
-
import * as
|
|
55630
|
+
import * as fs29 from "fs";
|
|
55631
|
+
import * as path42 from "path";
|
|
55445
55632
|
var EXT_MAP = {
|
|
55446
55633
|
python: ".py",
|
|
55447
55634
|
py: ".py",
|
|
@@ -55503,8 +55690,8 @@ var extract_code_blocks = createSwarmTool({
|
|
|
55503
55690
|
execute: async (args2, directory) => {
|
|
55504
55691
|
const { content, output_dir, prefix } = args2;
|
|
55505
55692
|
const targetDir = output_dir || directory;
|
|
55506
|
-
if (!
|
|
55507
|
-
|
|
55693
|
+
if (!fs29.existsSync(targetDir)) {
|
|
55694
|
+
fs29.mkdirSync(targetDir, { recursive: true });
|
|
55508
55695
|
}
|
|
55509
55696
|
if (!content) {
|
|
55510
55697
|
return "Error: content is required";
|
|
@@ -55522,16 +55709,16 @@ var extract_code_blocks = createSwarmTool({
|
|
|
55522
55709
|
if (prefix) {
|
|
55523
55710
|
filename = `${prefix}_${filename}`;
|
|
55524
55711
|
}
|
|
55525
|
-
let filepath =
|
|
55526
|
-
const base =
|
|
55527
|
-
const ext =
|
|
55712
|
+
let filepath = path42.join(targetDir, filename);
|
|
55713
|
+
const base = path42.basename(filepath, path42.extname(filepath));
|
|
55714
|
+
const ext = path42.extname(filepath);
|
|
55528
55715
|
let counter = 1;
|
|
55529
|
-
while (
|
|
55530
|
-
filepath =
|
|
55716
|
+
while (fs29.existsSync(filepath)) {
|
|
55717
|
+
filepath = path42.join(targetDir, `${base}_${counter}${ext}`);
|
|
55531
55718
|
counter++;
|
|
55532
55719
|
}
|
|
55533
55720
|
try {
|
|
55534
|
-
|
|
55721
|
+
fs29.writeFileSync(filepath, code.trim(), "utf-8");
|
|
55535
55722
|
savedFiles.push(filepath);
|
|
55536
55723
|
} catch (error93) {
|
|
55537
55724
|
errors5.push(`Failed to save ${filename}: ${error93 instanceof Error ? error93.message : String(error93)}`);
|
|
@@ -55644,8 +55831,8 @@ var gitingest = tool({
|
|
|
55644
55831
|
});
|
|
55645
55832
|
// src/tools/imports.ts
|
|
55646
55833
|
init_dist();
|
|
55647
|
-
import * as
|
|
55648
|
-
import * as
|
|
55834
|
+
import * as fs30 from "fs";
|
|
55835
|
+
import * as path43 from "path";
|
|
55649
55836
|
var MAX_FILE_PATH_LENGTH2 = 500;
|
|
55650
55837
|
var MAX_SYMBOL_LENGTH = 256;
|
|
55651
55838
|
var MAX_FILE_SIZE_BYTES4 = 1024 * 1024;
|
|
@@ -55699,7 +55886,7 @@ function validateSymbolInput(symbol3) {
|
|
|
55699
55886
|
return null;
|
|
55700
55887
|
}
|
|
55701
55888
|
function isBinaryFile2(filePath, buffer) {
|
|
55702
|
-
const ext =
|
|
55889
|
+
const ext = path43.extname(filePath).toLowerCase();
|
|
55703
55890
|
if (ext === ".json" || ext === ".md" || ext === ".txt") {
|
|
55704
55891
|
return false;
|
|
55705
55892
|
}
|
|
@@ -55723,15 +55910,15 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
55723
55910
|
const imports = [];
|
|
55724
55911
|
let _resolvedTarget;
|
|
55725
55912
|
try {
|
|
55726
|
-
_resolvedTarget =
|
|
55913
|
+
_resolvedTarget = path43.resolve(targetFile);
|
|
55727
55914
|
} catch {
|
|
55728
55915
|
_resolvedTarget = targetFile;
|
|
55729
55916
|
}
|
|
55730
|
-
const targetBasename =
|
|
55917
|
+
const targetBasename = path43.basename(targetFile, path43.extname(targetFile));
|
|
55731
55918
|
const targetWithExt = targetFile;
|
|
55732
55919
|
const targetWithoutExt = targetFile.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
55733
|
-
const normalizedTargetWithExt =
|
|
55734
|
-
const normalizedTargetWithoutExt =
|
|
55920
|
+
const normalizedTargetWithExt = path43.normalize(targetWithExt).replace(/\\/g, "/");
|
|
55921
|
+
const normalizedTargetWithoutExt = path43.normalize(targetWithoutExt).replace(/\\/g, "/");
|
|
55735
55922
|
const importRegex = /import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
|
|
55736
55923
|
for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
|
|
55737
55924
|
const modulePath = match[1] || match[2] || match[3];
|
|
@@ -55754,9 +55941,9 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
55754
55941
|
}
|
|
55755
55942
|
const _normalizedModule = modulePath.replace(/^\.\//, "").replace(/^\.\.\\/, "../");
|
|
55756
55943
|
let isMatch = false;
|
|
55757
|
-
const _targetDir =
|
|
55758
|
-
const targetExt =
|
|
55759
|
-
const targetBasenameNoExt =
|
|
55944
|
+
const _targetDir = path43.dirname(targetFile);
|
|
55945
|
+
const targetExt = path43.extname(targetFile);
|
|
55946
|
+
const targetBasenameNoExt = path43.basename(targetFile, targetExt);
|
|
55760
55947
|
const moduleNormalized = modulePath.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
55761
55948
|
const moduleName = modulePath.split(/[/\\]/).pop() || "";
|
|
55762
55949
|
const moduleNameNoExt = moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
@@ -55813,7 +56000,7 @@ var SKIP_DIRECTORIES2 = new Set([
|
|
|
55813
56000
|
function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFiles: 0, fileErrors: [] }) {
|
|
55814
56001
|
let entries;
|
|
55815
56002
|
try {
|
|
55816
|
-
entries =
|
|
56003
|
+
entries = fs30.readdirSync(dir);
|
|
55817
56004
|
} catch (e) {
|
|
55818
56005
|
stats.fileErrors.push({
|
|
55819
56006
|
path: dir,
|
|
@@ -55824,13 +56011,13 @@ function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFile
|
|
|
55824
56011
|
entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
|
|
55825
56012
|
for (const entry of entries) {
|
|
55826
56013
|
if (SKIP_DIRECTORIES2.has(entry)) {
|
|
55827
|
-
stats.skippedDirs.push(
|
|
56014
|
+
stats.skippedDirs.push(path43.join(dir, entry));
|
|
55828
56015
|
continue;
|
|
55829
56016
|
}
|
|
55830
|
-
const fullPath =
|
|
56017
|
+
const fullPath = path43.join(dir, entry);
|
|
55831
56018
|
let stat2;
|
|
55832
56019
|
try {
|
|
55833
|
-
stat2 =
|
|
56020
|
+
stat2 = fs30.statSync(fullPath);
|
|
55834
56021
|
} catch (e) {
|
|
55835
56022
|
stats.fileErrors.push({
|
|
55836
56023
|
path: fullPath,
|
|
@@ -55841,7 +56028,7 @@ function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFile
|
|
|
55841
56028
|
if (stat2.isDirectory()) {
|
|
55842
56029
|
findSourceFiles(fullPath, files, stats);
|
|
55843
56030
|
} else if (stat2.isFile()) {
|
|
55844
|
-
const ext =
|
|
56031
|
+
const ext = path43.extname(fullPath).toLowerCase();
|
|
55845
56032
|
if (SUPPORTED_EXTENSIONS.includes(ext)) {
|
|
55846
56033
|
files.push(fullPath);
|
|
55847
56034
|
}
|
|
@@ -55897,8 +56084,8 @@ var imports = tool({
|
|
|
55897
56084
|
return JSON.stringify(errorResult, null, 2);
|
|
55898
56085
|
}
|
|
55899
56086
|
try {
|
|
55900
|
-
const targetFile =
|
|
55901
|
-
if (!
|
|
56087
|
+
const targetFile = path43.resolve(file3);
|
|
56088
|
+
if (!fs30.existsSync(targetFile)) {
|
|
55902
56089
|
const errorResult = {
|
|
55903
56090
|
error: `target file not found: ${file3}`,
|
|
55904
56091
|
target: file3,
|
|
@@ -55908,7 +56095,7 @@ var imports = tool({
|
|
|
55908
56095
|
};
|
|
55909
56096
|
return JSON.stringify(errorResult, null, 2);
|
|
55910
56097
|
}
|
|
55911
|
-
const targetStat =
|
|
56098
|
+
const targetStat = fs30.statSync(targetFile);
|
|
55912
56099
|
if (!targetStat.isFile()) {
|
|
55913
56100
|
const errorResult = {
|
|
55914
56101
|
error: "target must be a file, not a directory",
|
|
@@ -55919,7 +56106,7 @@ var imports = tool({
|
|
|
55919
56106
|
};
|
|
55920
56107
|
return JSON.stringify(errorResult, null, 2);
|
|
55921
56108
|
}
|
|
55922
|
-
const baseDir =
|
|
56109
|
+
const baseDir = path43.dirname(targetFile);
|
|
55923
56110
|
const scanStats = {
|
|
55924
56111
|
skippedDirs: [],
|
|
55925
56112
|
skippedFiles: 0,
|
|
@@ -55934,12 +56121,12 @@ var imports = tool({
|
|
|
55934
56121
|
if (consumers.length >= MAX_CONSUMERS)
|
|
55935
56122
|
break;
|
|
55936
56123
|
try {
|
|
55937
|
-
const stat2 =
|
|
56124
|
+
const stat2 = fs30.statSync(filePath);
|
|
55938
56125
|
if (stat2.size > MAX_FILE_SIZE_BYTES4) {
|
|
55939
56126
|
skippedFileCount++;
|
|
55940
56127
|
continue;
|
|
55941
56128
|
}
|
|
55942
|
-
const buffer =
|
|
56129
|
+
const buffer = fs30.readFileSync(filePath);
|
|
55943
56130
|
if (isBinaryFile2(filePath, buffer)) {
|
|
55944
56131
|
skippedFileCount++;
|
|
55945
56132
|
continue;
|
|
@@ -56004,7 +56191,7 @@ var imports = tool({
|
|
|
56004
56191
|
});
|
|
56005
56192
|
// src/tools/knowledge-query.ts
|
|
56006
56193
|
init_dist();
|
|
56007
|
-
import { existsSync as
|
|
56194
|
+
import { existsSync as existsSync28 } from "fs";
|
|
56008
56195
|
init_create_tool();
|
|
56009
56196
|
var DEFAULT_LIMIT = 10;
|
|
56010
56197
|
var MAX_LESSON_LENGTH = 200;
|
|
@@ -56074,14 +56261,14 @@ function validateLimit(limit) {
|
|
|
56074
56261
|
}
|
|
56075
56262
|
async function readSwarmKnowledge(directory) {
|
|
56076
56263
|
const swarmPath = resolveSwarmKnowledgePath(directory);
|
|
56077
|
-
if (!
|
|
56264
|
+
if (!existsSync28(swarmPath)) {
|
|
56078
56265
|
return [];
|
|
56079
56266
|
}
|
|
56080
56267
|
return readKnowledge(swarmPath);
|
|
56081
56268
|
}
|
|
56082
56269
|
async function readHiveKnowledge() {
|
|
56083
56270
|
const hivePath = resolveHiveKnowledgePath();
|
|
56084
|
-
if (!
|
|
56271
|
+
if (!existsSync28(hivePath)) {
|
|
56085
56272
|
return [];
|
|
56086
56273
|
}
|
|
56087
56274
|
return readKnowledge(hivePath);
|
|
@@ -56240,8 +56427,8 @@ init_dist();
|
|
|
56240
56427
|
init_config();
|
|
56241
56428
|
init_schema();
|
|
56242
56429
|
init_manager();
|
|
56243
|
-
import * as
|
|
56244
|
-
import * as
|
|
56430
|
+
import * as fs31 from "fs";
|
|
56431
|
+
import * as path44 from "path";
|
|
56245
56432
|
init_utils2();
|
|
56246
56433
|
init_create_tool();
|
|
56247
56434
|
function safeWarn(message, error93) {
|
|
@@ -56436,7 +56623,7 @@ async function executePhaseComplete(args2, workingDirectory) {
|
|
|
56436
56623
|
}
|
|
56437
56624
|
if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
|
|
56438
56625
|
try {
|
|
56439
|
-
const projectName =
|
|
56626
|
+
const projectName = path44.basename(dir);
|
|
56440
56627
|
const knowledgeConfig = {
|
|
56441
56628
|
enabled: true,
|
|
56442
56629
|
swarm_max_entries: 100,
|
|
@@ -56484,7 +56671,7 @@ async function executePhaseComplete(args2, workingDirectory) {
|
|
|
56484
56671
|
if (agentsMissing.length > 0) {
|
|
56485
56672
|
try {
|
|
56486
56673
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
56487
|
-
const planRaw =
|
|
56674
|
+
const planRaw = fs31.readFileSync(planPath, "utf-8");
|
|
56488
56675
|
const plan = JSON.parse(planRaw);
|
|
56489
56676
|
const targetPhase = plan.phases.find((p) => p.id === phase);
|
|
56490
56677
|
if (targetPhase && targetPhase.tasks.length > 0 && targetPhase.tasks.every((t) => t.status === "completed")) {
|
|
@@ -56525,7 +56712,7 @@ async function executePhaseComplete(args2, workingDirectory) {
|
|
|
56525
56712
|
};
|
|
56526
56713
|
try {
|
|
56527
56714
|
const eventsPath = validateSwarmPath(dir, "events.jsonl");
|
|
56528
|
-
|
|
56715
|
+
fs31.appendFileSync(eventsPath, `${JSON.stringify(event)}
|
|
56529
56716
|
`, "utf-8");
|
|
56530
56717
|
} catch (writeError) {
|
|
56531
56718
|
warnings.push(`Warning: failed to write phase complete event: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
|
|
@@ -56544,12 +56731,12 @@ async function executePhaseComplete(args2, workingDirectory) {
|
|
|
56544
56731
|
}
|
|
56545
56732
|
try {
|
|
56546
56733
|
const planPath = validateSwarmPath(dir, "plan.json");
|
|
56547
|
-
const planJson =
|
|
56734
|
+
const planJson = fs31.readFileSync(planPath, "utf-8");
|
|
56548
56735
|
const plan = JSON.parse(planJson);
|
|
56549
56736
|
const phaseObj = plan.phases.find((p) => p.id === phase);
|
|
56550
56737
|
if (phaseObj) {
|
|
56551
56738
|
phaseObj.status = "completed";
|
|
56552
|
-
|
|
56739
|
+
fs31.writeFileSync(planPath, `${JSON.stringify(plan, null, 2)}
|
|
56553
56740
|
`, "utf-8");
|
|
56554
56741
|
}
|
|
56555
56742
|
} catch (error93) {
|
|
@@ -56599,8 +56786,8 @@ init_dist();
|
|
|
56599
56786
|
init_discovery();
|
|
56600
56787
|
init_utils();
|
|
56601
56788
|
init_create_tool();
|
|
56602
|
-
import * as
|
|
56603
|
-
import * as
|
|
56789
|
+
import * as fs32 from "fs";
|
|
56790
|
+
import * as path45 from "path";
|
|
56604
56791
|
var MAX_OUTPUT_BYTES5 = 52428800;
|
|
56605
56792
|
var AUDIT_TIMEOUT_MS = 120000;
|
|
56606
56793
|
function isValidEcosystem(value) {
|
|
@@ -56618,28 +56805,28 @@ function validateArgs3(args2) {
|
|
|
56618
56805
|
function detectEcosystems(directory) {
|
|
56619
56806
|
const ecosystems = [];
|
|
56620
56807
|
const cwd = directory;
|
|
56621
|
-
if (
|
|
56808
|
+
if (fs32.existsSync(path45.join(cwd, "package.json"))) {
|
|
56622
56809
|
ecosystems.push("npm");
|
|
56623
56810
|
}
|
|
56624
|
-
if (
|
|
56811
|
+
if (fs32.existsSync(path45.join(cwd, "pyproject.toml")) || fs32.existsSync(path45.join(cwd, "requirements.txt"))) {
|
|
56625
56812
|
ecosystems.push("pip");
|
|
56626
56813
|
}
|
|
56627
|
-
if (
|
|
56814
|
+
if (fs32.existsSync(path45.join(cwd, "Cargo.toml"))) {
|
|
56628
56815
|
ecosystems.push("cargo");
|
|
56629
56816
|
}
|
|
56630
|
-
if (
|
|
56817
|
+
if (fs32.existsSync(path45.join(cwd, "go.mod"))) {
|
|
56631
56818
|
ecosystems.push("go");
|
|
56632
56819
|
}
|
|
56633
56820
|
try {
|
|
56634
|
-
const files =
|
|
56821
|
+
const files = fs32.readdirSync(cwd);
|
|
56635
56822
|
if (files.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"))) {
|
|
56636
56823
|
ecosystems.push("dotnet");
|
|
56637
56824
|
}
|
|
56638
56825
|
} catch {}
|
|
56639
|
-
if (
|
|
56826
|
+
if (fs32.existsSync(path45.join(cwd, "Gemfile")) || fs32.existsSync(path45.join(cwd, "Gemfile.lock"))) {
|
|
56640
56827
|
ecosystems.push("ruby");
|
|
56641
56828
|
}
|
|
56642
|
-
if (
|
|
56829
|
+
if (fs32.existsSync(path45.join(cwd, "pubspec.yaml"))) {
|
|
56643
56830
|
ecosystems.push("dart");
|
|
56644
56831
|
}
|
|
56645
56832
|
return ecosystems;
|
|
@@ -57701,8 +57888,8 @@ var SUPPORTED_PARSER_EXTENSIONS = new Set([
|
|
|
57701
57888
|
]);
|
|
57702
57889
|
// src/tools/pre-check-batch.ts
|
|
57703
57890
|
init_dist();
|
|
57704
|
-
import * as
|
|
57705
|
-
import * as
|
|
57891
|
+
import * as fs35 from "fs";
|
|
57892
|
+
import * as path48 from "path";
|
|
57706
57893
|
|
|
57707
57894
|
// node_modules/yocto-queue/index.js
|
|
57708
57895
|
class Node2 {
|
|
@@ -57869,8 +58056,8 @@ init_lint();
|
|
|
57869
58056
|
init_manager();
|
|
57870
58057
|
|
|
57871
58058
|
// src/quality/metrics.ts
|
|
57872
|
-
import * as
|
|
57873
|
-
import * as
|
|
58059
|
+
import * as fs33 from "fs";
|
|
58060
|
+
import * as path46 from "path";
|
|
57874
58061
|
var MAX_FILE_SIZE_BYTES5 = 256 * 1024;
|
|
57875
58062
|
var MIN_DUPLICATION_LINES = 10;
|
|
57876
58063
|
function estimateCyclomaticComplexity(content) {
|
|
@@ -57908,11 +58095,11 @@ function estimateCyclomaticComplexity(content) {
|
|
|
57908
58095
|
}
|
|
57909
58096
|
function getComplexityForFile2(filePath) {
|
|
57910
58097
|
try {
|
|
57911
|
-
const stat2 =
|
|
58098
|
+
const stat2 = fs33.statSync(filePath);
|
|
57912
58099
|
if (stat2.size > MAX_FILE_SIZE_BYTES5) {
|
|
57913
58100
|
return null;
|
|
57914
58101
|
}
|
|
57915
|
-
const content =
|
|
58102
|
+
const content = fs33.readFileSync(filePath, "utf-8");
|
|
57916
58103
|
return estimateCyclomaticComplexity(content);
|
|
57917
58104
|
} catch {
|
|
57918
58105
|
return null;
|
|
@@ -57922,8 +58109,8 @@ async function computeComplexityDelta(files, workingDir) {
|
|
|
57922
58109
|
let totalComplexity = 0;
|
|
57923
58110
|
const analyzedFiles = [];
|
|
57924
58111
|
for (const file3 of files) {
|
|
57925
|
-
const fullPath =
|
|
57926
|
-
if (!
|
|
58112
|
+
const fullPath = path46.isAbsolute(file3) ? file3 : path46.join(workingDir, file3);
|
|
58113
|
+
if (!fs33.existsSync(fullPath)) {
|
|
57927
58114
|
continue;
|
|
57928
58115
|
}
|
|
57929
58116
|
const complexity = getComplexityForFile2(fullPath);
|
|
@@ -58044,8 +58231,8 @@ function countGoExports(content) {
|
|
|
58044
58231
|
}
|
|
58045
58232
|
function getExportCountForFile(filePath) {
|
|
58046
58233
|
try {
|
|
58047
|
-
const content =
|
|
58048
|
-
const ext =
|
|
58234
|
+
const content = fs33.readFileSync(filePath, "utf-8");
|
|
58235
|
+
const ext = path46.extname(filePath).toLowerCase();
|
|
58049
58236
|
switch (ext) {
|
|
58050
58237
|
case ".ts":
|
|
58051
58238
|
case ".tsx":
|
|
@@ -58071,8 +58258,8 @@ async function computePublicApiDelta(files, workingDir) {
|
|
|
58071
58258
|
let totalExports = 0;
|
|
58072
58259
|
const analyzedFiles = [];
|
|
58073
58260
|
for (const file3 of files) {
|
|
58074
|
-
const fullPath =
|
|
58075
|
-
if (!
|
|
58261
|
+
const fullPath = path46.isAbsolute(file3) ? file3 : path46.join(workingDir, file3);
|
|
58262
|
+
if (!fs33.existsSync(fullPath)) {
|
|
58076
58263
|
continue;
|
|
58077
58264
|
}
|
|
58078
58265
|
const exports = getExportCountForFile(fullPath);
|
|
@@ -58105,16 +58292,16 @@ async function computeDuplicationRatio(files, workingDir) {
|
|
|
58105
58292
|
let duplicateLines = 0;
|
|
58106
58293
|
const analyzedFiles = [];
|
|
58107
58294
|
for (const file3 of files) {
|
|
58108
|
-
const fullPath =
|
|
58109
|
-
if (!
|
|
58295
|
+
const fullPath = path46.isAbsolute(file3) ? file3 : path46.join(workingDir, file3);
|
|
58296
|
+
if (!fs33.existsSync(fullPath)) {
|
|
58110
58297
|
continue;
|
|
58111
58298
|
}
|
|
58112
58299
|
try {
|
|
58113
|
-
const stat2 =
|
|
58300
|
+
const stat2 = fs33.statSync(fullPath);
|
|
58114
58301
|
if (stat2.size > MAX_FILE_SIZE_BYTES5) {
|
|
58115
58302
|
continue;
|
|
58116
58303
|
}
|
|
58117
|
-
const content =
|
|
58304
|
+
const content = fs33.readFileSync(fullPath, "utf-8");
|
|
58118
58305
|
const lines = content.split(`
|
|
58119
58306
|
`).filter((line) => line.trim().length > 0);
|
|
58120
58307
|
if (lines.length < MIN_DUPLICATION_LINES) {
|
|
@@ -58138,8 +58325,8 @@ function countCodeLines(content) {
|
|
|
58138
58325
|
return lines.length;
|
|
58139
58326
|
}
|
|
58140
58327
|
function isTestFile(filePath) {
|
|
58141
|
-
const basename8 =
|
|
58142
|
-
const _ext =
|
|
58328
|
+
const basename8 = path46.basename(filePath);
|
|
58329
|
+
const _ext = path46.extname(filePath).toLowerCase();
|
|
58143
58330
|
const testPatterns = [
|
|
58144
58331
|
".test.",
|
|
58145
58332
|
".spec.",
|
|
@@ -58220,8 +58407,8 @@ function matchGlobSegment(globSegments, pathSegments) {
|
|
|
58220
58407
|
}
|
|
58221
58408
|
return gIndex === globSegments.length && pIndex === pathSegments.length;
|
|
58222
58409
|
}
|
|
58223
|
-
function matchesGlobSegment(
|
|
58224
|
-
const normalizedPath =
|
|
58410
|
+
function matchesGlobSegment(path47, glob) {
|
|
58411
|
+
const normalizedPath = path47.replace(/\\/g, "/");
|
|
58225
58412
|
const normalizedGlob = glob.replace(/\\/g, "/");
|
|
58226
58413
|
if (normalizedPath.includes("//")) {
|
|
58227
58414
|
return false;
|
|
@@ -58252,8 +58439,8 @@ function simpleGlobToRegex2(glob) {
|
|
|
58252
58439
|
function hasGlobstar(glob) {
|
|
58253
58440
|
return glob.includes("**");
|
|
58254
58441
|
}
|
|
58255
|
-
function globMatches(
|
|
58256
|
-
const normalizedPath =
|
|
58442
|
+
function globMatches(path47, glob) {
|
|
58443
|
+
const normalizedPath = path47.replace(/\\/g, "/");
|
|
58257
58444
|
if (!glob || glob === "") {
|
|
58258
58445
|
if (normalizedPath.includes("//")) {
|
|
58259
58446
|
return false;
|
|
@@ -58289,31 +58476,31 @@ function shouldExcludeFile(filePath, excludeGlobs) {
|
|
|
58289
58476
|
async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
58290
58477
|
let testLines = 0;
|
|
58291
58478
|
let codeLines = 0;
|
|
58292
|
-
const srcDir =
|
|
58293
|
-
if (
|
|
58479
|
+
const srcDir = path46.join(workingDir, "src");
|
|
58480
|
+
if (fs33.existsSync(srcDir)) {
|
|
58294
58481
|
await scanDirectoryForLines(srcDir, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
58295
58482
|
codeLines += lines;
|
|
58296
58483
|
});
|
|
58297
58484
|
}
|
|
58298
58485
|
const possibleSrcDirs = ["lib", "app", "source", "core"];
|
|
58299
58486
|
for (const dir of possibleSrcDirs) {
|
|
58300
|
-
const dirPath =
|
|
58301
|
-
if (
|
|
58487
|
+
const dirPath = path46.join(workingDir, dir);
|
|
58488
|
+
if (fs33.existsSync(dirPath)) {
|
|
58302
58489
|
await scanDirectoryForLines(dirPath, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
58303
58490
|
codeLines += lines;
|
|
58304
58491
|
});
|
|
58305
58492
|
}
|
|
58306
58493
|
}
|
|
58307
|
-
const testsDir =
|
|
58308
|
-
if (
|
|
58494
|
+
const testsDir = path46.join(workingDir, "tests");
|
|
58495
|
+
if (fs33.existsSync(testsDir)) {
|
|
58309
58496
|
await scanDirectoryForLines(testsDir, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
58310
58497
|
testLines += lines;
|
|
58311
58498
|
});
|
|
58312
58499
|
}
|
|
58313
58500
|
const possibleTestDirs = ["test", "__tests__", "specs"];
|
|
58314
58501
|
for (const dir of possibleTestDirs) {
|
|
58315
|
-
const dirPath =
|
|
58316
|
-
if (
|
|
58502
|
+
const dirPath = path46.join(workingDir, dir);
|
|
58503
|
+
if (fs33.existsSync(dirPath) && dirPath !== testsDir) {
|
|
58317
58504
|
await scanDirectoryForLines(dirPath, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
58318
58505
|
testLines += lines;
|
|
58319
58506
|
});
|
|
@@ -58325,9 +58512,9 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
58325
58512
|
}
|
|
58326
58513
|
async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTestScan, callback) {
|
|
58327
58514
|
try {
|
|
58328
|
-
const entries =
|
|
58515
|
+
const entries = fs33.readdirSync(dirPath, { withFileTypes: true });
|
|
58329
58516
|
for (const entry of entries) {
|
|
58330
|
-
const fullPath =
|
|
58517
|
+
const fullPath = path46.join(dirPath, entry.name);
|
|
58331
58518
|
if (entry.isDirectory()) {
|
|
58332
58519
|
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === ".git") {
|
|
58333
58520
|
continue;
|
|
@@ -58335,7 +58522,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
58335
58522
|
await scanDirectoryForLines(fullPath, includeGlobs, excludeGlobs, isTestScan, callback);
|
|
58336
58523
|
} else if (entry.isFile()) {
|
|
58337
58524
|
const relativePath = fullPath.replace(`${process.cwd()}/`, "");
|
|
58338
|
-
const ext =
|
|
58525
|
+
const ext = path46.extname(entry.name).toLowerCase();
|
|
58339
58526
|
const validExts = [
|
|
58340
58527
|
".ts",
|
|
58341
58528
|
".tsx",
|
|
@@ -58371,7 +58558,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
58371
58558
|
continue;
|
|
58372
58559
|
}
|
|
58373
58560
|
try {
|
|
58374
|
-
const content =
|
|
58561
|
+
const content = fs33.readFileSync(fullPath, "utf-8");
|
|
58375
58562
|
const lines = countCodeLines(content);
|
|
58376
58563
|
callback(lines);
|
|
58377
58564
|
} catch {}
|
|
@@ -58585,8 +58772,8 @@ async function qualityBudget(input, directory) {
|
|
|
58585
58772
|
init_dist();
|
|
58586
58773
|
init_manager();
|
|
58587
58774
|
init_detector();
|
|
58588
|
-
import * as
|
|
58589
|
-
import * as
|
|
58775
|
+
import * as fs34 from "fs";
|
|
58776
|
+
import * as path47 from "path";
|
|
58590
58777
|
import { extname as extname9 } from "path";
|
|
58591
58778
|
|
|
58592
58779
|
// src/sast/rules/c.ts
|
|
@@ -59270,7 +59457,7 @@ function executeRulesSync(filePath, content, language) {
|
|
|
59270
59457
|
}
|
|
59271
59458
|
|
|
59272
59459
|
// src/sast/semgrep.ts
|
|
59273
|
-
import { execFile as execFile2, execFileSync as execFileSync2, spawn } from "child_process";
|
|
59460
|
+
import { execFile as execFile2, execFileSync as execFileSync2, spawn as spawn2 } from "child_process";
|
|
59274
59461
|
import { promisify as promisify2 } from "util";
|
|
59275
59462
|
var _execFileAsync = promisify2(execFile2);
|
|
59276
59463
|
var semgrepAvailableCache = null;
|
|
@@ -59335,7 +59522,7 @@ function mapSemgrepSeverity(severity) {
|
|
|
59335
59522
|
}
|
|
59336
59523
|
async function executeWithTimeout(command, args2, options) {
|
|
59337
59524
|
return new Promise((resolve15) => {
|
|
59338
|
-
const child =
|
|
59525
|
+
const child = spawn2(command, args2, {
|
|
59339
59526
|
shell: false,
|
|
59340
59527
|
cwd: options.cwd
|
|
59341
59528
|
});
|
|
@@ -59453,17 +59640,17 @@ var SEVERITY_ORDER = {
|
|
|
59453
59640
|
};
|
|
59454
59641
|
function shouldSkipFile(filePath) {
|
|
59455
59642
|
try {
|
|
59456
|
-
const stats =
|
|
59643
|
+
const stats = fs34.statSync(filePath);
|
|
59457
59644
|
if (stats.size > MAX_FILE_SIZE_BYTES6) {
|
|
59458
59645
|
return { skip: true, reason: "file too large" };
|
|
59459
59646
|
}
|
|
59460
59647
|
if (stats.size === 0) {
|
|
59461
59648
|
return { skip: true, reason: "empty file" };
|
|
59462
59649
|
}
|
|
59463
|
-
const fd =
|
|
59650
|
+
const fd = fs34.openSync(filePath, "r");
|
|
59464
59651
|
const buffer = Buffer.alloc(8192);
|
|
59465
|
-
const bytesRead =
|
|
59466
|
-
|
|
59652
|
+
const bytesRead = fs34.readSync(fd, buffer, 0, 8192, 0);
|
|
59653
|
+
fs34.closeSync(fd);
|
|
59467
59654
|
if (bytesRead > 0) {
|
|
59468
59655
|
let nullCount = 0;
|
|
59469
59656
|
for (let i2 = 0;i2 < bytesRead; i2++) {
|
|
@@ -59502,7 +59689,7 @@ function countBySeverity(findings) {
|
|
|
59502
59689
|
}
|
|
59503
59690
|
function scanFileWithTierA(filePath, language) {
|
|
59504
59691
|
try {
|
|
59505
|
-
const content =
|
|
59692
|
+
const content = fs34.readFileSync(filePath, "utf-8");
|
|
59506
59693
|
const findings = executeRulesSync(filePath, content, language);
|
|
59507
59694
|
return findings.map((f) => ({
|
|
59508
59695
|
rule_id: f.rule_id,
|
|
@@ -59549,8 +59736,8 @@ async function sastScan(input, directory, config3) {
|
|
|
59549
59736
|
_filesSkipped++;
|
|
59550
59737
|
continue;
|
|
59551
59738
|
}
|
|
59552
|
-
const resolvedPath =
|
|
59553
|
-
if (!
|
|
59739
|
+
const resolvedPath = path47.isAbsolute(filePath) ? filePath : path47.resolve(directory, filePath);
|
|
59740
|
+
if (!fs34.existsSync(resolvedPath)) {
|
|
59554
59741
|
_filesSkipped++;
|
|
59555
59742
|
continue;
|
|
59556
59743
|
}
|
|
@@ -59748,18 +59935,18 @@ function validatePath(inputPath, baseDir, workspaceDir) {
|
|
|
59748
59935
|
let resolved;
|
|
59749
59936
|
const isWinAbs = isWindowsAbsolutePath(inputPath);
|
|
59750
59937
|
if (isWinAbs) {
|
|
59751
|
-
resolved =
|
|
59752
|
-
} else if (
|
|
59753
|
-
resolved =
|
|
59938
|
+
resolved = path48.win32.resolve(inputPath);
|
|
59939
|
+
} else if (path48.isAbsolute(inputPath)) {
|
|
59940
|
+
resolved = path48.resolve(inputPath);
|
|
59754
59941
|
} else {
|
|
59755
|
-
resolved =
|
|
59942
|
+
resolved = path48.resolve(baseDir, inputPath);
|
|
59756
59943
|
}
|
|
59757
|
-
const workspaceResolved =
|
|
59944
|
+
const workspaceResolved = path48.resolve(workspaceDir);
|
|
59758
59945
|
let relative5;
|
|
59759
59946
|
if (isWinAbs) {
|
|
59760
|
-
relative5 =
|
|
59947
|
+
relative5 = path48.win32.relative(workspaceResolved, resolved);
|
|
59761
59948
|
} else {
|
|
59762
|
-
relative5 =
|
|
59949
|
+
relative5 = path48.relative(workspaceResolved, resolved);
|
|
59763
59950
|
}
|
|
59764
59951
|
if (relative5.startsWith("..")) {
|
|
59765
59952
|
return "path traversal detected";
|
|
@@ -59820,13 +60007,13 @@ async function runLintWrapped(files, directory, _config) {
|
|
|
59820
60007
|
}
|
|
59821
60008
|
async function runLintOnFiles(linter, files, workspaceDir) {
|
|
59822
60009
|
const isWindows = process.platform === "win32";
|
|
59823
|
-
const binDir =
|
|
60010
|
+
const binDir = path48.join(workspaceDir, "node_modules", ".bin");
|
|
59824
60011
|
const validatedFiles = [];
|
|
59825
60012
|
for (const file3 of files) {
|
|
59826
60013
|
if (typeof file3 !== "string") {
|
|
59827
60014
|
continue;
|
|
59828
60015
|
}
|
|
59829
|
-
const resolvedPath =
|
|
60016
|
+
const resolvedPath = path48.resolve(file3);
|
|
59830
60017
|
const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
|
|
59831
60018
|
if (validationError) {
|
|
59832
60019
|
continue;
|
|
@@ -59844,10 +60031,10 @@ async function runLintOnFiles(linter, files, workspaceDir) {
|
|
|
59844
60031
|
}
|
|
59845
60032
|
let command;
|
|
59846
60033
|
if (linter === "biome") {
|
|
59847
|
-
const biomeBin = isWindows ?
|
|
60034
|
+
const biomeBin = isWindows ? path48.join(binDir, "biome.EXE") : path48.join(binDir, "biome");
|
|
59848
60035
|
command = [biomeBin, "check", ...validatedFiles];
|
|
59849
60036
|
} else {
|
|
59850
|
-
const eslintBin = isWindows ?
|
|
60037
|
+
const eslintBin = isWindows ? path48.join(binDir, "eslint.cmd") : path48.join(binDir, "eslint");
|
|
59851
60038
|
command = [eslintBin, ...validatedFiles];
|
|
59852
60039
|
}
|
|
59853
60040
|
try {
|
|
@@ -59984,7 +60171,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
59984
60171
|
skippedFiles++;
|
|
59985
60172
|
continue;
|
|
59986
60173
|
}
|
|
59987
|
-
const resolvedPath =
|
|
60174
|
+
const resolvedPath = path48.resolve(file3);
|
|
59988
60175
|
const validationError = validatePath(resolvedPath, directory, directory);
|
|
59989
60176
|
if (validationError) {
|
|
59990
60177
|
skippedFiles++;
|
|
@@ -60002,14 +60189,14 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
60002
60189
|
};
|
|
60003
60190
|
}
|
|
60004
60191
|
for (const file3 of validatedFiles) {
|
|
60005
|
-
const ext =
|
|
60192
|
+
const ext = path48.extname(file3).toLowerCase();
|
|
60006
60193
|
if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
|
|
60007
60194
|
skippedFiles++;
|
|
60008
60195
|
continue;
|
|
60009
60196
|
}
|
|
60010
60197
|
let stat2;
|
|
60011
60198
|
try {
|
|
60012
|
-
stat2 =
|
|
60199
|
+
stat2 = fs35.statSync(file3);
|
|
60013
60200
|
} catch {
|
|
60014
60201
|
skippedFiles++;
|
|
60015
60202
|
continue;
|
|
@@ -60020,7 +60207,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
60020
60207
|
}
|
|
60021
60208
|
let content;
|
|
60022
60209
|
try {
|
|
60023
|
-
const buffer =
|
|
60210
|
+
const buffer = fs35.readFileSync(file3);
|
|
60024
60211
|
if (buffer.includes(0)) {
|
|
60025
60212
|
skippedFiles++;
|
|
60026
60213
|
continue;
|
|
@@ -60161,7 +60348,7 @@ async function runPreCheckBatch(input, workspaceDir) {
|
|
|
60161
60348
|
warn(`pre_check_batch: Invalid file path: ${file3}`);
|
|
60162
60349
|
continue;
|
|
60163
60350
|
}
|
|
60164
|
-
changedFiles.push(
|
|
60351
|
+
changedFiles.push(path48.resolve(directory, file3));
|
|
60165
60352
|
}
|
|
60166
60353
|
if (changedFiles.length === 0) {
|
|
60167
60354
|
warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
|
|
@@ -60312,7 +60499,7 @@ var pre_check_batch = createSwarmTool({
|
|
|
60312
60499
|
};
|
|
60313
60500
|
return JSON.stringify(errorResult, null, 2);
|
|
60314
60501
|
}
|
|
60315
|
-
const resolvedDirectory =
|
|
60502
|
+
const resolvedDirectory = path48.resolve(typedArgs.directory);
|
|
60316
60503
|
const workspaceAnchor = resolvedDirectory;
|
|
60317
60504
|
const dirError = validateDirectory3(resolvedDirectory, workspaceAnchor);
|
|
60318
60505
|
if (dirError) {
|
|
@@ -60419,8 +60606,8 @@ ${paginatedContent}`;
|
|
|
60419
60606
|
init_tool();
|
|
60420
60607
|
init_manager2();
|
|
60421
60608
|
init_create_tool();
|
|
60422
|
-
import * as
|
|
60423
|
-
import * as
|
|
60609
|
+
import * as fs36 from "fs";
|
|
60610
|
+
import * as path49 from "path";
|
|
60424
60611
|
function detectPlaceholderContent(args2) {
|
|
60425
60612
|
const issues = [];
|
|
60426
60613
|
const placeholderPattern = /^\[\w[\w\s]*\]$/;
|
|
@@ -60524,19 +60711,19 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
60524
60711
|
try {
|
|
60525
60712
|
await savePlan(dir, plan);
|
|
60526
60713
|
try {
|
|
60527
|
-
const markerPath =
|
|
60714
|
+
const markerPath = path49.join(dir, ".swarm", ".plan-write-marker");
|
|
60528
60715
|
const marker = JSON.stringify({
|
|
60529
60716
|
source: "save_plan",
|
|
60530
60717
|
timestamp: new Date().toISOString(),
|
|
60531
60718
|
phases_count: plan.phases.length,
|
|
60532
60719
|
tasks_count: tasksCount
|
|
60533
60720
|
});
|
|
60534
|
-
await
|
|
60721
|
+
await fs36.promises.writeFile(markerPath, marker, "utf8");
|
|
60535
60722
|
} catch {}
|
|
60536
60723
|
return {
|
|
60537
60724
|
success: true,
|
|
60538
60725
|
message: "Plan saved successfully",
|
|
60539
|
-
plan_path:
|
|
60726
|
+
plan_path: path49.join(dir, ".swarm", "plan.json"),
|
|
60540
60727
|
phases_count: plan.phases.length,
|
|
60541
60728
|
tasks_count: tasksCount
|
|
60542
60729
|
};
|
|
@@ -60574,8 +60761,8 @@ var save_plan = createSwarmTool({
|
|
|
60574
60761
|
// src/tools/sbom-generate.ts
|
|
60575
60762
|
init_dist();
|
|
60576
60763
|
init_manager();
|
|
60577
|
-
import * as
|
|
60578
|
-
import * as
|
|
60764
|
+
import * as fs37 from "fs";
|
|
60765
|
+
import * as path50 from "path";
|
|
60579
60766
|
|
|
60580
60767
|
// src/sbom/detectors/index.ts
|
|
60581
60768
|
init_utils();
|
|
@@ -61421,9 +61608,9 @@ function findManifestFiles(rootDir) {
|
|
|
61421
61608
|
const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
|
|
61422
61609
|
function searchDir(dir) {
|
|
61423
61610
|
try {
|
|
61424
|
-
const entries =
|
|
61611
|
+
const entries = fs37.readdirSync(dir, { withFileTypes: true });
|
|
61425
61612
|
for (const entry of entries) {
|
|
61426
|
-
const fullPath =
|
|
61613
|
+
const fullPath = path50.join(dir, entry.name);
|
|
61427
61614
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
|
|
61428
61615
|
continue;
|
|
61429
61616
|
}
|
|
@@ -61432,7 +61619,7 @@ function findManifestFiles(rootDir) {
|
|
|
61432
61619
|
} else if (entry.isFile()) {
|
|
61433
61620
|
for (const pattern of patterns) {
|
|
61434
61621
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
61435
|
-
manifestFiles.push(
|
|
61622
|
+
manifestFiles.push(path50.relative(rootDir, fullPath));
|
|
61436
61623
|
break;
|
|
61437
61624
|
}
|
|
61438
61625
|
}
|
|
@@ -61448,13 +61635,13 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
61448
61635
|
const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
|
|
61449
61636
|
for (const dir of directories) {
|
|
61450
61637
|
try {
|
|
61451
|
-
const entries =
|
|
61638
|
+
const entries = fs37.readdirSync(dir, { withFileTypes: true });
|
|
61452
61639
|
for (const entry of entries) {
|
|
61453
|
-
const fullPath =
|
|
61640
|
+
const fullPath = path50.join(dir, entry.name);
|
|
61454
61641
|
if (entry.isFile()) {
|
|
61455
61642
|
for (const pattern of patterns) {
|
|
61456
61643
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
61457
|
-
found.push(
|
|
61644
|
+
found.push(path50.relative(workingDir, fullPath));
|
|
61458
61645
|
break;
|
|
61459
61646
|
}
|
|
61460
61647
|
}
|
|
@@ -61467,11 +61654,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
61467
61654
|
function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
|
|
61468
61655
|
const dirs = new Set;
|
|
61469
61656
|
for (const file3 of changedFiles) {
|
|
61470
|
-
let currentDir =
|
|
61657
|
+
let currentDir = path50.dirname(file3);
|
|
61471
61658
|
while (true) {
|
|
61472
|
-
if (currentDir && currentDir !== "." && currentDir !==
|
|
61473
|
-
dirs.add(
|
|
61474
|
-
const parent =
|
|
61659
|
+
if (currentDir && currentDir !== "." && currentDir !== path50.sep) {
|
|
61660
|
+
dirs.add(path50.join(workingDir, currentDir));
|
|
61661
|
+
const parent = path50.dirname(currentDir);
|
|
61475
61662
|
if (parent === currentDir)
|
|
61476
61663
|
break;
|
|
61477
61664
|
currentDir = parent;
|
|
@@ -61485,7 +61672,7 @@ function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
|
|
|
61485
61672
|
}
|
|
61486
61673
|
function ensureOutputDir(outputDir) {
|
|
61487
61674
|
try {
|
|
61488
|
-
|
|
61675
|
+
fs37.mkdirSync(outputDir, { recursive: true });
|
|
61489
61676
|
} catch (error93) {
|
|
61490
61677
|
if (!error93 || error93.code !== "EEXIST") {
|
|
61491
61678
|
throw error93;
|
|
@@ -61555,7 +61742,7 @@ var sbom_generate = createSwarmTool({
|
|
|
61555
61742
|
const changedFiles = obj.changed_files;
|
|
61556
61743
|
const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
|
|
61557
61744
|
const workingDir = directory;
|
|
61558
|
-
const outputDir =
|
|
61745
|
+
const outputDir = path50.isAbsolute(relativeOutputDir) ? relativeOutputDir : path50.join(workingDir, relativeOutputDir);
|
|
61559
61746
|
let manifestFiles = [];
|
|
61560
61747
|
if (scope === "all") {
|
|
61561
61748
|
manifestFiles = findManifestFiles(workingDir);
|
|
@@ -61578,11 +61765,11 @@ var sbom_generate = createSwarmTool({
|
|
|
61578
61765
|
const processedFiles = [];
|
|
61579
61766
|
for (const manifestFile of manifestFiles) {
|
|
61580
61767
|
try {
|
|
61581
|
-
const fullPath =
|
|
61582
|
-
if (!
|
|
61768
|
+
const fullPath = path50.isAbsolute(manifestFile) ? manifestFile : path50.join(workingDir, manifestFile);
|
|
61769
|
+
if (!fs37.existsSync(fullPath)) {
|
|
61583
61770
|
continue;
|
|
61584
61771
|
}
|
|
61585
|
-
const content =
|
|
61772
|
+
const content = fs37.readFileSync(fullPath, "utf-8");
|
|
61586
61773
|
const components = detectComponents(manifestFile, content);
|
|
61587
61774
|
processedFiles.push(manifestFile);
|
|
61588
61775
|
if (components.length > 0) {
|
|
@@ -61595,8 +61782,8 @@ var sbom_generate = createSwarmTool({
|
|
|
61595
61782
|
const bom = generateCycloneDX(allComponents);
|
|
61596
61783
|
const bomJson = serializeCycloneDX(bom);
|
|
61597
61784
|
const filename = generateSbomFilename();
|
|
61598
|
-
const outputPath =
|
|
61599
|
-
|
|
61785
|
+
const outputPath = path50.join(outputDir, filename);
|
|
61786
|
+
fs37.writeFileSync(outputPath, bomJson, "utf-8");
|
|
61600
61787
|
const verdict = processedFiles.length > 0 ? "pass" : "pass";
|
|
61601
61788
|
try {
|
|
61602
61789
|
const timestamp = new Date().toISOString();
|
|
@@ -61638,8 +61825,8 @@ var sbom_generate = createSwarmTool({
|
|
|
61638
61825
|
// src/tools/schema-drift.ts
|
|
61639
61826
|
init_dist();
|
|
61640
61827
|
init_create_tool();
|
|
61641
|
-
import * as
|
|
61642
|
-
import * as
|
|
61828
|
+
import * as fs38 from "fs";
|
|
61829
|
+
import * as path51 from "path";
|
|
61643
61830
|
var SPEC_CANDIDATES = [
|
|
61644
61831
|
"openapi.json",
|
|
61645
61832
|
"openapi.yaml",
|
|
@@ -61671,28 +61858,28 @@ function normalizePath2(p) {
|
|
|
61671
61858
|
}
|
|
61672
61859
|
function discoverSpecFile(cwd, specFileArg) {
|
|
61673
61860
|
if (specFileArg) {
|
|
61674
|
-
const resolvedPath =
|
|
61675
|
-
const normalizedCwd = cwd.endsWith(
|
|
61861
|
+
const resolvedPath = path51.resolve(cwd, specFileArg);
|
|
61862
|
+
const normalizedCwd = cwd.endsWith(path51.sep) ? cwd : cwd + path51.sep;
|
|
61676
61863
|
if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
|
|
61677
61864
|
throw new Error("Invalid spec_file: path traversal detected");
|
|
61678
61865
|
}
|
|
61679
|
-
const ext =
|
|
61866
|
+
const ext = path51.extname(resolvedPath).toLowerCase();
|
|
61680
61867
|
if (!ALLOWED_EXTENSIONS.includes(ext)) {
|
|
61681
61868
|
throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
|
|
61682
61869
|
}
|
|
61683
|
-
const stats =
|
|
61870
|
+
const stats = fs38.statSync(resolvedPath);
|
|
61684
61871
|
if (stats.size > MAX_SPEC_SIZE) {
|
|
61685
61872
|
throw new Error(`Invalid spec_file: file exceeds ${MAX_SPEC_SIZE / 1024 / 1024}MB limit`);
|
|
61686
61873
|
}
|
|
61687
|
-
if (!
|
|
61874
|
+
if (!fs38.existsSync(resolvedPath)) {
|
|
61688
61875
|
throw new Error(`Spec file not found: ${resolvedPath}`);
|
|
61689
61876
|
}
|
|
61690
61877
|
return resolvedPath;
|
|
61691
61878
|
}
|
|
61692
61879
|
for (const candidate of SPEC_CANDIDATES) {
|
|
61693
|
-
const candidatePath =
|
|
61694
|
-
if (
|
|
61695
|
-
const stats =
|
|
61880
|
+
const candidatePath = path51.resolve(cwd, candidate);
|
|
61881
|
+
if (fs38.existsSync(candidatePath)) {
|
|
61882
|
+
const stats = fs38.statSync(candidatePath);
|
|
61696
61883
|
if (stats.size <= MAX_SPEC_SIZE) {
|
|
61697
61884
|
return candidatePath;
|
|
61698
61885
|
}
|
|
@@ -61701,8 +61888,8 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
61701
61888
|
return null;
|
|
61702
61889
|
}
|
|
61703
61890
|
function parseSpec(specFile) {
|
|
61704
|
-
const content =
|
|
61705
|
-
const ext =
|
|
61891
|
+
const content = fs38.readFileSync(specFile, "utf-8");
|
|
61892
|
+
const ext = path51.extname(specFile).toLowerCase();
|
|
61706
61893
|
if (ext === ".json") {
|
|
61707
61894
|
return parseJsonSpec(content);
|
|
61708
61895
|
}
|
|
@@ -61773,12 +61960,12 @@ function extractRoutes(cwd) {
|
|
|
61773
61960
|
function walkDir(dir) {
|
|
61774
61961
|
let entries;
|
|
61775
61962
|
try {
|
|
61776
|
-
entries =
|
|
61963
|
+
entries = fs38.readdirSync(dir, { withFileTypes: true });
|
|
61777
61964
|
} catch {
|
|
61778
61965
|
return;
|
|
61779
61966
|
}
|
|
61780
61967
|
for (const entry of entries) {
|
|
61781
|
-
const fullPath =
|
|
61968
|
+
const fullPath = path51.join(dir, entry.name);
|
|
61782
61969
|
if (entry.isSymbolicLink()) {
|
|
61783
61970
|
continue;
|
|
61784
61971
|
}
|
|
@@ -61788,7 +61975,7 @@ function extractRoutes(cwd) {
|
|
|
61788
61975
|
}
|
|
61789
61976
|
walkDir(fullPath);
|
|
61790
61977
|
} else if (entry.isFile()) {
|
|
61791
|
-
const ext =
|
|
61978
|
+
const ext = path51.extname(entry.name).toLowerCase();
|
|
61792
61979
|
const baseName = entry.name.toLowerCase();
|
|
61793
61980
|
if (![".ts", ".js", ".mjs"].includes(ext)) {
|
|
61794
61981
|
continue;
|
|
@@ -61806,7 +61993,7 @@ function extractRoutes(cwd) {
|
|
|
61806
61993
|
}
|
|
61807
61994
|
function extractRoutesFromFile(filePath) {
|
|
61808
61995
|
const routes = [];
|
|
61809
|
-
const content =
|
|
61996
|
+
const content = fs38.readFileSync(filePath, "utf-8");
|
|
61810
61997
|
const lines = content.split(/\r?\n/);
|
|
61811
61998
|
const expressRegex = /(?:app|router|server|express)\.(get|post|put|patch|delete|options|head)\s*\(\s*['"`]([^'"`]+)['"`]/g;
|
|
61812
61999
|
const flaskRegex = /@(?:app|blueprint|bp)\.route\s*\(\s*['"]([^'"]+)['"]/g;
|
|
@@ -61957,8 +62144,8 @@ init_secretscan();
|
|
|
61957
62144
|
// src/tools/symbols.ts
|
|
61958
62145
|
init_tool();
|
|
61959
62146
|
init_create_tool();
|
|
61960
|
-
import * as
|
|
61961
|
-
import * as
|
|
62147
|
+
import * as fs39 from "fs";
|
|
62148
|
+
import * as path52 from "path";
|
|
61962
62149
|
var MAX_FILE_SIZE_BYTES7 = 1024 * 1024;
|
|
61963
62150
|
var WINDOWS_RESERVED_NAMES = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
61964
62151
|
function containsControlCharacters(str) {
|
|
@@ -61987,11 +62174,11 @@ function containsWindowsAttacks(str) {
|
|
|
61987
62174
|
}
|
|
61988
62175
|
function isPathInWorkspace(filePath, workspace) {
|
|
61989
62176
|
try {
|
|
61990
|
-
const resolvedPath =
|
|
61991
|
-
const realWorkspace =
|
|
61992
|
-
const realResolvedPath =
|
|
61993
|
-
const relativePath =
|
|
61994
|
-
if (relativePath.startsWith("..") ||
|
|
62177
|
+
const resolvedPath = path52.resolve(workspace, filePath);
|
|
62178
|
+
const realWorkspace = fs39.realpathSync(workspace);
|
|
62179
|
+
const realResolvedPath = fs39.realpathSync(resolvedPath);
|
|
62180
|
+
const relativePath = path52.relative(realWorkspace, realResolvedPath);
|
|
62181
|
+
if (relativePath.startsWith("..") || path52.isAbsolute(relativePath)) {
|
|
61995
62182
|
return false;
|
|
61996
62183
|
}
|
|
61997
62184
|
return true;
|
|
@@ -62003,17 +62190,17 @@ function validatePathForRead(filePath, workspace) {
|
|
|
62003
62190
|
return isPathInWorkspace(filePath, workspace);
|
|
62004
62191
|
}
|
|
62005
62192
|
function extractTSSymbols(filePath, cwd) {
|
|
62006
|
-
const fullPath =
|
|
62193
|
+
const fullPath = path52.join(cwd, filePath);
|
|
62007
62194
|
if (!validatePathForRead(fullPath, cwd)) {
|
|
62008
62195
|
return [];
|
|
62009
62196
|
}
|
|
62010
62197
|
let content;
|
|
62011
62198
|
try {
|
|
62012
|
-
const stats =
|
|
62199
|
+
const stats = fs39.statSync(fullPath);
|
|
62013
62200
|
if (stats.size > MAX_FILE_SIZE_BYTES7) {
|
|
62014
62201
|
throw new Error(`File too large: ${stats.size} bytes (max: ${MAX_FILE_SIZE_BYTES7})`);
|
|
62015
62202
|
}
|
|
62016
|
-
content =
|
|
62203
|
+
content = fs39.readFileSync(fullPath, "utf-8");
|
|
62017
62204
|
} catch {
|
|
62018
62205
|
return [];
|
|
62019
62206
|
}
|
|
@@ -62155,17 +62342,17 @@ function extractTSSymbols(filePath, cwd) {
|
|
|
62155
62342
|
});
|
|
62156
62343
|
}
|
|
62157
62344
|
function extractPythonSymbols(filePath, cwd) {
|
|
62158
|
-
const fullPath =
|
|
62345
|
+
const fullPath = path52.join(cwd, filePath);
|
|
62159
62346
|
if (!validatePathForRead(fullPath, cwd)) {
|
|
62160
62347
|
return [];
|
|
62161
62348
|
}
|
|
62162
62349
|
let content;
|
|
62163
62350
|
try {
|
|
62164
|
-
const stats =
|
|
62351
|
+
const stats = fs39.statSync(fullPath);
|
|
62165
62352
|
if (stats.size > MAX_FILE_SIZE_BYTES7) {
|
|
62166
62353
|
throw new Error(`File too large: ${stats.size} bytes (max: ${MAX_FILE_SIZE_BYTES7})`);
|
|
62167
62354
|
}
|
|
62168
|
-
content =
|
|
62355
|
+
content = fs39.readFileSync(fullPath, "utf-8");
|
|
62169
62356
|
} catch {
|
|
62170
62357
|
return [];
|
|
62171
62358
|
}
|
|
@@ -62238,7 +62425,7 @@ var symbols = createSwarmTool({
|
|
|
62238
62425
|
}, null, 2);
|
|
62239
62426
|
}
|
|
62240
62427
|
const cwd = directory;
|
|
62241
|
-
const ext =
|
|
62428
|
+
const ext = path52.extname(file3);
|
|
62242
62429
|
if (containsControlCharacters(file3)) {
|
|
62243
62430
|
return JSON.stringify({
|
|
62244
62431
|
file: file3,
|
|
@@ -62309,8 +62496,8 @@ init_test_runner();
|
|
|
62309
62496
|
init_dist();
|
|
62310
62497
|
init_utils();
|
|
62311
62498
|
init_create_tool();
|
|
62312
|
-
import * as
|
|
62313
|
-
import * as
|
|
62499
|
+
import * as fs40 from "fs";
|
|
62500
|
+
import * as path53 from "path";
|
|
62314
62501
|
var MAX_TEXT_LENGTH = 200;
|
|
62315
62502
|
var MAX_FILE_SIZE_BYTES8 = 1024 * 1024;
|
|
62316
62503
|
var SUPPORTED_EXTENSIONS2 = new Set([
|
|
@@ -62381,9 +62568,9 @@ function validatePathsInput(paths, cwd) {
|
|
|
62381
62568
|
return { error: "paths contains path traversal", resolvedPath: null };
|
|
62382
62569
|
}
|
|
62383
62570
|
try {
|
|
62384
|
-
const resolvedPath =
|
|
62385
|
-
const normalizedCwd =
|
|
62386
|
-
const normalizedResolved =
|
|
62571
|
+
const resolvedPath = path53.resolve(paths);
|
|
62572
|
+
const normalizedCwd = path53.resolve(cwd);
|
|
62573
|
+
const normalizedResolved = path53.resolve(resolvedPath);
|
|
62387
62574
|
if (!normalizedResolved.startsWith(normalizedCwd)) {
|
|
62388
62575
|
return {
|
|
62389
62576
|
error: "paths must be within the current working directory",
|
|
@@ -62399,13 +62586,13 @@ function validatePathsInput(paths, cwd) {
|
|
|
62399
62586
|
}
|
|
62400
62587
|
}
|
|
62401
62588
|
function isSupportedExtension(filePath) {
|
|
62402
|
-
const ext =
|
|
62589
|
+
const ext = path53.extname(filePath).toLowerCase();
|
|
62403
62590
|
return SUPPORTED_EXTENSIONS2.has(ext);
|
|
62404
62591
|
}
|
|
62405
62592
|
function findSourceFiles2(dir, files = []) {
|
|
62406
62593
|
let entries;
|
|
62407
62594
|
try {
|
|
62408
|
-
entries =
|
|
62595
|
+
entries = fs40.readdirSync(dir);
|
|
62409
62596
|
} catch {
|
|
62410
62597
|
return files;
|
|
62411
62598
|
}
|
|
@@ -62414,10 +62601,10 @@ function findSourceFiles2(dir, files = []) {
|
|
|
62414
62601
|
if (SKIP_DIRECTORIES3.has(entry)) {
|
|
62415
62602
|
continue;
|
|
62416
62603
|
}
|
|
62417
|
-
const fullPath =
|
|
62604
|
+
const fullPath = path53.join(dir, entry);
|
|
62418
62605
|
let stat2;
|
|
62419
62606
|
try {
|
|
62420
|
-
stat2 =
|
|
62607
|
+
stat2 = fs40.statSync(fullPath);
|
|
62421
62608
|
} catch {
|
|
62422
62609
|
continue;
|
|
62423
62610
|
}
|
|
@@ -62510,7 +62697,7 @@ var todo_extract = createSwarmTool({
|
|
|
62510
62697
|
return JSON.stringify(errorResult, null, 2);
|
|
62511
62698
|
}
|
|
62512
62699
|
const scanPath = resolvedPath;
|
|
62513
|
-
if (!
|
|
62700
|
+
if (!fs40.existsSync(scanPath)) {
|
|
62514
62701
|
const errorResult = {
|
|
62515
62702
|
error: `path not found: ${pathsInput}`,
|
|
62516
62703
|
total: 0,
|
|
@@ -62520,13 +62707,13 @@ var todo_extract = createSwarmTool({
|
|
|
62520
62707
|
return JSON.stringify(errorResult, null, 2);
|
|
62521
62708
|
}
|
|
62522
62709
|
const filesToScan = [];
|
|
62523
|
-
const stat2 =
|
|
62710
|
+
const stat2 = fs40.statSync(scanPath);
|
|
62524
62711
|
if (stat2.isFile()) {
|
|
62525
62712
|
if (isSupportedExtension(scanPath)) {
|
|
62526
62713
|
filesToScan.push(scanPath);
|
|
62527
62714
|
} else {
|
|
62528
62715
|
const errorResult = {
|
|
62529
|
-
error: `unsupported file extension: ${
|
|
62716
|
+
error: `unsupported file extension: ${path53.extname(scanPath)}`,
|
|
62530
62717
|
total: 0,
|
|
62531
62718
|
byPriority: { high: 0, medium: 0, low: 0 },
|
|
62532
62719
|
entries: []
|
|
@@ -62539,11 +62726,11 @@ var todo_extract = createSwarmTool({
|
|
|
62539
62726
|
const allEntries = [];
|
|
62540
62727
|
for (const filePath of filesToScan) {
|
|
62541
62728
|
try {
|
|
62542
|
-
const fileStat =
|
|
62729
|
+
const fileStat = fs40.statSync(filePath);
|
|
62543
62730
|
if (fileStat.size > MAX_FILE_SIZE_BYTES8) {
|
|
62544
62731
|
continue;
|
|
62545
62732
|
}
|
|
62546
|
-
const content =
|
|
62733
|
+
const content = fs40.readFileSync(filePath, "utf-8");
|
|
62547
62734
|
const entries = parseTodoComments(content, filePath, tagsSet);
|
|
62548
62735
|
allEntries.push(...entries);
|
|
62549
62736
|
} catch {}
|
|
@@ -62571,18 +62758,18 @@ var todo_extract = createSwarmTool({
|
|
|
62571
62758
|
// src/tools/update-task-status.ts
|
|
62572
62759
|
init_tool();
|
|
62573
62760
|
init_schema();
|
|
62574
|
-
import * as
|
|
62575
|
-
import * as
|
|
62761
|
+
import * as fs42 from "fs";
|
|
62762
|
+
import * as path55 from "path";
|
|
62576
62763
|
|
|
62577
62764
|
// src/hooks/diff-scope.ts
|
|
62578
|
-
import * as
|
|
62579
|
-
import * as
|
|
62765
|
+
import * as fs41 from "fs";
|
|
62766
|
+
import * as path54 from "path";
|
|
62580
62767
|
function getDeclaredScope(taskId, directory) {
|
|
62581
62768
|
try {
|
|
62582
|
-
const planPath =
|
|
62583
|
-
if (!
|
|
62769
|
+
const planPath = path54.join(directory, ".swarm", "plan.json");
|
|
62770
|
+
if (!fs41.existsSync(planPath))
|
|
62584
62771
|
return null;
|
|
62585
|
-
const raw =
|
|
62772
|
+
const raw = fs41.readFileSync(planPath, "utf-8");
|
|
62586
62773
|
const plan = JSON.parse(raw);
|
|
62587
62774
|
for (const phase of plan.phases ?? []) {
|
|
62588
62775
|
for (const task of phase.tasks ?? []) {
|
|
@@ -62694,7 +62881,7 @@ var TIER_3_PATTERNS = [
|
|
|
62694
62881
|
];
|
|
62695
62882
|
function matchesTier3Pattern(files) {
|
|
62696
62883
|
for (const file3 of files) {
|
|
62697
|
-
const fileName =
|
|
62884
|
+
const fileName = path55.basename(file3);
|
|
62698
62885
|
for (const pattern of TIER_3_PATTERNS) {
|
|
62699
62886
|
if (pattern.test(fileName)) {
|
|
62700
62887
|
return true;
|
|
@@ -62716,8 +62903,8 @@ function checkReviewerGate(taskId, workingDirectory) {
|
|
|
62716
62903
|
if (hasActiveTurboMode2()) {
|
|
62717
62904
|
const resolvedDir2 = workingDirectory ?? process.cwd();
|
|
62718
62905
|
try {
|
|
62719
|
-
const planPath =
|
|
62720
|
-
const planRaw =
|
|
62906
|
+
const planPath = path55.join(resolvedDir2, ".swarm", "plan.json");
|
|
62907
|
+
const planRaw = fs42.readFileSync(planPath, "utf-8");
|
|
62721
62908
|
const plan = JSON.parse(planRaw);
|
|
62722
62909
|
for (const planPhase of plan.phases ?? []) {
|
|
62723
62910
|
for (const task of planPhase.tasks ?? []) {
|
|
@@ -62736,8 +62923,8 @@ function checkReviewerGate(taskId, workingDirectory) {
|
|
|
62736
62923
|
}
|
|
62737
62924
|
const resolvedDir = workingDirectory ?? process.cwd();
|
|
62738
62925
|
try {
|
|
62739
|
-
const evidencePath =
|
|
62740
|
-
const raw =
|
|
62926
|
+
const evidencePath = path55.join(resolvedDir, ".swarm", "evidence", `${taskId}.json`);
|
|
62927
|
+
const raw = fs42.readFileSync(evidencePath, "utf-8");
|
|
62741
62928
|
const evidence = JSON.parse(raw);
|
|
62742
62929
|
if (evidence?.required_gates && Array.isArray(evidence.required_gates) && evidence?.gates) {
|
|
62743
62930
|
const allGatesMet = evidence.required_gates.every((gate) => evidence.gates[gate] != null);
|
|
@@ -62777,8 +62964,8 @@ function checkReviewerGate(taskId, workingDirectory) {
|
|
|
62777
62964
|
}
|
|
62778
62965
|
try {
|
|
62779
62966
|
const resolvedDir2 = workingDirectory ?? process.cwd();
|
|
62780
|
-
const planPath =
|
|
62781
|
-
const planRaw =
|
|
62967
|
+
const planPath = path55.join(resolvedDir2, ".swarm", "plan.json");
|
|
62968
|
+
const planRaw = fs42.readFileSync(planPath, "utf-8");
|
|
62782
62969
|
const plan = JSON.parse(planRaw);
|
|
62783
62970
|
for (const planPhase of plan.phases ?? []) {
|
|
62784
62971
|
for (const task of planPhase.tasks ?? []) {
|
|
@@ -62959,8 +63146,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
62959
63146
|
};
|
|
62960
63147
|
}
|
|
62961
63148
|
}
|
|
62962
|
-
normalizedDir =
|
|
62963
|
-
const pathParts = normalizedDir.split(
|
|
63149
|
+
normalizedDir = path55.normalize(args2.working_directory);
|
|
63150
|
+
const pathParts = normalizedDir.split(path55.sep);
|
|
62964
63151
|
if (pathParts.includes("..")) {
|
|
62965
63152
|
return {
|
|
62966
63153
|
success: false,
|
|
@@ -62970,11 +63157,11 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
62970
63157
|
]
|
|
62971
63158
|
};
|
|
62972
63159
|
}
|
|
62973
|
-
const resolvedDir =
|
|
63160
|
+
const resolvedDir = path55.resolve(normalizedDir);
|
|
62974
63161
|
try {
|
|
62975
|
-
const realPath =
|
|
62976
|
-
const planPath =
|
|
62977
|
-
if (!
|
|
63162
|
+
const realPath = fs42.realpathSync(resolvedDir);
|
|
63163
|
+
const planPath = path55.join(realPath, ".swarm", "plan.json");
|
|
63164
|
+
if (!fs42.existsSync(planPath)) {
|
|
62978
63165
|
return {
|
|
62979
63166
|
success: false,
|
|
62980
63167
|
message: `Invalid working_directory: plan not found in "${realPath}"`,
|
|
@@ -63168,7 +63355,7 @@ var OpenCodeSwarm = async (ctx) => {
|
|
|
63168
63355
|
const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
|
|
63169
63356
|
preflightTriggerManager = new PTM(automationConfig);
|
|
63170
63357
|
const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
|
|
63171
|
-
const swarmDir =
|
|
63358
|
+
const swarmDir = path56.resolve(ctx.directory, ".swarm");
|
|
63172
63359
|
statusArtifact = new ASA(swarmDir);
|
|
63173
63360
|
statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
|
|
63174
63361
|
if (automationConfig.capabilities?.evidence_auto_summaries === true) {
|