opencode-swarm 7.32.3 → 7.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +6 -2
- package/dist/config/schema.d.ts +16 -2
- package/dist/index.js +777 -391
- package/dist/memory/config.d.ts +5 -1
- package/dist/memory/gateway.d.ts +2 -0
- package/dist/memory/index.d.ts +2 -1
- package/dist/memory/provider.d.ts +1 -0
- package/dist/memory/sqlite-provider.d.ts +39 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -48,7 +48,7 @@ var package_default;
|
|
|
48
48
|
var init_package = __esm(() => {
|
|
49
49
|
package_default = {
|
|
50
50
|
name: "opencode-swarm",
|
|
51
|
-
version: "7.
|
|
51
|
+
version: "7.33.0",
|
|
52
52
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
53
53
|
main: "dist/index.js",
|
|
54
54
|
types: "dist/index.d.ts",
|
|
@@ -15539,8 +15539,12 @@ var init_schema = __esm(() => {
|
|
|
15539
15539
|
});
|
|
15540
15540
|
MemoryConfigSchema = exports_external.object({
|
|
15541
15541
|
enabled: exports_external.boolean().default(false),
|
|
15542
|
-
provider: exports_external.
|
|
15542
|
+
provider: exports_external.enum(["local-jsonl", "sqlite"]).default("local-jsonl"),
|
|
15543
15543
|
storageDir: exports_external.string().default(".swarm/memory"),
|
|
15544
|
+
sqlite: exports_external.object({
|
|
15545
|
+
path: exports_external.string().default(".swarm/memory/memory.db"),
|
|
15546
|
+
busyTimeoutMs: exports_external.number().int().min(0).max(60000).default(5000)
|
|
15547
|
+
}).default({ path: ".swarm/memory/memory.db", busyTimeoutMs: 5000 }),
|
|
15544
15548
|
recall: exports_external.object({
|
|
15545
15549
|
defaultMaxItems: exports_external.number().int().min(1).max(20).default(8),
|
|
15546
15550
|
defaultTokenBudget: exports_external.number().int().min(100).max(5000).default(1200),
|
|
@@ -84599,7 +84603,7 @@ __export(exports_project_context, {
|
|
|
84599
84603
|
LANG_BACKEND_DETECTION_TIMEOUT_MS: () => LANG_BACKEND_DETECTION_TIMEOUT_MS
|
|
84600
84604
|
});
|
|
84601
84605
|
import * as fs113 from "node:fs";
|
|
84602
|
-
import * as
|
|
84606
|
+
import * as path148 from "node:path";
|
|
84603
84607
|
function detectFileExists2(directory, pattern) {
|
|
84604
84608
|
if (pattern.includes("*") || pattern.includes("?")) {
|
|
84605
84609
|
try {
|
|
@@ -84611,7 +84615,7 @@ function detectFileExists2(directory, pattern) {
|
|
|
84611
84615
|
}
|
|
84612
84616
|
}
|
|
84613
84617
|
try {
|
|
84614
|
-
fs113.accessSync(
|
|
84618
|
+
fs113.accessSync(path148.join(directory, pattern));
|
|
84615
84619
|
return true;
|
|
84616
84620
|
} catch {
|
|
84617
84621
|
return false;
|
|
@@ -84620,7 +84624,7 @@ function detectFileExists2(directory, pattern) {
|
|
|
84620
84624
|
function selectTestCommandFromScriptsTest(backend, directory) {
|
|
84621
84625
|
let pkgRaw;
|
|
84622
84626
|
try {
|
|
84623
|
-
pkgRaw = fs113.readFileSync(
|
|
84627
|
+
pkgRaw = fs113.readFileSync(path148.join(directory, "package.json"), "utf-8");
|
|
84624
84628
|
} catch {
|
|
84625
84629
|
return null;
|
|
84626
84630
|
}
|
|
@@ -84729,7 +84733,7 @@ var init_project_context = __esm(() => {
|
|
|
84729
84733
|
init_package();
|
|
84730
84734
|
init_agents2();
|
|
84731
84735
|
init_critic();
|
|
84732
|
-
import * as
|
|
84736
|
+
import * as path149 from "node:path";
|
|
84733
84737
|
|
|
84734
84738
|
// src/background/index.ts
|
|
84735
84739
|
init_event_bus();
|
|
@@ -97595,6 +97599,10 @@ var DEFAULT_MEMORY_CONFIG = {
|
|
|
97595
97599
|
enabled: false,
|
|
97596
97600
|
provider: "local-jsonl",
|
|
97597
97601
|
storageDir: ".swarm/memory",
|
|
97602
|
+
sqlite: {
|
|
97603
|
+
path: ".swarm/memory/memory.db",
|
|
97604
|
+
busyTimeoutMs: 5000
|
|
97605
|
+
},
|
|
97598
97606
|
recall: {
|
|
97599
97607
|
defaultMaxItems: 8,
|
|
97600
97608
|
defaultTokenBudget: 1200,
|
|
@@ -97634,6 +97642,10 @@ function resolveMemoryConfig(input) {
|
|
|
97634
97642
|
return {
|
|
97635
97643
|
...DEFAULT_MEMORY_CONFIG,
|
|
97636
97644
|
...input ?? {},
|
|
97645
|
+
sqlite: {
|
|
97646
|
+
...DEFAULT_MEMORY_CONFIG.sqlite,
|
|
97647
|
+
...input?.sqlite ?? {}
|
|
97648
|
+
},
|
|
97637
97649
|
recall: {
|
|
97638
97650
|
...DEFAULT_MEMORY_CONFIG.recall,
|
|
97639
97651
|
...input?.recall ?? {},
|
|
@@ -97671,7 +97683,7 @@ class MemoryDisabledError extends Error {
|
|
|
97671
97683
|
// src/memory/gateway.ts
|
|
97672
97684
|
import { createHash as createHash9 } from "node:crypto";
|
|
97673
97685
|
import { existsSync as existsSync50, readFileSync as readFileSync39 } from "node:fs";
|
|
97674
|
-
import * as
|
|
97686
|
+
import * as path97 from "node:path";
|
|
97675
97687
|
|
|
97676
97688
|
// src/memory/local-jsonl-provider.ts
|
|
97677
97689
|
init_utils2();
|
|
@@ -98373,6 +98385,367 @@ function toRecallBundle(input) {
|
|
|
98373
98385
|
};
|
|
98374
98386
|
}
|
|
98375
98387
|
|
|
98388
|
+
// src/memory/sqlite-provider.ts
|
|
98389
|
+
init_utils2();
|
|
98390
|
+
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
98391
|
+
import { mkdirSync as mkdirSync24 } from "node:fs";
|
|
98392
|
+
import { createRequire as createRequire3 } from "node:module";
|
|
98393
|
+
import * as path96 from "node:path";
|
|
98394
|
+
var _DatabaseCtor2 = null;
|
|
98395
|
+
function loadDatabaseCtor2() {
|
|
98396
|
+
if (_DatabaseCtor2)
|
|
98397
|
+
return _DatabaseCtor2;
|
|
98398
|
+
const req = createRequire3(import.meta.url);
|
|
98399
|
+
_DatabaseCtor2 = req("bun:sqlite").Database;
|
|
98400
|
+
return _DatabaseCtor2;
|
|
98401
|
+
}
|
|
98402
|
+
var MIGRATIONS2 = [
|
|
98403
|
+
{
|
|
98404
|
+
version: 1,
|
|
98405
|
+
name: "create_memory_provider_tables",
|
|
98406
|
+
sql: `
|
|
98407
|
+
CREATE TABLE IF NOT EXISTS memory_items (
|
|
98408
|
+
id TEXT PRIMARY KEY,
|
|
98409
|
+
scope_key TEXT NOT NULL,
|
|
98410
|
+
kind TEXT NOT NULL,
|
|
98411
|
+
updated_at TEXT NOT NULL,
|
|
98412
|
+
expires_at TEXT,
|
|
98413
|
+
superseded_by TEXT,
|
|
98414
|
+
deleted INTEGER NOT NULL DEFAULT 0,
|
|
98415
|
+
record_json TEXT NOT NULL
|
|
98416
|
+
);
|
|
98417
|
+
CREATE INDEX IF NOT EXISTS idx_memory_items_scope_kind
|
|
98418
|
+
ON memory_items(scope_key, kind);
|
|
98419
|
+
CREATE INDEX IF NOT EXISTS idx_memory_items_updated_at
|
|
98420
|
+
ON memory_items(updated_at);
|
|
98421
|
+
|
|
98422
|
+
CREATE TABLE IF NOT EXISTS memory_proposals (
|
|
98423
|
+
id TEXT PRIMARY KEY,
|
|
98424
|
+
status TEXT NOT NULL,
|
|
98425
|
+
created_at TEXT NOT NULL,
|
|
98426
|
+
proposal_json TEXT NOT NULL
|
|
98427
|
+
);
|
|
98428
|
+
CREATE INDEX IF NOT EXISTS idx_memory_proposals_status_created
|
|
98429
|
+
ON memory_proposals(status, created_at);
|
|
98430
|
+
|
|
98431
|
+
CREATE TABLE IF NOT EXISTS memory_events (
|
|
98432
|
+
id TEXT PRIMARY KEY,
|
|
98433
|
+
operation TEXT NOT NULL,
|
|
98434
|
+
target_id TEXT NOT NULL,
|
|
98435
|
+
reason TEXT,
|
|
98436
|
+
timestamp TEXT NOT NULL,
|
|
98437
|
+
event_json TEXT
|
|
98438
|
+
);
|
|
98439
|
+
|
|
98440
|
+
CREATE TABLE IF NOT EXISTS memory_recall_usage (
|
|
98441
|
+
id TEXT PRIMARY KEY,
|
|
98442
|
+
bundle_id TEXT NOT NULL,
|
|
98443
|
+
timestamp TEXT NOT NULL,
|
|
98444
|
+
usage_json TEXT NOT NULL
|
|
98445
|
+
);
|
|
98446
|
+
CREATE INDEX IF NOT EXISTS idx_memory_recall_usage_bundle
|
|
98447
|
+
ON memory_recall_usage(bundle_id);
|
|
98448
|
+
`
|
|
98449
|
+
}
|
|
98450
|
+
];
|
|
98451
|
+
|
|
98452
|
+
class SQLiteMemoryProvider {
|
|
98453
|
+
name = "sqlite";
|
|
98454
|
+
rootDirectory;
|
|
98455
|
+
config;
|
|
98456
|
+
initialized = false;
|
|
98457
|
+
db = null;
|
|
98458
|
+
memories = new Map;
|
|
98459
|
+
proposals = new Map;
|
|
98460
|
+
constructor(rootDirectory, config3 = {}) {
|
|
98461
|
+
this.rootDirectory = rootDirectory;
|
|
98462
|
+
this.config = {
|
|
98463
|
+
...DEFAULT_MEMORY_CONFIG,
|
|
98464
|
+
...config3,
|
|
98465
|
+
sqlite: {
|
|
98466
|
+
...DEFAULT_MEMORY_CONFIG.sqlite,
|
|
98467
|
+
...config3.sqlite ?? {}
|
|
98468
|
+
},
|
|
98469
|
+
recall: {
|
|
98470
|
+
...DEFAULT_MEMORY_CONFIG.recall,
|
|
98471
|
+
...config3.recall ?? {},
|
|
98472
|
+
injection: {
|
|
98473
|
+
...DEFAULT_MEMORY_CONFIG.recall.injection,
|
|
98474
|
+
...config3.recall?.injection ?? {}
|
|
98475
|
+
}
|
|
98476
|
+
},
|
|
98477
|
+
writes: {
|
|
98478
|
+
...DEFAULT_MEMORY_CONFIG.writes,
|
|
98479
|
+
...config3.writes ?? {}
|
|
98480
|
+
},
|
|
98481
|
+
redaction: {
|
|
98482
|
+
...DEFAULT_MEMORY_CONFIG.redaction,
|
|
98483
|
+
...config3.redaction ?? {}
|
|
98484
|
+
}
|
|
98485
|
+
};
|
|
98486
|
+
}
|
|
98487
|
+
databasePath() {
|
|
98488
|
+
const relativePath = this.config.sqlite.path.replace(/^\.swarm[/\\]?/, "");
|
|
98489
|
+
return validateSwarmPath(this.rootDirectory, relativePath);
|
|
98490
|
+
}
|
|
98491
|
+
async initialize() {
|
|
98492
|
+
if (this.initialized)
|
|
98493
|
+
return;
|
|
98494
|
+
const dbPath = this.databasePath();
|
|
98495
|
+
mkdirSync24(path96.dirname(dbPath), { recursive: true });
|
|
98496
|
+
const Db = loadDatabaseCtor2();
|
|
98497
|
+
this.db = new Db(dbPath);
|
|
98498
|
+
this.db.run("PRAGMA journal_mode = WAL;");
|
|
98499
|
+
this.db.run("PRAGMA synchronous = NORMAL;");
|
|
98500
|
+
const busyTimeoutMs = Math.min(60000, Math.max(0, Math.trunc(this.config.sqlite.busyTimeoutMs)));
|
|
98501
|
+
this.db.run(`PRAGMA busy_timeout = ${busyTimeoutMs};`);
|
|
98502
|
+
this.db.run("PRAGMA foreign_keys = ON;");
|
|
98503
|
+
this.runMigrations();
|
|
98504
|
+
const memoryLoad = this.loadMemories();
|
|
98505
|
+
const proposalLoad = this.loadProposals();
|
|
98506
|
+
this.memories = new Map(memoryLoad.records.map((record3) => [record3.id, record3]));
|
|
98507
|
+
this.proposals = new Map(proposalLoad.records.map((proposal) => [proposal.id, proposal]));
|
|
98508
|
+
this.initialized = true;
|
|
98509
|
+
if (memoryLoad.invalidCount > 0) {
|
|
98510
|
+
await this.event("invalid_load", "memory_items", `${memoryLoad.invalidCount} invalid SQLite memory row(s) skipped`);
|
|
98511
|
+
}
|
|
98512
|
+
if (proposalLoad.invalidCount > 0) {
|
|
98513
|
+
await this.event("invalid_load", "memory_proposals", `${proposalLoad.invalidCount} invalid SQLite proposal row(s) skipped`);
|
|
98514
|
+
}
|
|
98515
|
+
}
|
|
98516
|
+
async upsert(record3) {
|
|
98517
|
+
await this.initialize();
|
|
98518
|
+
const existing = this.memories.get(record3.id);
|
|
98519
|
+
if (existing?.metadata.deleted === true) {
|
|
98520
|
+
throw new MemoryValidationError("memory is tombstoned and cannot be upserted");
|
|
98521
|
+
}
|
|
98522
|
+
const next = validateMemoryRecordRules({
|
|
98523
|
+
...record3,
|
|
98524
|
+
createdAt: existing?.createdAt ?? record3.createdAt
|
|
98525
|
+
}, { rejectDurableSecrets: this.config.redaction.rejectDurableSecrets });
|
|
98526
|
+
this.memories.set(next.id, next);
|
|
98527
|
+
this.writeMemory(next);
|
|
98528
|
+
await this.event("upsert", next.id);
|
|
98529
|
+
return next;
|
|
98530
|
+
}
|
|
98531
|
+
async get(id) {
|
|
98532
|
+
await this.initialize();
|
|
98533
|
+
return this.memories.get(id) ?? null;
|
|
98534
|
+
}
|
|
98535
|
+
async delete(id, reason) {
|
|
98536
|
+
await this.initialize();
|
|
98537
|
+
const existing = this.memories.get(id);
|
|
98538
|
+
if (!existing)
|
|
98539
|
+
return;
|
|
98540
|
+
if (this.config.hardDelete) {
|
|
98541
|
+
this.memories.delete(id);
|
|
98542
|
+
this.requireDb().run("DELETE FROM memory_items WHERE id = ?", [id]);
|
|
98543
|
+
} else {
|
|
98544
|
+
const tombstone = {
|
|
98545
|
+
...existing,
|
|
98546
|
+
updatedAt: new Date().toISOString(),
|
|
98547
|
+
metadata: { ...existing.metadata, deleted: true, deleteReason: reason }
|
|
98548
|
+
};
|
|
98549
|
+
this.memories.set(id, tombstone);
|
|
98550
|
+
this.writeMemory(tombstone);
|
|
98551
|
+
}
|
|
98552
|
+
await this.event("delete", id, reason);
|
|
98553
|
+
}
|
|
98554
|
+
async recall(request) {
|
|
98555
|
+
return (await this.recallWithDiagnostics(request)).items;
|
|
98556
|
+
}
|
|
98557
|
+
async recallWithDiagnostics(request) {
|
|
98558
|
+
await this.initialize();
|
|
98559
|
+
const records = await this.list({
|
|
98560
|
+
scopes: request.scopes,
|
|
98561
|
+
kinds: request.kinds,
|
|
98562
|
+
includeExpired: request.includeExpired
|
|
98563
|
+
});
|
|
98564
|
+
const result = scoreMemoryRecordsWithDiagnostics(records, request);
|
|
98565
|
+
return {
|
|
98566
|
+
items: result.items.slice(0, request.maxItems),
|
|
98567
|
+
diagnostics: {
|
|
98568
|
+
...result.diagnostics,
|
|
98569
|
+
returnedCount: Math.min(result.diagnostics.returnedCount, request.maxItems)
|
|
98570
|
+
}
|
|
98571
|
+
};
|
|
98572
|
+
}
|
|
98573
|
+
async recordRecallUsage(event) {
|
|
98574
|
+
await this.initialize();
|
|
98575
|
+
this.requireDb().run(`INSERT INTO memory_recall_usage (
|
|
98576
|
+
id,
|
|
98577
|
+
bundle_id,
|
|
98578
|
+
timestamp,
|
|
98579
|
+
usage_json
|
|
98580
|
+
) VALUES (?, ?, ?, ?)`, [randomUUID9(), event.bundleId, event.timestamp, JSON.stringify(event)]);
|
|
98581
|
+
await this.event("recall", event.bundleId, JSON.stringify(event));
|
|
98582
|
+
}
|
|
98583
|
+
async list(filter = {}) {
|
|
98584
|
+
await this.initialize();
|
|
98585
|
+
let records = Array.from(this.memories.values());
|
|
98586
|
+
if (filter.scopes && filter.scopes.length > 0) {
|
|
98587
|
+
records = records.filter((record3) => scopeAllowed(record3.scope, filter.scopes ?? []));
|
|
98588
|
+
}
|
|
98589
|
+
if (filter.kinds && filter.kinds.length > 0) {
|
|
98590
|
+
records = records.filter((record3) => filter.kinds?.includes(record3.kind));
|
|
98591
|
+
}
|
|
98592
|
+
if (!filter.includeExpired) {
|
|
98593
|
+
const now = Date.now();
|
|
98594
|
+
records = records.filter((record3) => {
|
|
98595
|
+
if (!record3.expiresAt)
|
|
98596
|
+
return true;
|
|
98597
|
+
const expires = Date.parse(record3.expiresAt);
|
|
98598
|
+
return !Number.isFinite(expires) || expires > now;
|
|
98599
|
+
});
|
|
98600
|
+
}
|
|
98601
|
+
records = records.filter((record3) => !record3.supersededBy && record3.metadata.deleted !== true);
|
|
98602
|
+
records.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
98603
|
+
return records.slice(0, filter.limit ?? records.length);
|
|
98604
|
+
}
|
|
98605
|
+
async createProposal(proposal) {
|
|
98606
|
+
await this.initialize();
|
|
98607
|
+
const next = validateMemoryProposal(proposal);
|
|
98608
|
+
if (next.proposedRecord) {
|
|
98609
|
+
validateMemoryRecordRules(next.proposedRecord, {
|
|
98610
|
+
rejectDurableSecrets: this.config.redaction.rejectDurableSecrets
|
|
98611
|
+
});
|
|
98612
|
+
}
|
|
98613
|
+
this.proposals.set(next.id, next);
|
|
98614
|
+
this.requireDb().run(`INSERT OR REPLACE INTO memory_proposals (
|
|
98615
|
+
id,
|
|
98616
|
+
status,
|
|
98617
|
+
created_at,
|
|
98618
|
+
proposal_json
|
|
98619
|
+
) VALUES (?, ?, ?, ?)`, [next.id, next.status, next.createdAt, JSON.stringify(next)]);
|
|
98620
|
+
await this.event("proposal", next.id);
|
|
98621
|
+
return next;
|
|
98622
|
+
}
|
|
98623
|
+
async listProposals(filter = {}) {
|
|
98624
|
+
await this.initialize();
|
|
98625
|
+
let proposals = Array.from(this.proposals.values());
|
|
98626
|
+
if (filter.status) {
|
|
98627
|
+
proposals = proposals.filter((proposal) => proposal.status === filter.status);
|
|
98628
|
+
}
|
|
98629
|
+
proposals.sort((a, b) => b.createdAt.localeCompare(a.createdAt));
|
|
98630
|
+
return proposals.slice(0, filter.limit ?? proposals.length);
|
|
98631
|
+
}
|
|
98632
|
+
close() {
|
|
98633
|
+
if (!this.db)
|
|
98634
|
+
return;
|
|
98635
|
+
this.db.close();
|
|
98636
|
+
this.db = null;
|
|
98637
|
+
this.initialized = false;
|
|
98638
|
+
}
|
|
98639
|
+
runMigrations() {
|
|
98640
|
+
const db = this.requireDb();
|
|
98641
|
+
db.run(`CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
98642
|
+
version INTEGER PRIMARY KEY,
|
|
98643
|
+
name TEXT NOT NULL,
|
|
98644
|
+
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
98645
|
+
)`);
|
|
98646
|
+
const row = db.query("SELECT MAX(version) as version FROM schema_migrations").get();
|
|
98647
|
+
const currentVersion = row?.version ?? 0;
|
|
98648
|
+
for (const migration of MIGRATIONS2) {
|
|
98649
|
+
if (migration.version <= currentVersion)
|
|
98650
|
+
continue;
|
|
98651
|
+
const apply = db.transaction(() => {
|
|
98652
|
+
for (const statement of splitSql(migration.sql)) {
|
|
98653
|
+
db.run(statement);
|
|
98654
|
+
}
|
|
98655
|
+
db.run("INSERT INTO schema_migrations (version, name) VALUES (?, ?)", [
|
|
98656
|
+
migration.version,
|
|
98657
|
+
migration.name
|
|
98658
|
+
]);
|
|
98659
|
+
this.insertEvent("migration", String(migration.version), migration.name);
|
|
98660
|
+
});
|
|
98661
|
+
apply();
|
|
98662
|
+
}
|
|
98663
|
+
}
|
|
98664
|
+
loadMemories() {
|
|
98665
|
+
const rows = this.requireDb().query("SELECT id, record_json FROM memory_items ORDER BY updated_at ASC").all();
|
|
98666
|
+
const records = [];
|
|
98667
|
+
let invalidCount = 0;
|
|
98668
|
+
for (const row of rows) {
|
|
98669
|
+
try {
|
|
98670
|
+
records.push(validateMemoryRecordRules(JSON.parse(row.record_json), {
|
|
98671
|
+
rejectDurableSecrets: this.config.redaction.rejectDurableSecrets
|
|
98672
|
+
}));
|
|
98673
|
+
} catch {
|
|
98674
|
+
invalidCount++;
|
|
98675
|
+
}
|
|
98676
|
+
}
|
|
98677
|
+
return { records, invalidCount };
|
|
98678
|
+
}
|
|
98679
|
+
loadProposals() {
|
|
98680
|
+
const rows = this.requireDb().query("SELECT id, proposal_json FROM memory_proposals ORDER BY created_at ASC").all();
|
|
98681
|
+
const records = [];
|
|
98682
|
+
let invalidCount = 0;
|
|
98683
|
+
for (const row of rows) {
|
|
98684
|
+
try {
|
|
98685
|
+
const proposal = validateMemoryProposal(JSON.parse(row.proposal_json));
|
|
98686
|
+
if (proposal.proposedRecord) {
|
|
98687
|
+
validateMemoryRecordRules(proposal.proposedRecord, {
|
|
98688
|
+
rejectDurableSecrets: this.config.redaction.rejectDurableSecrets
|
|
98689
|
+
});
|
|
98690
|
+
}
|
|
98691
|
+
records.push(proposal);
|
|
98692
|
+
} catch {
|
|
98693
|
+
invalidCount++;
|
|
98694
|
+
}
|
|
98695
|
+
}
|
|
98696
|
+
return { records, invalidCount };
|
|
98697
|
+
}
|
|
98698
|
+
writeMemory(record3) {
|
|
98699
|
+
this.requireDb().run(`INSERT OR REPLACE INTO memory_items (
|
|
98700
|
+
id,
|
|
98701
|
+
scope_key,
|
|
98702
|
+
kind,
|
|
98703
|
+
updated_at,
|
|
98704
|
+
expires_at,
|
|
98705
|
+
superseded_by,
|
|
98706
|
+
deleted,
|
|
98707
|
+
record_json
|
|
98708
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
98709
|
+
record3.id,
|
|
98710
|
+
JSON.stringify(record3.scope),
|
|
98711
|
+
record3.kind,
|
|
98712
|
+
record3.updatedAt,
|
|
98713
|
+
record3.expiresAt ?? null,
|
|
98714
|
+
record3.supersededBy ?? null,
|
|
98715
|
+
record3.metadata.deleted === true ? 1 : 0,
|
|
98716
|
+
JSON.stringify(record3)
|
|
98717
|
+
]);
|
|
98718
|
+
}
|
|
98719
|
+
async event(operation, targetId, reason) {
|
|
98720
|
+
this.insertEvent(operation, targetId, reason);
|
|
98721
|
+
}
|
|
98722
|
+
insertEvent(operation, targetId, reason) {
|
|
98723
|
+
this.requireDb().run(`INSERT INTO memory_events (
|
|
98724
|
+
id,
|
|
98725
|
+
operation,
|
|
98726
|
+
target_id,
|
|
98727
|
+
reason,
|
|
98728
|
+
timestamp,
|
|
98729
|
+
event_json
|
|
98730
|
+
) VALUES (?, ?, ?, ?, ?, ?)`, [
|
|
98731
|
+
randomUUID9(),
|
|
98732
|
+
operation,
|
|
98733
|
+
targetId,
|
|
98734
|
+
reason ?? null,
|
|
98735
|
+
new Date().toISOString(),
|
|
98736
|
+
reason ? JSON.stringify({ reason }) : null
|
|
98737
|
+
]);
|
|
98738
|
+
}
|
|
98739
|
+
requireDb() {
|
|
98740
|
+
if (!this.db)
|
|
98741
|
+
throw new Error("SQLite memory provider is not initialized");
|
|
98742
|
+
return this.db;
|
|
98743
|
+
}
|
|
98744
|
+
}
|
|
98745
|
+
function splitSql(sql) {
|
|
98746
|
+
return sql.split(";").map((statement) => statement.trim()).filter(Boolean);
|
|
98747
|
+
}
|
|
98748
|
+
|
|
98376
98749
|
// src/memory/gateway.ts
|
|
98377
98750
|
class MemoryGateway {
|
|
98378
98751
|
context;
|
|
@@ -98382,16 +98755,19 @@ class MemoryGateway {
|
|
|
98382
98755
|
constructor(context, options = {}) {
|
|
98383
98756
|
this.context = context;
|
|
98384
98757
|
this.config = resolveMemoryConfig(options.config ?? DEFAULT_MEMORY_CONFIG);
|
|
98385
|
-
this.provider = options.provider ??
|
|
98758
|
+
this.provider = options.provider ?? createConfiguredMemoryProvider(context.directory, this.config);
|
|
98386
98759
|
this.now = options.now ?? (() => new Date);
|
|
98387
98760
|
}
|
|
98388
98761
|
isEnabled() {
|
|
98389
98762
|
return this.config.enabled;
|
|
98390
98763
|
}
|
|
98764
|
+
async dispose() {
|
|
98765
|
+
await this.provider.close?.();
|
|
98766
|
+
}
|
|
98391
98767
|
deriveAllowedScopes() {
|
|
98392
|
-
const resolvedRoot =
|
|
98393
|
-
const repoId = createStableId(readGitRemoteUrl(resolvedRoot) ??
|
|
98394
|
-
const workspaceId = createStableId(
|
|
98768
|
+
const resolvedRoot = path97.resolve(this.context.directory);
|
|
98769
|
+
const repoId = createStableId(readGitRemoteUrl(resolvedRoot) ?? path97.basename(resolvedRoot));
|
|
98770
|
+
const workspaceId = createStableId(path97.dirname(resolvedRoot));
|
|
98395
98771
|
const scopes = [
|
|
98396
98772
|
{ type: "workspace", workspaceId },
|
|
98397
98773
|
{
|
|
@@ -98591,6 +98967,12 @@ class MemoryGateway {
|
|
|
98591
98967
|
function createMemoryGateway(context, options = {}) {
|
|
98592
98968
|
return new MemoryGateway(context, options);
|
|
98593
98969
|
}
|
|
98970
|
+
function createConfiguredMemoryProvider(directory, config3) {
|
|
98971
|
+
if (config3.provider === "sqlite") {
|
|
98972
|
+
return new SQLiteMemoryProvider(directory, config3);
|
|
98973
|
+
}
|
|
98974
|
+
return new LocalJsonlMemoryProvider(directory, config3);
|
|
98975
|
+
}
|
|
98594
98976
|
function sourceFromEvidence(evidenceRefs, context) {
|
|
98595
98977
|
const first = evidenceRefs[0];
|
|
98596
98978
|
if (!first) {
|
|
@@ -98612,7 +98994,7 @@ var gitRemoteUrlCache = new Map;
|
|
|
98612
98994
|
function readGitRemoteUrl(directory) {
|
|
98613
98995
|
if (gitRemoteUrlCache.has(directory))
|
|
98614
98996
|
return gitRemoteUrlCache.get(directory);
|
|
98615
|
-
const gitConfigPath =
|
|
98997
|
+
const gitConfigPath = path97.join(directory, ".git", "config");
|
|
98616
98998
|
if (!existsSync50(gitConfigPath)) {
|
|
98617
98999
|
gitRemoteUrlCache.set(directory, undefined);
|
|
98618
99000
|
return;
|
|
@@ -98660,7 +99042,7 @@ function scopeKey(scope) {
|
|
|
98660
99042
|
workspaceId: scope.workspaceId,
|
|
98661
99043
|
projectId: scope.projectId,
|
|
98662
99044
|
repoId: scope.repoId,
|
|
98663
|
-
repoRoot: scope.repoRoot ?
|
|
99045
|
+
repoRoot: scope.repoRoot ? path97.resolve(scope.repoRoot) : undefined,
|
|
98664
99046
|
runId: scope.runId,
|
|
98665
99047
|
agentId: scope.agentId
|
|
98666
99048
|
});
|
|
@@ -98907,12 +99289,12 @@ function buildScopesFromInput(input) {
|
|
|
98907
99289
|
// src/memory/run-log.ts
|
|
98908
99290
|
init_utils2();
|
|
98909
99291
|
import { appendFile as appendFile12, mkdir as mkdir19 } from "node:fs/promises";
|
|
98910
|
-
import * as
|
|
99292
|
+
import * as path98 from "node:path";
|
|
98911
99293
|
async function appendMemoryRunLog(directory, runId, event) {
|
|
98912
99294
|
const safeRunId = sanitizeRunId(runId);
|
|
98913
|
-
const relativePath =
|
|
99295
|
+
const relativePath = path98.join("runs", safeRunId, "memory.jsonl");
|
|
98914
99296
|
const filePath = validateSwarmPath(directory, relativePath);
|
|
98915
|
-
await mkdir19(
|
|
99297
|
+
await mkdir19(path98.dirname(filePath), { recursive: true });
|
|
98916
99298
|
await appendFile12(filePath, `${JSON.stringify({
|
|
98917
99299
|
...event,
|
|
98918
99300
|
runId: safeRunId,
|
|
@@ -99690,16 +100072,16 @@ init_telemetry();
|
|
|
99690
100072
|
|
|
99691
100073
|
// src/prm/replay.ts
|
|
99692
100074
|
import { promises as fs68 } from "node:fs";
|
|
99693
|
-
import
|
|
100075
|
+
import path99 from "node:path";
|
|
99694
100076
|
function isPathSafe2(targetPath, basePath) {
|
|
99695
|
-
const resolvedTarget =
|
|
99696
|
-
const resolvedBase =
|
|
99697
|
-
const rel =
|
|
99698
|
-
return !rel.startsWith("..") && !
|
|
100077
|
+
const resolvedTarget = path99.resolve(targetPath);
|
|
100078
|
+
const resolvedBase = path99.resolve(basePath);
|
|
100079
|
+
const rel = path99.relative(resolvedBase, resolvedTarget);
|
|
100080
|
+
return !rel.startsWith("..") && !path99.isAbsolute(rel);
|
|
99699
100081
|
}
|
|
99700
100082
|
function isWithinReplaysDir(targetPath) {
|
|
99701
|
-
const resolved =
|
|
99702
|
-
const parts2 = resolved.split(
|
|
100083
|
+
const resolved = path99.resolve(targetPath);
|
|
100084
|
+
const parts2 = resolved.split(path99.sep);
|
|
99703
100085
|
for (let i2 = 0;i2 < parts2.length - 1; i2++) {
|
|
99704
100086
|
if (parts2[i2] === ".swarm" && parts2[i2 + 1] === "replays") {
|
|
99705
100087
|
return true;
|
|
@@ -99712,10 +100094,10 @@ function sanitizeFilename(input) {
|
|
|
99712
100094
|
}
|
|
99713
100095
|
async function startReplayRecording(sessionID, directory) {
|
|
99714
100096
|
try {
|
|
99715
|
-
const replayDir =
|
|
100097
|
+
const replayDir = path99.join(directory, ".swarm", "replays");
|
|
99716
100098
|
const safeSessionID = sanitizeFilename(sessionID);
|
|
99717
100099
|
const filename = `${safeSessionID}-${Date.now()}.jsonl`;
|
|
99718
|
-
const filepath =
|
|
100100
|
+
const filepath = path99.join(replayDir, filename);
|
|
99719
100101
|
if (!isPathSafe2(filepath, replayDir)) {
|
|
99720
100102
|
console.warn(`[replay] Invalid path detected - path traversal attempt blocked for session ${sessionID}`);
|
|
99721
100103
|
return null;
|
|
@@ -100096,7 +100478,7 @@ init_telemetry();
|
|
|
100096
100478
|
init_dist();
|
|
100097
100479
|
init_create_tool();
|
|
100098
100480
|
import * as fs69 from "node:fs";
|
|
100099
|
-
import * as
|
|
100481
|
+
import * as path100 from "node:path";
|
|
100100
100482
|
init_path_security();
|
|
100101
100483
|
var WINDOWS_RESERVED_NAMES2 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
100102
100484
|
function containsWindowsAttacks2(str) {
|
|
@@ -100113,14 +100495,14 @@ function containsWindowsAttacks2(str) {
|
|
|
100113
100495
|
}
|
|
100114
100496
|
function isPathInWorkspace2(filePath, workspace) {
|
|
100115
100497
|
try {
|
|
100116
|
-
const resolvedPath =
|
|
100498
|
+
const resolvedPath = path100.resolve(workspace, filePath);
|
|
100117
100499
|
if (!fs69.existsSync(resolvedPath)) {
|
|
100118
100500
|
return true;
|
|
100119
100501
|
}
|
|
100120
100502
|
const realWorkspace = fs69.realpathSync(workspace);
|
|
100121
100503
|
const realResolvedPath = fs69.realpathSync(resolvedPath);
|
|
100122
|
-
const relativePath =
|
|
100123
|
-
if (relativePath.startsWith("..") ||
|
|
100504
|
+
const relativePath = path100.relative(realWorkspace, realResolvedPath);
|
|
100505
|
+
if (relativePath.startsWith("..") || path100.isAbsolute(relativePath)) {
|
|
100124
100506
|
return false;
|
|
100125
100507
|
}
|
|
100126
100508
|
return true;
|
|
@@ -100129,7 +100511,7 @@ function isPathInWorkspace2(filePath, workspace) {
|
|
|
100129
100511
|
}
|
|
100130
100512
|
}
|
|
100131
100513
|
function processFile2(file3, cwd, exportedOnly) {
|
|
100132
|
-
const ext =
|
|
100514
|
+
const ext = path100.extname(file3);
|
|
100133
100515
|
if (containsControlChars(file3)) {
|
|
100134
100516
|
return {
|
|
100135
100517
|
file: file3,
|
|
@@ -100162,7 +100544,7 @@ function processFile2(file3, cwd, exportedOnly) {
|
|
|
100162
100544
|
errorType: "path-outside-workspace"
|
|
100163
100545
|
};
|
|
100164
100546
|
}
|
|
100165
|
-
const fullPath =
|
|
100547
|
+
const fullPath = path100.join(cwd, file3);
|
|
100166
100548
|
if (!fs69.existsSync(fullPath)) {
|
|
100167
100549
|
return {
|
|
100168
100550
|
file: file3,
|
|
@@ -100454,15 +100836,15 @@ init_task_id();
|
|
|
100454
100836
|
init_create_tool();
|
|
100455
100837
|
init_resolve_working_directory();
|
|
100456
100838
|
import * as fs70 from "node:fs";
|
|
100457
|
-
import * as
|
|
100839
|
+
import * as path101 from "node:path";
|
|
100458
100840
|
var EVIDENCE_DIR = ".swarm/evidence";
|
|
100459
100841
|
function isValidTaskId3(taskId) {
|
|
100460
100842
|
return isStrictTaskId(taskId);
|
|
100461
100843
|
}
|
|
100462
100844
|
function isPathWithinSwarm(filePath, workspaceRoot) {
|
|
100463
|
-
const normalizedWorkspace =
|
|
100464
|
-
const swarmPath =
|
|
100465
|
-
const normalizedPath =
|
|
100845
|
+
const normalizedWorkspace = path101.resolve(workspaceRoot);
|
|
100846
|
+
const swarmPath = path101.join(normalizedWorkspace, ".swarm", "evidence");
|
|
100847
|
+
const normalizedPath = path101.resolve(filePath);
|
|
100466
100848
|
return normalizedPath.startsWith(swarmPath);
|
|
100467
100849
|
}
|
|
100468
100850
|
function readEvidenceFile(evidencePath) {
|
|
@@ -100543,7 +100925,7 @@ var check_gate_status = createSwarmTool({
|
|
|
100543
100925
|
};
|
|
100544
100926
|
return JSON.stringify(errorResult, null, 2);
|
|
100545
100927
|
}
|
|
100546
|
-
const evidencePath =
|
|
100928
|
+
const evidencePath = path101.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
|
|
100547
100929
|
if (!isPathWithinSwarm(evidencePath, directory)) {
|
|
100548
100930
|
const errorResult = {
|
|
100549
100931
|
taskId: taskIdInput,
|
|
@@ -100640,7 +101022,7 @@ init_state();
|
|
|
100640
101022
|
init_create_tool();
|
|
100641
101023
|
init_resolve_working_directory();
|
|
100642
101024
|
import * as fs71 from "node:fs";
|
|
100643
|
-
import * as
|
|
101025
|
+
import * as path102 from "node:path";
|
|
100644
101026
|
function extractMatches(regex, text) {
|
|
100645
101027
|
return Array.from(text.matchAll(regex));
|
|
100646
101028
|
}
|
|
@@ -100792,10 +101174,10 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
100792
101174
|
let hasFileReadFailure = false;
|
|
100793
101175
|
for (const filePath of fileTargets) {
|
|
100794
101176
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
100795
|
-
const resolvedPath =
|
|
100796
|
-
const projectRoot =
|
|
100797
|
-
const relative21 =
|
|
100798
|
-
const withinProject = relative21 === "" || !relative21.startsWith("..") && !
|
|
101177
|
+
const resolvedPath = path102.resolve(directory, normalizedPath);
|
|
101178
|
+
const projectRoot = path102.resolve(directory);
|
|
101179
|
+
const relative21 = path102.relative(projectRoot, resolvedPath);
|
|
101180
|
+
const withinProject = relative21 === "" || !relative21.startsWith("..") && !path102.isAbsolute(relative21);
|
|
100799
101181
|
if (!withinProject) {
|
|
100800
101182
|
blockedTasks.push({
|
|
100801
101183
|
task_id: task.id,
|
|
@@ -100850,8 +101232,8 @@ async function executeCompletionVerify(args2, directory) {
|
|
|
100850
101232
|
blockedTasks
|
|
100851
101233
|
};
|
|
100852
101234
|
try {
|
|
100853
|
-
const evidenceDir =
|
|
100854
|
-
const evidencePath =
|
|
101235
|
+
const evidenceDir = path102.join(directory, ".swarm", "evidence", `${phase}`);
|
|
101236
|
+
const evidencePath = path102.join(evidenceDir, "completion-verify.json");
|
|
100855
101237
|
fs71.mkdirSync(evidenceDir, { recursive: true });
|
|
100856
101238
|
const evidenceBundle = {
|
|
100857
101239
|
schema_version: "1.0.0",
|
|
@@ -100928,11 +101310,11 @@ var completion_verify = createSwarmTool({
|
|
|
100928
101310
|
// src/tools/complexity-hotspots.ts
|
|
100929
101311
|
init_zod();
|
|
100930
101312
|
import * as fs73 from "node:fs";
|
|
100931
|
-
import * as
|
|
101313
|
+
import * as path104 from "node:path";
|
|
100932
101314
|
|
|
100933
101315
|
// src/quality/metrics.ts
|
|
100934
101316
|
import * as fs72 from "node:fs";
|
|
100935
|
-
import * as
|
|
101317
|
+
import * as path103 from "node:path";
|
|
100936
101318
|
var MAX_FILE_SIZE_BYTES4 = 256 * 1024;
|
|
100937
101319
|
var MIN_DUPLICATION_LINES = 10;
|
|
100938
101320
|
function estimateCyclomaticComplexity(content) {
|
|
@@ -100984,7 +101366,7 @@ async function computeComplexityDelta(files, workingDir) {
|
|
|
100984
101366
|
let totalComplexity = 0;
|
|
100985
101367
|
const analyzedFiles = [];
|
|
100986
101368
|
for (const file3 of files) {
|
|
100987
|
-
const fullPath =
|
|
101369
|
+
const fullPath = path103.isAbsolute(file3) ? file3 : path103.join(workingDir, file3);
|
|
100988
101370
|
if (!fs72.existsSync(fullPath)) {
|
|
100989
101371
|
continue;
|
|
100990
101372
|
}
|
|
@@ -101107,7 +101489,7 @@ function countGoExports(content) {
|
|
|
101107
101489
|
function getExportCountForFile(filePath) {
|
|
101108
101490
|
try {
|
|
101109
101491
|
const content = fs72.readFileSync(filePath, "utf-8");
|
|
101110
|
-
const ext =
|
|
101492
|
+
const ext = path103.extname(filePath).toLowerCase();
|
|
101111
101493
|
switch (ext) {
|
|
101112
101494
|
case ".ts":
|
|
101113
101495
|
case ".tsx":
|
|
@@ -101133,7 +101515,7 @@ async function computePublicApiDelta(files, workingDir) {
|
|
|
101133
101515
|
let totalExports = 0;
|
|
101134
101516
|
const analyzedFiles = [];
|
|
101135
101517
|
for (const file3 of files) {
|
|
101136
|
-
const fullPath =
|
|
101518
|
+
const fullPath = path103.isAbsolute(file3) ? file3 : path103.join(workingDir, file3);
|
|
101137
101519
|
if (!fs72.existsSync(fullPath)) {
|
|
101138
101520
|
continue;
|
|
101139
101521
|
}
|
|
@@ -101167,7 +101549,7 @@ async function computeDuplicationRatio(files, workingDir) {
|
|
|
101167
101549
|
let duplicateLines = 0;
|
|
101168
101550
|
const analyzedFiles = [];
|
|
101169
101551
|
for (const file3 of files) {
|
|
101170
|
-
const fullPath =
|
|
101552
|
+
const fullPath = path103.isAbsolute(file3) ? file3 : path103.join(workingDir, file3);
|
|
101171
101553
|
if (!fs72.existsSync(fullPath)) {
|
|
101172
101554
|
continue;
|
|
101173
101555
|
}
|
|
@@ -101200,8 +101582,8 @@ function countCodeLines(content) {
|
|
|
101200
101582
|
return lines.length;
|
|
101201
101583
|
}
|
|
101202
101584
|
function isTestFile(filePath) {
|
|
101203
|
-
const basename15 =
|
|
101204
|
-
const _ext =
|
|
101585
|
+
const basename15 = path103.basename(filePath);
|
|
101586
|
+
const _ext = path103.extname(filePath).toLowerCase();
|
|
101205
101587
|
const testPatterns = [
|
|
101206
101588
|
".test.",
|
|
101207
101589
|
".spec.",
|
|
@@ -101282,8 +101664,8 @@ function matchGlobSegment(globSegments, pathSegments) {
|
|
|
101282
101664
|
}
|
|
101283
101665
|
return gIndex === globSegments.length && pIndex === pathSegments.length;
|
|
101284
101666
|
}
|
|
101285
|
-
function matchesGlobSegment(
|
|
101286
|
-
const normalizedPath =
|
|
101667
|
+
function matchesGlobSegment(path104, glob) {
|
|
101668
|
+
const normalizedPath = path104.replace(/\\/g, "/");
|
|
101287
101669
|
const normalizedGlob = glob.replace(/\\/g, "/");
|
|
101288
101670
|
if (normalizedPath.includes("//")) {
|
|
101289
101671
|
return false;
|
|
@@ -101314,8 +101696,8 @@ function simpleGlobToRegex2(glob) {
|
|
|
101314
101696
|
function hasGlobstar(glob) {
|
|
101315
101697
|
return glob.includes("**");
|
|
101316
101698
|
}
|
|
101317
|
-
function globMatches(
|
|
101318
|
-
const normalizedPath =
|
|
101699
|
+
function globMatches(path104, glob) {
|
|
101700
|
+
const normalizedPath = path104.replace(/\\/g, "/");
|
|
101319
101701
|
if (!glob || glob === "") {
|
|
101320
101702
|
if (normalizedPath.includes("//")) {
|
|
101321
101703
|
return false;
|
|
@@ -101351,7 +101733,7 @@ function shouldExcludeFile(filePath, excludeGlobs) {
|
|
|
101351
101733
|
async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
101352
101734
|
let testLines = 0;
|
|
101353
101735
|
let codeLines = 0;
|
|
101354
|
-
const srcDir =
|
|
101736
|
+
const srcDir = path103.join(workingDir, "src");
|
|
101355
101737
|
if (fs72.existsSync(srcDir)) {
|
|
101356
101738
|
await scanDirectoryForLines(srcDir, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
101357
101739
|
codeLines += lines;
|
|
@@ -101359,14 +101741,14 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
101359
101741
|
}
|
|
101360
101742
|
const possibleSrcDirs = ["lib", "app", "source", "core"];
|
|
101361
101743
|
for (const dir of possibleSrcDirs) {
|
|
101362
|
-
const dirPath =
|
|
101744
|
+
const dirPath = path103.join(workingDir, dir);
|
|
101363
101745
|
if (fs72.existsSync(dirPath)) {
|
|
101364
101746
|
await scanDirectoryForLines(dirPath, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
101365
101747
|
codeLines += lines;
|
|
101366
101748
|
});
|
|
101367
101749
|
}
|
|
101368
101750
|
}
|
|
101369
|
-
const testsDir =
|
|
101751
|
+
const testsDir = path103.join(workingDir, "tests");
|
|
101370
101752
|
if (fs72.existsSync(testsDir)) {
|
|
101371
101753
|
await scanDirectoryForLines(testsDir, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
101372
101754
|
testLines += lines;
|
|
@@ -101374,7 +101756,7 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
101374
101756
|
}
|
|
101375
101757
|
const possibleTestDirs = ["test", "__tests__", "specs"];
|
|
101376
101758
|
for (const dir of possibleTestDirs) {
|
|
101377
|
-
const dirPath =
|
|
101759
|
+
const dirPath = path103.join(workingDir, dir);
|
|
101378
101760
|
if (fs72.existsSync(dirPath) && dirPath !== testsDir) {
|
|
101379
101761
|
await scanDirectoryForLines(dirPath, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
101380
101762
|
testLines += lines;
|
|
@@ -101389,7 +101771,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
101389
101771
|
try {
|
|
101390
101772
|
const entries = fs72.readdirSync(dirPath, { withFileTypes: true });
|
|
101391
101773
|
for (const entry of entries) {
|
|
101392
|
-
const fullPath =
|
|
101774
|
+
const fullPath = path103.join(dirPath, entry.name);
|
|
101393
101775
|
if (entry.isDirectory()) {
|
|
101394
101776
|
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === ".git") {
|
|
101395
101777
|
continue;
|
|
@@ -101397,7 +101779,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
101397
101779
|
await scanDirectoryForLines(fullPath, includeGlobs, excludeGlobs, isTestScan, callback);
|
|
101398
101780
|
} else if (entry.isFile()) {
|
|
101399
101781
|
const relativePath = fullPath.replace(`${dirPath}/`, "");
|
|
101400
|
-
const ext =
|
|
101782
|
+
const ext = path103.extname(entry.name).toLowerCase();
|
|
101401
101783
|
const validExts = [
|
|
101402
101784
|
".ts",
|
|
101403
101785
|
".tsx",
|
|
@@ -101648,7 +102030,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
101648
102030
|
const extSet = new Set(extensions.map((e) => e.startsWith(".") ? e : `.${e}`));
|
|
101649
102031
|
const filteredChurn = new Map;
|
|
101650
102032
|
for (const [file3, count] of churnMap) {
|
|
101651
|
-
const ext =
|
|
102033
|
+
const ext = path104.extname(file3).toLowerCase();
|
|
101652
102034
|
if (extSet.has(ext)) {
|
|
101653
102035
|
filteredChurn.set(file3, count);
|
|
101654
102036
|
}
|
|
@@ -101659,7 +102041,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
101659
102041
|
for (const [file3, churnCount] of filteredChurn) {
|
|
101660
102042
|
let fullPath = file3;
|
|
101661
102043
|
if (!fs73.existsSync(fullPath)) {
|
|
101662
|
-
fullPath =
|
|
102044
|
+
fullPath = path104.join(cwd, file3);
|
|
101663
102045
|
}
|
|
101664
102046
|
const complexity = getComplexityForFile2(fullPath);
|
|
101665
102047
|
if (complexity !== null) {
|
|
@@ -101827,7 +102209,7 @@ ${body2}`);
|
|
|
101827
102209
|
|
|
101828
102210
|
// src/council/council-evidence-writer.ts
|
|
101829
102211
|
init_task_file();
|
|
101830
|
-
import { appendFileSync as appendFileSync12, existsSync as existsSync55, mkdirSync as
|
|
102212
|
+
import { appendFileSync as appendFileSync12, existsSync as existsSync55, mkdirSync as mkdirSync26, readFileSync as readFileSync45 } from "node:fs";
|
|
101831
102213
|
import { join as join88 } from "node:path";
|
|
101832
102214
|
var EVIDENCE_DIR2 = ".swarm/evidence";
|
|
101833
102215
|
var VALID_TASK_ID = /^\d+\.\d+(\.\d+)*$/;
|
|
@@ -101866,7 +102248,7 @@ async function writeCouncilEvidence(workingDir, synthesis) {
|
|
|
101866
102248
|
throw new Error(`writeCouncilEvidence: invalid taskId "${synthesis.taskId}" — must match N.M or N.M.P format`);
|
|
101867
102249
|
}
|
|
101868
102250
|
const dir = join88(workingDir, EVIDENCE_DIR2);
|
|
101869
|
-
|
|
102251
|
+
mkdirSync26(dir, { recursive: true });
|
|
101870
102252
|
const filePath = taskEvidencePath(workingDir, synthesis.taskId);
|
|
101871
102253
|
await _internals45.withTaskEvidenceLock(workingDir, synthesis.taskId, COUNCIL_AGENT_ID, async () => {
|
|
101872
102254
|
const existingRoot = Object.create(null);
|
|
@@ -101904,7 +102286,7 @@ async function writeCouncilEvidence(workingDir, synthesis) {
|
|
|
101904
102286
|
});
|
|
101905
102287
|
try {
|
|
101906
102288
|
const councilDir = join88(workingDir, ".swarm", "council");
|
|
101907
|
-
|
|
102289
|
+
mkdirSync26(councilDir, { recursive: true });
|
|
101908
102290
|
const auditLine = JSON.stringify({
|
|
101909
102291
|
round: synthesis.roundNumber,
|
|
101910
102292
|
verdict: synthesis.overallVerdict,
|
|
@@ -102233,12 +102615,12 @@ function buildFinalCouncilFeedback(projectSummary, verdict, vetoedBy, requiredFi
|
|
|
102233
102615
|
}
|
|
102234
102616
|
|
|
102235
102617
|
// src/council/criteria-store.ts
|
|
102236
|
-
import { existsSync as existsSync56, mkdirSync as
|
|
102618
|
+
import { existsSync as existsSync56, mkdirSync as mkdirSync27, readFileSync as readFileSync46, writeFileSync as writeFileSync17 } from "node:fs";
|
|
102237
102619
|
import { join as join89 } from "node:path";
|
|
102238
102620
|
var COUNCIL_DIR = ".swarm/council";
|
|
102239
102621
|
function writeCriteria(workingDir, taskId, criteria) {
|
|
102240
102622
|
const dir = join89(workingDir, COUNCIL_DIR);
|
|
102241
|
-
|
|
102623
|
+
mkdirSync27(dir, { recursive: true });
|
|
102242
102624
|
const payload = {
|
|
102243
102625
|
taskId,
|
|
102244
102626
|
criteria,
|
|
@@ -102400,7 +102782,7 @@ var submit_council_verdicts = createSwarmTool({
|
|
|
102400
102782
|
init_zod();
|
|
102401
102783
|
init_loader();
|
|
102402
102784
|
import * as fs74 from "node:fs";
|
|
102403
|
-
import * as
|
|
102785
|
+
import * as path105 from "node:path";
|
|
102404
102786
|
|
|
102405
102787
|
// src/council/general-council-advisory.ts
|
|
102406
102788
|
var ADVISORY_HEADER = "[general_council] (advisory; not blocking)";
|
|
@@ -102828,10 +103210,10 @@ var convene_general_council = createSwarmTool({
|
|
|
102828
103210
|
const round1 = input.round1Responses;
|
|
102829
103211
|
const round2 = input.round2Responses ?? [];
|
|
102830
103212
|
const result = synthesizeGeneralCouncil(input.question, input.mode, round1, round2);
|
|
102831
|
-
const evidenceDir =
|
|
103213
|
+
const evidenceDir = path105.join(workingDir, ".swarm", "council", "general");
|
|
102832
103214
|
const safeTimestamp = result.timestamp.replace(/[:.]/g, "-");
|
|
102833
103215
|
const evidenceFile = `${safeTimestamp}-${input.mode}.json`;
|
|
102834
|
-
const evidencePath =
|
|
103216
|
+
const evidencePath = path105.join(evidenceDir, evidenceFile);
|
|
102835
103217
|
try {
|
|
102836
103218
|
await fs74.promises.mkdir(evidenceDir, { recursive: true });
|
|
102837
103219
|
await fs74.promises.writeFile(evidencePath, JSON.stringify(result, null, 2));
|
|
@@ -103076,7 +103458,7 @@ init_state();
|
|
|
103076
103458
|
init_task_id();
|
|
103077
103459
|
init_create_tool();
|
|
103078
103460
|
import * as fs75 from "node:fs";
|
|
103079
|
-
import * as
|
|
103461
|
+
import * as path106 from "node:path";
|
|
103080
103462
|
function validateTaskIdFormat2(taskId) {
|
|
103081
103463
|
return validateTaskIdFormat(taskId);
|
|
103082
103464
|
}
|
|
@@ -103150,8 +103532,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
103150
103532
|
};
|
|
103151
103533
|
}
|
|
103152
103534
|
}
|
|
103153
|
-
normalizedDir =
|
|
103154
|
-
const pathParts = normalizedDir.split(
|
|
103535
|
+
normalizedDir = path106.normalize(args2.working_directory);
|
|
103536
|
+
const pathParts = normalizedDir.split(path106.sep);
|
|
103155
103537
|
if (pathParts.includes("..")) {
|
|
103156
103538
|
return {
|
|
103157
103539
|
success: false,
|
|
@@ -103161,10 +103543,10 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
103161
103543
|
]
|
|
103162
103544
|
};
|
|
103163
103545
|
}
|
|
103164
|
-
const resolvedDir =
|
|
103546
|
+
const resolvedDir = path106.resolve(normalizedDir);
|
|
103165
103547
|
try {
|
|
103166
103548
|
const realPath = fs75.realpathSync(resolvedDir);
|
|
103167
|
-
const planPath2 =
|
|
103549
|
+
const planPath2 = path106.join(realPath, ".swarm", "plan.json");
|
|
103168
103550
|
if (!fs75.existsSync(planPath2)) {
|
|
103169
103551
|
return {
|
|
103170
103552
|
success: false,
|
|
@@ -103185,9 +103567,9 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
103185
103567
|
}
|
|
103186
103568
|
if (normalizedDir && fallbackDir) {
|
|
103187
103569
|
try {
|
|
103188
|
-
const canonicalWorkingDir = fs75.realpathSync(
|
|
103189
|
-
const canonicalProjectRoot = fs75.realpathSync(
|
|
103190
|
-
if (canonicalWorkingDir.startsWith(canonicalProjectRoot +
|
|
103570
|
+
const canonicalWorkingDir = fs75.realpathSync(path106.resolve(normalizedDir));
|
|
103571
|
+
const canonicalProjectRoot = fs75.realpathSync(path106.resolve(fallbackDir));
|
|
103572
|
+
if (canonicalWorkingDir.startsWith(canonicalProjectRoot + path106.sep)) {
|
|
103191
103573
|
return {
|
|
103192
103574
|
success: false,
|
|
103193
103575
|
message: `working_directory "${normalizedDir}" is a subdirectory of the project root. Use the project root "${fallbackDir}" instead.`,
|
|
@@ -103209,7 +103591,7 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
103209
103591
|
};
|
|
103210
103592
|
}
|
|
103211
103593
|
const directory = normalizedDir || fallbackDir;
|
|
103212
|
-
const planPath =
|
|
103594
|
+
const planPath = path106.resolve(directory, ".swarm", "plan.json");
|
|
103213
103595
|
if (!fs75.existsSync(planPath)) {
|
|
103214
103596
|
return {
|
|
103215
103597
|
success: false,
|
|
@@ -103249,8 +103631,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
103249
103631
|
const normalizeErrors = [];
|
|
103250
103632
|
const dir = directory;
|
|
103251
103633
|
const mergedFiles = rawMergedFiles.map((file3) => {
|
|
103252
|
-
if (
|
|
103253
|
-
const relativePath =
|
|
103634
|
+
if (path106.isAbsolute(file3)) {
|
|
103635
|
+
const relativePath = path106.relative(dir, file3).replace(/\\/g, "/");
|
|
103254
103636
|
if (relativePath.startsWith("..")) {
|
|
103255
103637
|
normalizeErrors.push(`Path '${file3}' resolves outside the project directory`);
|
|
103256
103638
|
return file3;
|
|
@@ -103311,7 +103693,7 @@ var declare_scope = createSwarmTool({
|
|
|
103311
103693
|
init_zod();
|
|
103312
103694
|
import * as child_process7 from "node:child_process";
|
|
103313
103695
|
import * as fs76 from "node:fs";
|
|
103314
|
-
import * as
|
|
103696
|
+
import * as path107 from "node:path";
|
|
103315
103697
|
init_create_tool();
|
|
103316
103698
|
var MAX_DIFF_LINES = 500;
|
|
103317
103699
|
var DIFF_TIMEOUT_MS = 30000;
|
|
@@ -103340,20 +103722,20 @@ function validateBase(base) {
|
|
|
103340
103722
|
function validatePaths(paths) {
|
|
103341
103723
|
if (!paths)
|
|
103342
103724
|
return null;
|
|
103343
|
-
for (const
|
|
103344
|
-
if (!
|
|
103725
|
+
for (const path108 of paths) {
|
|
103726
|
+
if (!path108 || path108.length === 0) {
|
|
103345
103727
|
return "empty path not allowed";
|
|
103346
103728
|
}
|
|
103347
|
-
if (
|
|
103729
|
+
if (path108.length > MAX_PATH_LENGTH) {
|
|
103348
103730
|
return `path exceeds maximum length of ${MAX_PATH_LENGTH}`;
|
|
103349
103731
|
}
|
|
103350
|
-
if (SHELL_METACHARACTERS2.test(
|
|
103732
|
+
if (SHELL_METACHARACTERS2.test(path108)) {
|
|
103351
103733
|
return "path contains shell metacharacters";
|
|
103352
103734
|
}
|
|
103353
|
-
if (
|
|
103735
|
+
if (path108.startsWith("-")) {
|
|
103354
103736
|
return 'path cannot start with "-" (option-like arguments not allowed)';
|
|
103355
103737
|
}
|
|
103356
|
-
if (CONTROL_CHAR_PATTERN2.test(
|
|
103738
|
+
if (CONTROL_CHAR_PATTERN2.test(path108)) {
|
|
103357
103739
|
return "path contains control characters";
|
|
103358
103740
|
}
|
|
103359
103741
|
}
|
|
@@ -103461,8 +103843,8 @@ var diff = createSwarmTool({
|
|
|
103461
103843
|
if (parts2.length >= 3) {
|
|
103462
103844
|
const additions = parseInt(parts2[0], 10) || 0;
|
|
103463
103845
|
const deletions = parseInt(parts2[1], 10) || 0;
|
|
103464
|
-
const
|
|
103465
|
-
files.push({ path:
|
|
103846
|
+
const path108 = parts2[2];
|
|
103847
|
+
files.push({ path: path108, additions, deletions });
|
|
103466
103848
|
}
|
|
103467
103849
|
}
|
|
103468
103850
|
const contractChanges = [];
|
|
@@ -103502,7 +103884,7 @@ var diff = createSwarmTool({
|
|
|
103502
103884
|
} else if (base === "unstaged") {
|
|
103503
103885
|
const oldRef = `:${file3.path}`;
|
|
103504
103886
|
oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
|
|
103505
|
-
newContent = fs76.readFileSync(
|
|
103887
|
+
newContent = fs76.readFileSync(path107.join(directory, file3.path), "utf-8");
|
|
103506
103888
|
} else {
|
|
103507
103889
|
const oldRef = `${base}:${file3.path}`;
|
|
103508
103890
|
oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
|
|
@@ -103577,7 +103959,7 @@ var diff = createSwarmTool({
|
|
|
103577
103959
|
init_zod();
|
|
103578
103960
|
import * as child_process8 from "node:child_process";
|
|
103579
103961
|
import * as fs77 from "node:fs";
|
|
103580
|
-
import * as
|
|
103962
|
+
import * as path108 from "node:path";
|
|
103581
103963
|
init_create_tool();
|
|
103582
103964
|
init_resolve_working_directory();
|
|
103583
103965
|
var diff_summary = createSwarmTool({
|
|
@@ -103630,7 +104012,7 @@ var diff_summary = createSwarmTool({
|
|
|
103630
104012
|
}
|
|
103631
104013
|
try {
|
|
103632
104014
|
let oldContent;
|
|
103633
|
-
const newContent = fs77.readFileSync(
|
|
104015
|
+
const newContent = fs77.readFileSync(path108.join(workingDir, filePath), "utf-8");
|
|
103634
104016
|
if (fileExistsInHead) {
|
|
103635
104017
|
oldContent = child_process8.execFileSync("git", ["show", `HEAD:${filePath}`], {
|
|
103636
104018
|
encoding: "utf-8",
|
|
@@ -103859,7 +104241,7 @@ init_zod();
|
|
|
103859
104241
|
init_create_tool();
|
|
103860
104242
|
init_path_security();
|
|
103861
104243
|
import * as fs78 from "node:fs";
|
|
103862
|
-
import * as
|
|
104244
|
+
import * as path109 from "node:path";
|
|
103863
104245
|
var MAX_FILE_SIZE_BYTES6 = 1024 * 1024;
|
|
103864
104246
|
var MAX_EVIDENCE_FILES = 1000;
|
|
103865
104247
|
var EVIDENCE_DIR3 = ".swarm/evidence";
|
|
@@ -103886,9 +104268,9 @@ function validateRequiredTypes(input) {
|
|
|
103886
104268
|
return null;
|
|
103887
104269
|
}
|
|
103888
104270
|
function isPathWithinSwarm2(filePath, cwd) {
|
|
103889
|
-
const normalizedCwd =
|
|
103890
|
-
const swarmPath =
|
|
103891
|
-
const normalizedPath =
|
|
104271
|
+
const normalizedCwd = path109.resolve(cwd);
|
|
104272
|
+
const swarmPath = path109.join(normalizedCwd, ".swarm");
|
|
104273
|
+
const normalizedPath = path109.resolve(filePath);
|
|
103892
104274
|
return normalizedPath.startsWith(swarmPath);
|
|
103893
104275
|
}
|
|
103894
104276
|
function parseCompletedTasks(planContent) {
|
|
@@ -103918,10 +104300,10 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
103918
104300
|
if (!VALID_EVIDENCE_FILENAME_REGEX.test(filename)) {
|
|
103919
104301
|
continue;
|
|
103920
104302
|
}
|
|
103921
|
-
const filePath =
|
|
104303
|
+
const filePath = path109.join(evidenceDir, filename);
|
|
103922
104304
|
try {
|
|
103923
|
-
const resolvedPath =
|
|
103924
|
-
const evidenceDirResolved =
|
|
104305
|
+
const resolvedPath = path109.resolve(filePath);
|
|
104306
|
+
const evidenceDirResolved = path109.resolve(evidenceDir);
|
|
103925
104307
|
if (!resolvedPath.startsWith(evidenceDirResolved)) {
|
|
103926
104308
|
continue;
|
|
103927
104309
|
}
|
|
@@ -104039,7 +104421,7 @@ var evidence_check = createSwarmTool({
|
|
|
104039
104421
|
return JSON.stringify(errorResult, null, 2);
|
|
104040
104422
|
}
|
|
104041
104423
|
const requiredTypes = requiredTypesValue.split(",").map((t) => t.trim()).filter((t) => t.length > 0).map(normalizeEvidenceType);
|
|
104042
|
-
const planPath =
|
|
104424
|
+
const planPath = path109.join(cwd, PLAN_FILE);
|
|
104043
104425
|
if (!isPathWithinSwarm2(planPath, cwd)) {
|
|
104044
104426
|
const errorResult = {
|
|
104045
104427
|
error: "plan file path validation failed",
|
|
@@ -104071,7 +104453,7 @@ var evidence_check = createSwarmTool({
|
|
|
104071
104453
|
};
|
|
104072
104454
|
return JSON.stringify(result2, null, 2);
|
|
104073
104455
|
}
|
|
104074
|
-
const evidenceDir =
|
|
104456
|
+
const evidenceDir = path109.join(cwd, EVIDENCE_DIR3);
|
|
104075
104457
|
const evidence = readEvidenceFiles(evidenceDir, cwd);
|
|
104076
104458
|
const { tasksWithFullEvidence, gaps } = analyzeGaps(completedTasks, evidence, requiredTypes);
|
|
104077
104459
|
const completeness = completedTasks.length > 0 ? Math.round(tasksWithFullEvidence.length / completedTasks.length * 100) / 100 : 1;
|
|
@@ -104089,7 +104471,7 @@ var evidence_check = createSwarmTool({
|
|
|
104089
104471
|
init_zod();
|
|
104090
104472
|
init_create_tool();
|
|
104091
104473
|
import * as fs79 from "node:fs";
|
|
104092
|
-
import * as
|
|
104474
|
+
import * as path110 from "node:path";
|
|
104093
104475
|
var EXT_MAP = {
|
|
104094
104476
|
python: ".py",
|
|
104095
104477
|
py: ".py",
|
|
@@ -104170,12 +104552,12 @@ var extract_code_blocks = createSwarmTool({
|
|
|
104170
104552
|
if (prefix) {
|
|
104171
104553
|
filename = `${prefix}_${filename}`;
|
|
104172
104554
|
}
|
|
104173
|
-
let filepath =
|
|
104174
|
-
const base =
|
|
104175
|
-
const ext =
|
|
104555
|
+
let filepath = path110.join(targetDir, filename);
|
|
104556
|
+
const base = path110.basename(filepath, path110.extname(filepath));
|
|
104557
|
+
const ext = path110.extname(filepath);
|
|
104176
104558
|
let counter = 1;
|
|
104177
104559
|
while (fs79.existsSync(filepath)) {
|
|
104178
|
-
filepath =
|
|
104560
|
+
filepath = path110.join(targetDir, `${base}_${counter}${ext}`);
|
|
104179
104561
|
counter++;
|
|
104180
104562
|
}
|
|
104181
104563
|
try {
|
|
@@ -104433,7 +104815,7 @@ init_zod();
|
|
|
104433
104815
|
init_create_tool();
|
|
104434
104816
|
init_path_security();
|
|
104435
104817
|
import * as fs80 from "node:fs";
|
|
104436
|
-
import * as
|
|
104818
|
+
import * as path111 from "node:path";
|
|
104437
104819
|
var MAX_FILE_PATH_LENGTH2 = 500;
|
|
104438
104820
|
var MAX_SYMBOL_LENGTH = 256;
|
|
104439
104821
|
var MAX_FILE_SIZE_BYTES7 = 1024 * 1024;
|
|
@@ -104481,7 +104863,7 @@ function validateSymbolInput(symbol3) {
|
|
|
104481
104863
|
return null;
|
|
104482
104864
|
}
|
|
104483
104865
|
function isBinaryFile2(filePath, buffer) {
|
|
104484
|
-
const ext =
|
|
104866
|
+
const ext = path111.extname(filePath).toLowerCase();
|
|
104485
104867
|
if (ext === ".json" || ext === ".md" || ext === ".txt") {
|
|
104486
104868
|
return false;
|
|
104487
104869
|
}
|
|
@@ -104505,15 +104887,15 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
104505
104887
|
const imports = [];
|
|
104506
104888
|
let _resolvedTarget;
|
|
104507
104889
|
try {
|
|
104508
|
-
_resolvedTarget =
|
|
104890
|
+
_resolvedTarget = path111.resolve(targetFile);
|
|
104509
104891
|
} catch {
|
|
104510
104892
|
_resolvedTarget = targetFile;
|
|
104511
104893
|
}
|
|
104512
|
-
const targetBasename =
|
|
104894
|
+
const targetBasename = path111.basename(targetFile, path111.extname(targetFile));
|
|
104513
104895
|
const targetWithExt = targetFile;
|
|
104514
104896
|
const targetWithoutExt = targetFile.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
104515
|
-
const normalizedTargetWithExt =
|
|
104516
|
-
const normalizedTargetWithoutExt =
|
|
104897
|
+
const normalizedTargetWithExt = path111.normalize(targetWithExt).replace(/\\/g, "/");
|
|
104898
|
+
const normalizedTargetWithoutExt = path111.normalize(targetWithoutExt).replace(/\\/g, "/");
|
|
104517
104899
|
const importRegex = /import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
|
|
104518
104900
|
for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
|
|
104519
104901
|
const modulePath = match[1] || match[2] || match[3];
|
|
@@ -104536,9 +104918,9 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
104536
104918
|
}
|
|
104537
104919
|
const _normalizedModule = modulePath.replace(/^\.\//, "").replace(/^\.\.\\/, "../");
|
|
104538
104920
|
let isMatch = false;
|
|
104539
|
-
const _targetDir =
|
|
104540
|
-
const targetExt =
|
|
104541
|
-
const targetBasenameNoExt =
|
|
104921
|
+
const _targetDir = path111.dirname(targetFile);
|
|
104922
|
+
const targetExt = path111.extname(targetFile);
|
|
104923
|
+
const targetBasenameNoExt = path111.basename(targetFile, targetExt);
|
|
104542
104924
|
const moduleNormalized = modulePath.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
104543
104925
|
const moduleName = modulePath.split(/[/\\]/).pop() || "";
|
|
104544
104926
|
const moduleNameNoExt = moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
@@ -104606,10 +104988,10 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
|
|
|
104606
104988
|
entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
|
|
104607
104989
|
for (const entry of entries) {
|
|
104608
104990
|
if (SKIP_DIRECTORIES4.has(entry)) {
|
|
104609
|
-
stats.skippedDirs.push(
|
|
104991
|
+
stats.skippedDirs.push(path111.join(dir, entry));
|
|
104610
104992
|
continue;
|
|
104611
104993
|
}
|
|
104612
|
-
const fullPath =
|
|
104994
|
+
const fullPath = path111.join(dir, entry);
|
|
104613
104995
|
let stat8;
|
|
104614
104996
|
try {
|
|
104615
104997
|
stat8 = fs80.statSync(fullPath);
|
|
@@ -104623,7 +105005,7 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
|
|
|
104623
105005
|
if (stat8.isDirectory()) {
|
|
104624
105006
|
findSourceFiles2(fullPath, files, stats);
|
|
104625
105007
|
} else if (stat8.isFile()) {
|
|
104626
|
-
const ext =
|
|
105008
|
+
const ext = path111.extname(fullPath).toLowerCase();
|
|
104627
105009
|
if (SUPPORTED_EXTENSIONS3.includes(ext)) {
|
|
104628
105010
|
files.push(fullPath);
|
|
104629
105011
|
}
|
|
@@ -104680,7 +105062,7 @@ var imports = createSwarmTool({
|
|
|
104680
105062
|
return JSON.stringify(errorResult, null, 2);
|
|
104681
105063
|
}
|
|
104682
105064
|
try {
|
|
104683
|
-
const targetFile =
|
|
105065
|
+
const targetFile = path111.resolve(file3);
|
|
104684
105066
|
if (!fs80.existsSync(targetFile)) {
|
|
104685
105067
|
const errorResult = {
|
|
104686
105068
|
error: `target file not found: ${file3}`,
|
|
@@ -104702,7 +105084,7 @@ var imports = createSwarmTool({
|
|
|
104702
105084
|
};
|
|
104703
105085
|
return JSON.stringify(errorResult, null, 2);
|
|
104704
105086
|
}
|
|
104705
|
-
const baseDir =
|
|
105087
|
+
const baseDir = path111.dirname(targetFile);
|
|
104706
105088
|
const scanStats = {
|
|
104707
105089
|
skippedDirs: [],
|
|
104708
105090
|
skippedFiles: 0,
|
|
@@ -104787,7 +105169,7 @@ var imports = createSwarmTool({
|
|
|
104787
105169
|
});
|
|
104788
105170
|
// src/tools/knowledge-ack.ts
|
|
104789
105171
|
init_zod();
|
|
104790
|
-
import { randomUUID as
|
|
105172
|
+
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
104791
105173
|
init_state();
|
|
104792
105174
|
init_logger();
|
|
104793
105175
|
init_create_tool();
|
|
@@ -104820,7 +105202,7 @@ var knowledge_ack = createSwarmTool({
|
|
|
104820
105202
|
let sessionId = ctx?.sessionID;
|
|
104821
105203
|
if (!sessionId) {
|
|
104822
105204
|
warn("[knowledge-ack] No sessionID in tool context — dedup disabled for this acknowledgment");
|
|
104823
|
-
sessionId =
|
|
105205
|
+
sessionId = randomUUID10();
|
|
104824
105206
|
}
|
|
104825
105207
|
const dedupKey = buildAckDedupKey(sessionId, a.id, a.result);
|
|
104826
105208
|
if (swarmState.knowledgeAckDedup.has(dedupKey)) {
|
|
@@ -104850,7 +105232,7 @@ init_knowledge_store();
|
|
|
104850
105232
|
init_knowledge_validator();
|
|
104851
105233
|
init_manager();
|
|
104852
105234
|
init_create_tool();
|
|
104853
|
-
import { randomUUID as
|
|
105235
|
+
import { randomUUID as randomUUID11 } from "node:crypto";
|
|
104854
105236
|
var VALID_CATEGORIES2 = [
|
|
104855
105237
|
"process",
|
|
104856
105238
|
"architecture",
|
|
@@ -104924,7 +105306,7 @@ var knowledge_add = createSwarmTool({
|
|
|
104924
105306
|
project_name = plan?.title ?? "";
|
|
104925
105307
|
} catch {}
|
|
104926
105308
|
const entry = {
|
|
104927
|
-
id:
|
|
105309
|
+
id: randomUUID11(),
|
|
104928
105310
|
tier: "swarm",
|
|
104929
105311
|
lesson,
|
|
104930
105312
|
category,
|
|
@@ -105327,22 +105709,22 @@ init_schema();
|
|
|
105327
105709
|
init_qa_gate_profile();
|
|
105328
105710
|
init_manager2();
|
|
105329
105711
|
import * as fs85 from "node:fs";
|
|
105330
|
-
import * as
|
|
105712
|
+
import * as path116 from "node:path";
|
|
105331
105713
|
|
|
105332
105714
|
// src/full-auto/phase-approval.ts
|
|
105333
105715
|
init_utils2();
|
|
105334
105716
|
init_logger();
|
|
105335
105717
|
init_state2();
|
|
105336
105718
|
import * as fs81 from "node:fs";
|
|
105337
|
-
import * as
|
|
105719
|
+
import * as path112 from "node:path";
|
|
105338
105720
|
var APPROVAL_TTL_MS = 24 * 60 * 60 * 1000;
|
|
105339
105721
|
function readEvidenceDir(directory, phase) {
|
|
105340
105722
|
try {
|
|
105341
|
-
const dirPath = validateSwarmPath(directory,
|
|
105723
|
+
const dirPath = validateSwarmPath(directory, path112.posix.join("evidence", String(phase)));
|
|
105342
105724
|
if (!fs81.existsSync(dirPath))
|
|
105343
105725
|
return [];
|
|
105344
105726
|
const entries = fs81.readdirSync(dirPath);
|
|
105345
|
-
return entries.filter((e) => e.startsWith("full-auto-") && e.endsWith(".json")).map((e) =>
|
|
105727
|
+
return entries.filter((e) => e.startsWith("full-auto-") && e.endsWith(".json")).map((e) => path112.join(dirPath, e));
|
|
105346
105728
|
} catch {
|
|
105347
105729
|
return [];
|
|
105348
105730
|
}
|
|
@@ -105481,16 +105863,16 @@ init_plan_schema();
|
|
|
105481
105863
|
init_ledger();
|
|
105482
105864
|
init_manager();
|
|
105483
105865
|
import * as fs82 from "node:fs";
|
|
105484
|
-
import * as
|
|
105866
|
+
import * as path113 from "node:path";
|
|
105485
105867
|
async function writeCheckpoint(directory) {
|
|
105486
105868
|
try {
|
|
105487
105869
|
const plan = await loadPlan(directory);
|
|
105488
105870
|
if (!plan)
|
|
105489
105871
|
return;
|
|
105490
|
-
const swarmDir =
|
|
105872
|
+
const swarmDir = path113.join(directory, ".swarm");
|
|
105491
105873
|
fs82.mkdirSync(swarmDir, { recursive: true });
|
|
105492
|
-
const jsonPath =
|
|
105493
|
-
const mdPath =
|
|
105874
|
+
const jsonPath = path113.join(swarmDir, "SWARM_PLAN.json");
|
|
105875
|
+
const mdPath = path113.join(swarmDir, "SWARM_PLAN.md");
|
|
105494
105876
|
fs82.writeFileSync(jsonPath, JSON.stringify(plan, null, 2), "utf8");
|
|
105495
105877
|
const md = derivePlanMarkdown(plan);
|
|
105496
105878
|
fs82.writeFileSync(mdPath, md, "utf8");
|
|
@@ -105509,15 +105891,15 @@ init_telemetry();
|
|
|
105509
105891
|
// src/turbo/lean/phase-ready.ts
|
|
105510
105892
|
init_file_locks();
|
|
105511
105893
|
import * as fs84 from "node:fs";
|
|
105512
|
-
import * as
|
|
105894
|
+
import * as path115 from "node:path";
|
|
105513
105895
|
|
|
105514
105896
|
// src/turbo/lean/evidence.ts
|
|
105515
105897
|
init_bun_compat();
|
|
105516
105898
|
import { rmSync as rmSync6 } from "node:fs";
|
|
105517
105899
|
import * as fs83 from "node:fs/promises";
|
|
105518
|
-
import * as
|
|
105900
|
+
import * as path114 from "node:path";
|
|
105519
105901
|
function leanTurboEvidenceDir(directory, phase) {
|
|
105520
|
-
return
|
|
105902
|
+
return path114.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
|
|
105521
105903
|
}
|
|
105522
105904
|
function validateLaneId(laneId) {
|
|
105523
105905
|
if (laneId.length === 0) {
|
|
@@ -105539,16 +105921,16 @@ function validateLaneId(laneId) {
|
|
|
105539
105921
|
function laneEvidencePath(directory, phase, laneId) {
|
|
105540
105922
|
validateLaneId(laneId);
|
|
105541
105923
|
const expectedDir = leanTurboEvidenceDir(directory, phase);
|
|
105542
|
-
const resolvedPath =
|
|
105543
|
-
const resolvedDir =
|
|
105544
|
-
if (!resolvedPath.startsWith(resolvedDir +
|
|
105924
|
+
const resolvedPath = path114.resolve(path114.join(expectedDir, `${laneId}.json`));
|
|
105925
|
+
const resolvedDir = path114.resolve(expectedDir);
|
|
105926
|
+
if (!resolvedPath.startsWith(resolvedDir + path114.sep) && resolvedPath !== resolvedDir) {
|
|
105545
105927
|
throw new Error(`Invalid laneId: path traversal detected (got "${laneId}")`);
|
|
105546
105928
|
}
|
|
105547
105929
|
return resolvedPath;
|
|
105548
105930
|
}
|
|
105549
105931
|
async function atomicWriteJson(filePath, data) {
|
|
105550
105932
|
const content = JSON.stringify(data, null, 2);
|
|
105551
|
-
const dir =
|
|
105933
|
+
const dir = path114.dirname(filePath);
|
|
105552
105934
|
await fs83.mkdir(dir, { recursive: true });
|
|
105553
105935
|
const tempPath = `${filePath}.tmp.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
105554
105936
|
try {
|
|
@@ -105562,7 +105944,7 @@ async function atomicWriteJson(filePath, data) {
|
|
|
105562
105944
|
}
|
|
105563
105945
|
}
|
|
105564
105946
|
function phaseEvidencePath(directory, phase) {
|
|
105565
|
-
return
|
|
105947
|
+
return path114.join(leanTurboEvidenceDir(directory, phase), "lean-turbo-phase.json");
|
|
105566
105948
|
}
|
|
105567
105949
|
async function writeLaneEvidence(directory, phase, evidence) {
|
|
105568
105950
|
const targetPath = laneEvidencePath(directory, phase, evidence.laneId);
|
|
@@ -105606,7 +105988,7 @@ async function listLaneEvidence(directory, phase) {
|
|
|
105606
105988
|
if (entry === "lean-turbo-phase.json") {
|
|
105607
105989
|
continue;
|
|
105608
105990
|
}
|
|
105609
|
-
const filePath =
|
|
105991
|
+
const filePath = path114.join(evidenceDir, entry);
|
|
105610
105992
|
let content;
|
|
105611
105993
|
try {
|
|
105612
105994
|
content = await fs83.readFile(filePath, "utf-8");
|
|
@@ -105630,7 +106012,7 @@ var DEFAULT_CONFIG2 = {
|
|
|
105630
106012
|
};
|
|
105631
106013
|
function defaultReadPlanJson(dir) {
|
|
105632
106014
|
try {
|
|
105633
|
-
const planPath =
|
|
106015
|
+
const planPath = path115.join(dir, ".swarm", "plan.json");
|
|
105634
106016
|
if (!fs84.existsSync(planPath))
|
|
105635
106017
|
return null;
|
|
105636
106018
|
const raw = fs84.readFileSync(planPath, "utf-8");
|
|
@@ -105645,7 +106027,7 @@ function defaultReadPlanJson(dir) {
|
|
|
105645
106027
|
}
|
|
105646
106028
|
function readReviewerEvidenceFromFile(directory, phase) {
|
|
105647
106029
|
try {
|
|
105648
|
-
const evidencePath =
|
|
106030
|
+
const evidencePath = path115.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-reviewer.json");
|
|
105649
106031
|
if (!fs84.existsSync(evidencePath)) {
|
|
105650
106032
|
return null;
|
|
105651
106033
|
}
|
|
@@ -105665,7 +106047,7 @@ function readReviewerEvidenceFromFile(directory, phase) {
|
|
|
105665
106047
|
}
|
|
105666
106048
|
function readCriticEvidenceFromFile(directory, phase) {
|
|
105667
106049
|
try {
|
|
105668
|
-
const evidencePath =
|
|
106050
|
+
const evidencePath = path115.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-critic.json");
|
|
105669
106051
|
if (!fs84.existsSync(evidencePath)) {
|
|
105670
106052
|
return null;
|
|
105671
106053
|
}
|
|
@@ -105684,7 +106066,7 @@ function readCriticEvidenceFromFile(directory, phase) {
|
|
|
105684
106066
|
}
|
|
105685
106067
|
}
|
|
105686
106068
|
function listLaneEvidenceSync(directory, phase) {
|
|
105687
|
-
const evidenceDir =
|
|
106069
|
+
const evidenceDir = path115.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
|
|
105688
106070
|
let entries;
|
|
105689
106071
|
try {
|
|
105690
106072
|
entries = fs84.readdirSync(evidenceDir);
|
|
@@ -105754,7 +106136,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
105754
106136
|
...DEFAULT_CONFIG2,
|
|
105755
106137
|
...actualConfig
|
|
105756
106138
|
};
|
|
105757
|
-
const statePath =
|
|
106139
|
+
const statePath = path115.join(directory, ".swarm", "turbo-state.json");
|
|
105758
106140
|
if (!fs84.existsSync(statePath)) {
|
|
105759
106141
|
return {
|
|
105760
106142
|
ok: false,
|
|
@@ -105942,7 +106324,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
105942
106324
|
}
|
|
105943
106325
|
}
|
|
105944
106326
|
if (mergedConfig.integrated_diff_required) {
|
|
105945
|
-
const evidencePath =
|
|
106327
|
+
const evidencePath = path115.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-phase.json");
|
|
105946
106328
|
let hasDiff = false;
|
|
105947
106329
|
try {
|
|
105948
106330
|
const content = fs84.readFileSync(evidencePath, "utf-8");
|
|
@@ -106237,7 +106619,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
106237
106619
|
let driftCheckEnabled = true;
|
|
106238
106620
|
let driftHasSpecMd = false;
|
|
106239
106621
|
try {
|
|
106240
|
-
const specMdPath =
|
|
106622
|
+
const specMdPath = path116.join(dir, ".swarm", "spec.md");
|
|
106241
106623
|
driftHasSpecMd = fs85.existsSync(specMdPath);
|
|
106242
106624
|
const gatePlan = await loadPlan(dir);
|
|
106243
106625
|
if (gatePlan) {
|
|
@@ -106258,7 +106640,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
106258
106640
|
} else {
|
|
106259
106641
|
let phaseType;
|
|
106260
106642
|
try {
|
|
106261
|
-
const planPath =
|
|
106643
|
+
const planPath = path116.join(dir, ".swarm", "plan.json");
|
|
106262
106644
|
if (fs85.existsSync(planPath)) {
|
|
106263
106645
|
const planRaw = fs85.readFileSync(planPath, "utf-8");
|
|
106264
106646
|
const plan = JSON.parse(planRaw);
|
|
@@ -106270,7 +106652,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
106270
106652
|
warnings.push(`Phase ${phase} is annotated as 'non-code'. Drift verification was skipped per phase type annotation.`);
|
|
106271
106653
|
} else {
|
|
106272
106654
|
try {
|
|
106273
|
-
const driftEvidencePath =
|
|
106655
|
+
const driftEvidencePath = path116.join(dir, ".swarm", "evidence", String(phase), "drift-verifier.json");
|
|
106274
106656
|
let driftVerdictFound = false;
|
|
106275
106657
|
let driftVerdictApproved = false;
|
|
106276
106658
|
try {
|
|
@@ -106308,7 +106690,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
106308
106690
|
let incompleteTaskCount = 0;
|
|
106309
106691
|
let planParseable = false;
|
|
106310
106692
|
try {
|
|
106311
|
-
const planPath =
|
|
106693
|
+
const planPath = path116.join(dir, ".swarm", "plan.json");
|
|
106312
106694
|
if (fs85.existsSync(planPath)) {
|
|
106313
106695
|
const planRaw = fs85.readFileSync(planPath, "utf-8");
|
|
106314
106696
|
const plan = JSON.parse(planRaw);
|
|
@@ -106375,7 +106757,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
106375
106757
|
const overrides = session2?.qaGateSessionOverrides ?? {};
|
|
106376
106758
|
const effective = getEffectiveGates(profile, overrides);
|
|
106377
106759
|
if (effective.hallucination_guard === true) {
|
|
106378
|
-
const hgPath =
|
|
106760
|
+
const hgPath = path116.join(dir, ".swarm", "evidence", String(phase), "hallucination-guard.json");
|
|
106379
106761
|
let hgVerdictFound = false;
|
|
106380
106762
|
let hgVerdictApproved = false;
|
|
106381
106763
|
try {
|
|
@@ -106447,7 +106829,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
106447
106829
|
const overrides = session2?.qaGateSessionOverrides ?? {};
|
|
106448
106830
|
const effective = getEffectiveGates(profile, overrides);
|
|
106449
106831
|
if (effective.mutation_test === true) {
|
|
106450
|
-
const mgPath =
|
|
106832
|
+
const mgPath = path116.join(dir, ".swarm", "evidence", String(phase), "mutation-gate.json");
|
|
106451
106833
|
let mgVerdictFound = false;
|
|
106452
106834
|
let mgVerdict;
|
|
106453
106835
|
try {
|
|
@@ -106521,7 +106903,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
106521
106903
|
const effective = getEffectiveGates(profile, overrides);
|
|
106522
106904
|
if (effective.council_mode === true) {
|
|
106523
106905
|
councilModeEnabled = true;
|
|
106524
|
-
const pcPath =
|
|
106906
|
+
const pcPath = path116.join(dir, ".swarm", "evidence", String(phase), "phase-council.json");
|
|
106525
106907
|
let pcVerdictFound = false;
|
|
106526
106908
|
let _pcVerdict;
|
|
106527
106909
|
let pcQuorumSize;
|
|
@@ -106729,7 +107111,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
106729
107111
|
const effective = getEffectiveGates(profile, overrides);
|
|
106730
107112
|
if (effective.final_council === true) {
|
|
106731
107113
|
finalCouncilEnabled = true;
|
|
106732
|
-
const fcPath =
|
|
107114
|
+
const fcPath = path116.join(dir, ".swarm", "evidence", "final-council.json");
|
|
106733
107115
|
let fcVerdictFound = false;
|
|
106734
107116
|
let _fcVerdict;
|
|
106735
107117
|
try {
|
|
@@ -106917,7 +107299,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
|
|
|
106917
107299
|
}
|
|
106918
107300
|
if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
|
|
106919
107301
|
try {
|
|
106920
|
-
const projectName =
|
|
107302
|
+
const projectName = path116.basename(dir);
|
|
106921
107303
|
const curationResult = await curateAndStoreSwarm(retroEntry.lessons_learned, projectName, { phase_number: phase }, dir, knowledgeConfig);
|
|
106922
107304
|
if (curationResult) {
|
|
106923
107305
|
const sessionState = swarmState.agentSessions.get(sessionID);
|
|
@@ -107287,7 +107669,7 @@ init_utils();
|
|
|
107287
107669
|
init_bun_compat();
|
|
107288
107670
|
init_create_tool();
|
|
107289
107671
|
import * as fs86 from "node:fs";
|
|
107290
|
-
import * as
|
|
107672
|
+
import * as path117 from "node:path";
|
|
107291
107673
|
var MAX_OUTPUT_BYTES5 = 52428800;
|
|
107292
107674
|
var AUDIT_TIMEOUT_MS = 120000;
|
|
107293
107675
|
function isValidEcosystem(value) {
|
|
@@ -107315,16 +107697,16 @@ function validateArgs3(args2) {
|
|
|
107315
107697
|
function detectEcosystems(directory) {
|
|
107316
107698
|
const ecosystems = [];
|
|
107317
107699
|
const cwd = directory;
|
|
107318
|
-
if (fs86.existsSync(
|
|
107700
|
+
if (fs86.existsSync(path117.join(cwd, "package.json"))) {
|
|
107319
107701
|
ecosystems.push("npm");
|
|
107320
107702
|
}
|
|
107321
|
-
if (fs86.existsSync(
|
|
107703
|
+
if (fs86.existsSync(path117.join(cwd, "pyproject.toml")) || fs86.existsSync(path117.join(cwd, "requirements.txt"))) {
|
|
107322
107704
|
ecosystems.push("pip");
|
|
107323
107705
|
}
|
|
107324
|
-
if (fs86.existsSync(
|
|
107706
|
+
if (fs86.existsSync(path117.join(cwd, "Cargo.toml"))) {
|
|
107325
107707
|
ecosystems.push("cargo");
|
|
107326
107708
|
}
|
|
107327
|
-
if (fs86.existsSync(
|
|
107709
|
+
if (fs86.existsSync(path117.join(cwd, "go.mod"))) {
|
|
107328
107710
|
ecosystems.push("go");
|
|
107329
107711
|
}
|
|
107330
107712
|
try {
|
|
@@ -107333,13 +107715,13 @@ function detectEcosystems(directory) {
|
|
|
107333
107715
|
ecosystems.push("dotnet");
|
|
107334
107716
|
}
|
|
107335
107717
|
} catch {}
|
|
107336
|
-
if (fs86.existsSync(
|
|
107718
|
+
if (fs86.existsSync(path117.join(cwd, "Gemfile")) || fs86.existsSync(path117.join(cwd, "Gemfile.lock"))) {
|
|
107337
107719
|
ecosystems.push("ruby");
|
|
107338
107720
|
}
|
|
107339
|
-
if (fs86.existsSync(
|
|
107721
|
+
if (fs86.existsSync(path117.join(cwd, "pubspec.yaml"))) {
|
|
107340
107722
|
ecosystems.push("dart");
|
|
107341
107723
|
}
|
|
107342
|
-
if (fs86.existsSync(
|
|
107724
|
+
if (fs86.existsSync(path117.join(cwd, "composer.lock"))) {
|
|
107343
107725
|
ecosystems.push("composer");
|
|
107344
107726
|
}
|
|
107345
107727
|
return ecosystems;
|
|
@@ -108475,7 +108857,7 @@ var pkg_audit = createSwarmTool({
|
|
|
108475
108857
|
init_zod();
|
|
108476
108858
|
init_manager2();
|
|
108477
108859
|
import * as fs87 from "node:fs";
|
|
108478
|
-
import * as
|
|
108860
|
+
import * as path118 from "node:path";
|
|
108479
108861
|
init_utils();
|
|
108480
108862
|
init_create_tool();
|
|
108481
108863
|
var MAX_FILE_SIZE = 1024 * 1024;
|
|
@@ -108598,7 +108980,7 @@ function isScaffoldFile(filePath) {
|
|
|
108598
108980
|
if (SCAFFOLD_PATH_PATTERNS.some((pattern) => pattern.test(normalizedPath))) {
|
|
108599
108981
|
return true;
|
|
108600
108982
|
}
|
|
108601
|
-
const filename =
|
|
108983
|
+
const filename = path118.basename(filePath);
|
|
108602
108984
|
if (SCAFFOLD_FILENAME_PATTERNS.some((pattern) => pattern.test(filename))) {
|
|
108603
108985
|
return true;
|
|
108604
108986
|
}
|
|
@@ -108615,7 +108997,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
|
|
|
108615
108997
|
if (regex.test(normalizedPath)) {
|
|
108616
108998
|
return true;
|
|
108617
108999
|
}
|
|
108618
|
-
const filename =
|
|
109000
|
+
const filename = path118.basename(filePath);
|
|
108619
109001
|
const filenameRegex = new RegExp(`^${regexPattern}$`, "i");
|
|
108620
109002
|
if (filenameRegex.test(filename)) {
|
|
108621
109003
|
return true;
|
|
@@ -108624,7 +109006,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
|
|
|
108624
109006
|
return false;
|
|
108625
109007
|
}
|
|
108626
109008
|
function isParserSupported(filePath) {
|
|
108627
|
-
const ext =
|
|
109009
|
+
const ext = path118.extname(filePath).toLowerCase();
|
|
108628
109010
|
return SUPPORTED_PARSER_EXTENSIONS.has(ext);
|
|
108629
109011
|
}
|
|
108630
109012
|
function isPlanFile(filePath) {
|
|
@@ -108871,9 +109253,9 @@ async function placeholderScan(input, directory) {
|
|
|
108871
109253
|
let filesScanned = 0;
|
|
108872
109254
|
const filesWithFindings = new Set;
|
|
108873
109255
|
for (const filePath of changed_files) {
|
|
108874
|
-
const fullPath =
|
|
108875
|
-
const resolvedDirectory =
|
|
108876
|
-
if (!fullPath.startsWith(resolvedDirectory +
|
|
109256
|
+
const fullPath = path118.isAbsolute(filePath) ? filePath : path118.resolve(directory, filePath);
|
|
109257
|
+
const resolvedDirectory = path118.resolve(directory);
|
|
109258
|
+
if (!fullPath.startsWith(resolvedDirectory + path118.sep) && fullPath !== resolvedDirectory) {
|
|
108877
109259
|
continue;
|
|
108878
109260
|
}
|
|
108879
109261
|
if (!fs87.existsSync(fullPath)) {
|
|
@@ -108882,7 +109264,7 @@ async function placeholderScan(input, directory) {
|
|
|
108882
109264
|
if (isAllowedByGlobs(filePath, allow_globs)) {
|
|
108883
109265
|
continue;
|
|
108884
109266
|
}
|
|
108885
|
-
const relativeFilePath =
|
|
109267
|
+
const relativeFilePath = path118.relative(directory, fullPath).replace(/\\/g, "/");
|
|
108886
109268
|
if (FILE_ALLOWLIST.some((allowed) => relativeFilePath.endsWith(allowed))) {
|
|
108887
109269
|
continue;
|
|
108888
109270
|
}
|
|
@@ -108954,7 +109336,7 @@ var placeholder_scan = createSwarmTool({
|
|
|
108954
109336
|
});
|
|
108955
109337
|
// src/tools/pre-check-batch.ts
|
|
108956
109338
|
import * as fs91 from "node:fs";
|
|
108957
|
-
import * as
|
|
109339
|
+
import * as path122 from "node:path";
|
|
108958
109340
|
init_zod();
|
|
108959
109341
|
init_manager2();
|
|
108960
109342
|
init_utils();
|
|
@@ -109095,7 +109477,7 @@ init_zod();
|
|
|
109095
109477
|
init_manager2();
|
|
109096
109478
|
init_detector();
|
|
109097
109479
|
import * as fs90 from "node:fs";
|
|
109098
|
-
import * as
|
|
109480
|
+
import * as path121 from "node:path";
|
|
109099
109481
|
import { extname as extname20 } from "node:path";
|
|
109100
109482
|
|
|
109101
109483
|
// src/sast/rules/c.ts
|
|
@@ -109811,7 +110193,7 @@ function executeRulesSync(filePath, content, language) {
|
|
|
109811
110193
|
// src/sast/semgrep.ts
|
|
109812
110194
|
import * as child_process9 from "node:child_process";
|
|
109813
110195
|
import * as fs88 from "node:fs";
|
|
109814
|
-
import * as
|
|
110196
|
+
import * as path119 from "node:path";
|
|
109815
110197
|
var semgrepAvailableCache = null;
|
|
109816
110198
|
var DEFAULT_RULES_DIR = ".swarm/semgrep-rules";
|
|
109817
110199
|
var DEFAULT_TIMEOUT_MS3 = 30000;
|
|
@@ -109998,7 +110380,7 @@ async function runSemgrep(options) {
|
|
|
109998
110380
|
}
|
|
109999
110381
|
function getRulesDirectory(projectRoot) {
|
|
110000
110382
|
if (projectRoot) {
|
|
110001
|
-
return
|
|
110383
|
+
return path119.resolve(projectRoot, DEFAULT_RULES_DIR);
|
|
110002
110384
|
}
|
|
110003
110385
|
return DEFAULT_RULES_DIR;
|
|
110004
110386
|
}
|
|
@@ -110019,24 +110401,24 @@ init_create_tool();
|
|
|
110019
110401
|
init_utils2();
|
|
110020
110402
|
import * as crypto10 from "node:crypto";
|
|
110021
110403
|
import * as fs89 from "node:fs";
|
|
110022
|
-
import * as
|
|
110404
|
+
import * as path120 from "node:path";
|
|
110023
110405
|
var BASELINE_SCHEMA_VERSION = "1.0.0";
|
|
110024
110406
|
var MAX_BASELINE_FINDINGS = 2000;
|
|
110025
110407
|
var MAX_BASELINE_BYTES = 2 * 1048576;
|
|
110026
110408
|
var LOCK_RETRY_DELAYS_MS = [50, 100, 200, 400, 800];
|
|
110027
110409
|
function normalizeFindingPath(directory, file3) {
|
|
110028
|
-
const resolved =
|
|
110029
|
-
const rel =
|
|
110410
|
+
const resolved = path120.isAbsolute(file3) ? file3 : path120.resolve(directory, file3);
|
|
110411
|
+
const rel = path120.relative(path120.resolve(directory), resolved);
|
|
110030
110412
|
return rel.replace(/\\/g, "/");
|
|
110031
110413
|
}
|
|
110032
110414
|
function baselineRelPath(phase) {
|
|
110033
|
-
return
|
|
110415
|
+
return path120.join("evidence", String(phase), "sast-baseline.json");
|
|
110034
110416
|
}
|
|
110035
110417
|
function tempRelPath(phase) {
|
|
110036
|
-
return
|
|
110418
|
+
return path120.join("evidence", String(phase), `sast-baseline.json.tmp.${Date.now()}.${process.pid}`);
|
|
110037
110419
|
}
|
|
110038
110420
|
function lockRelPath(phase) {
|
|
110039
|
-
return
|
|
110421
|
+
return path120.join("evidence", String(phase), "sast-baseline.json.lock");
|
|
110040
110422
|
}
|
|
110041
110423
|
function getLine(lines, idx) {
|
|
110042
110424
|
if (idx < 0 || idx >= lines.length)
|
|
@@ -110157,8 +110539,8 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
|
|
|
110157
110539
|
message: e instanceof Error ? e.message : "Path validation failed"
|
|
110158
110540
|
};
|
|
110159
110541
|
}
|
|
110160
|
-
fs89.mkdirSync(
|
|
110161
|
-
fs89.mkdirSync(
|
|
110542
|
+
fs89.mkdirSync(path120.dirname(baselinePath), { recursive: true });
|
|
110543
|
+
fs89.mkdirSync(path120.dirname(tempPath), { recursive: true });
|
|
110162
110544
|
const releaseLock = await acquireLock2(lockPath);
|
|
110163
110545
|
try {
|
|
110164
110546
|
let existing = null;
|
|
@@ -110431,9 +110813,9 @@ async function sastScan(input, directory, config3) {
|
|
|
110431
110813
|
_filesSkipped++;
|
|
110432
110814
|
continue;
|
|
110433
110815
|
}
|
|
110434
|
-
const resolvedPath =
|
|
110435
|
-
const resolvedDirectory =
|
|
110436
|
-
if (!resolvedPath.startsWith(resolvedDirectory +
|
|
110816
|
+
const resolvedPath = path121.isAbsolute(filePath) ? filePath : path121.resolve(directory, filePath);
|
|
110817
|
+
const resolvedDirectory = path121.resolve(directory);
|
|
110818
|
+
if (!resolvedPath.startsWith(resolvedDirectory + path121.sep) && resolvedPath !== resolvedDirectory) {
|
|
110437
110819
|
_filesSkipped++;
|
|
110438
110820
|
continue;
|
|
110439
110821
|
}
|
|
@@ -110748,18 +111130,18 @@ function validatePath(inputPath, baseDir, workspaceDir) {
|
|
|
110748
111130
|
let resolved;
|
|
110749
111131
|
const isWinAbs = isWindowsAbsolutePath(inputPath);
|
|
110750
111132
|
if (isWinAbs) {
|
|
110751
|
-
resolved =
|
|
110752
|
-
} else if (
|
|
110753
|
-
resolved =
|
|
111133
|
+
resolved = path122.win32.resolve(inputPath);
|
|
111134
|
+
} else if (path122.isAbsolute(inputPath)) {
|
|
111135
|
+
resolved = path122.resolve(inputPath);
|
|
110754
111136
|
} else {
|
|
110755
|
-
resolved =
|
|
111137
|
+
resolved = path122.resolve(baseDir, inputPath);
|
|
110756
111138
|
}
|
|
110757
|
-
const workspaceResolved =
|
|
111139
|
+
const workspaceResolved = path122.resolve(workspaceDir);
|
|
110758
111140
|
let relative25;
|
|
110759
111141
|
if (isWinAbs) {
|
|
110760
|
-
relative25 =
|
|
111142
|
+
relative25 = path122.win32.relative(workspaceResolved, resolved);
|
|
110761
111143
|
} else {
|
|
110762
|
-
relative25 =
|
|
111144
|
+
relative25 = path122.relative(workspaceResolved, resolved);
|
|
110763
111145
|
}
|
|
110764
111146
|
if (relative25.startsWith("..")) {
|
|
110765
111147
|
return "path traversal detected";
|
|
@@ -110824,7 +111206,7 @@ async function runLintOnFiles(linter, files, workspaceDir) {
|
|
|
110824
111206
|
if (typeof file3 !== "string") {
|
|
110825
111207
|
continue;
|
|
110826
111208
|
}
|
|
110827
|
-
const resolvedPath =
|
|
111209
|
+
const resolvedPath = path122.resolve(file3);
|
|
110828
111210
|
const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
|
|
110829
111211
|
if (validationError) {
|
|
110830
111212
|
continue;
|
|
@@ -110981,7 +111363,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
110981
111363
|
skippedFiles++;
|
|
110982
111364
|
continue;
|
|
110983
111365
|
}
|
|
110984
|
-
const resolvedPath =
|
|
111366
|
+
const resolvedPath = path122.resolve(file3);
|
|
110985
111367
|
const validationError = validatePath(resolvedPath, directory, directory);
|
|
110986
111368
|
if (validationError) {
|
|
110987
111369
|
skippedFiles++;
|
|
@@ -110999,7 +111381,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
110999
111381
|
};
|
|
111000
111382
|
}
|
|
111001
111383
|
for (const file3 of validatedFiles) {
|
|
111002
|
-
const ext =
|
|
111384
|
+
const ext = path122.extname(file3).toLowerCase();
|
|
111003
111385
|
if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
|
|
111004
111386
|
skippedFiles++;
|
|
111005
111387
|
continue;
|
|
@@ -111218,7 +111600,7 @@ function classifySastFindings(findings, changedLineRanges, directory) {
|
|
|
111218
111600
|
const preexistingFindings = [];
|
|
111219
111601
|
for (const finding of findings) {
|
|
111220
111602
|
const filePath = finding.location.file;
|
|
111221
|
-
const normalised =
|
|
111603
|
+
const normalised = path122.relative(directory, filePath).replace(/\\/g, "/");
|
|
111222
111604
|
const changedLines = changedLineRanges.get(normalised);
|
|
111223
111605
|
if (changedLines?.has(finding.location.line)) {
|
|
111224
111606
|
newFindings.push(finding);
|
|
@@ -111269,7 +111651,7 @@ async function runPreCheckBatch(input, workspaceDir, contextDir) {
|
|
|
111269
111651
|
warn(`pre_check_batch: Invalid file path: ${file3}`);
|
|
111270
111652
|
continue;
|
|
111271
111653
|
}
|
|
111272
|
-
changedFiles.push(
|
|
111654
|
+
changedFiles.push(path122.resolve(directory, file3));
|
|
111273
111655
|
}
|
|
111274
111656
|
if (changedFiles.length === 0) {
|
|
111275
111657
|
warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
|
|
@@ -111470,9 +111852,9 @@ var pre_check_batch = createSwarmTool({
|
|
|
111470
111852
|
};
|
|
111471
111853
|
return JSON.stringify(errorResult, null, 2);
|
|
111472
111854
|
}
|
|
111473
|
-
const resolvedDirectory =
|
|
111474
|
-
const workspaceAnchor =
|
|
111475
|
-
if (resolvedDirectory !== workspaceAnchor && resolvedDirectory.startsWith(workspaceAnchor +
|
|
111855
|
+
const resolvedDirectory = path122.resolve(typedArgs.directory);
|
|
111856
|
+
const workspaceAnchor = path122.resolve(directory);
|
|
111857
|
+
if (resolvedDirectory !== workspaceAnchor && resolvedDirectory.startsWith(workspaceAnchor + path122.sep)) {
|
|
111476
111858
|
const subDirError = `directory "${typedArgs.directory}" is a subdirectory of the project root — pre_check_batch requires the project root directory "${workspaceAnchor}"`;
|
|
111477
111859
|
const subDirResult = {
|
|
111478
111860
|
gates_passed: false,
|
|
@@ -111523,7 +111905,7 @@ var pre_check_batch = createSwarmTool({
|
|
|
111523
111905
|
});
|
|
111524
111906
|
// src/tools/repo-map.ts
|
|
111525
111907
|
init_zod();
|
|
111526
|
-
import * as
|
|
111908
|
+
import * as path123 from "node:path";
|
|
111527
111909
|
init_path_security();
|
|
111528
111910
|
init_create_tool();
|
|
111529
111911
|
var VALID_ACTIONS = [
|
|
@@ -111548,7 +111930,7 @@ function validateFile(p) {
|
|
|
111548
111930
|
return "file contains control characters";
|
|
111549
111931
|
if (containsPathTraversal(p))
|
|
111550
111932
|
return "file contains path traversal";
|
|
111551
|
-
if (
|
|
111933
|
+
if (path123.isAbsolute(p) || /^[a-zA-Z]:[\\/]/.test(p)) {
|
|
111552
111934
|
return "file must be a workspace-relative path, not absolute";
|
|
111553
111935
|
}
|
|
111554
111936
|
return null;
|
|
@@ -111571,8 +111953,8 @@ function ok(action, payload) {
|
|
|
111571
111953
|
}
|
|
111572
111954
|
function toRelativeGraphPath(input, workspaceRoot) {
|
|
111573
111955
|
const normalized = input.replace(/\\/g, "/");
|
|
111574
|
-
if (
|
|
111575
|
-
const rel =
|
|
111956
|
+
if (path123.isAbsolute(normalized)) {
|
|
111957
|
+
const rel = path123.relative(workspaceRoot, normalized).replace(/\\/g, "/");
|
|
111576
111958
|
return normalizeGraphPath2(rel);
|
|
111577
111959
|
}
|
|
111578
111960
|
return normalizeGraphPath2(normalized);
|
|
@@ -111717,7 +112099,7 @@ var repo_map = createSwarmTool({
|
|
|
111717
112099
|
init_zod();
|
|
111718
112100
|
init_create_tool();
|
|
111719
112101
|
import * as fs92 from "node:fs";
|
|
111720
|
-
import * as
|
|
112102
|
+
import * as path124 from "node:path";
|
|
111721
112103
|
var SPEC_FILE = ".swarm/spec.md";
|
|
111722
112104
|
var EVIDENCE_DIR4 = ".swarm/evidence";
|
|
111723
112105
|
var OBLIGATION_KEYWORDS = ["MUST", "SHOULD", "SHALL"];
|
|
@@ -111786,7 +112168,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
111786
112168
|
return [];
|
|
111787
112169
|
}
|
|
111788
112170
|
for (const entry of entries) {
|
|
111789
|
-
const entryPath =
|
|
112171
|
+
const entryPath = path124.join(evidenceDir, entry);
|
|
111790
112172
|
try {
|
|
111791
112173
|
const stat8 = fs92.statSync(entryPath);
|
|
111792
112174
|
if (!stat8.isDirectory()) {
|
|
@@ -111802,11 +112184,11 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
111802
112184
|
if (entryPhase !== String(phase)) {
|
|
111803
112185
|
continue;
|
|
111804
112186
|
}
|
|
111805
|
-
const evidenceFilePath =
|
|
112187
|
+
const evidenceFilePath = path124.join(entryPath, "evidence.json");
|
|
111806
112188
|
try {
|
|
111807
|
-
const resolvedPath =
|
|
111808
|
-
const evidenceDirResolved =
|
|
111809
|
-
if (!resolvedPath.startsWith(evidenceDirResolved +
|
|
112189
|
+
const resolvedPath = path124.resolve(evidenceFilePath);
|
|
112190
|
+
const evidenceDirResolved = path124.resolve(evidenceDir);
|
|
112191
|
+
if (!resolvedPath.startsWith(evidenceDirResolved + path124.sep)) {
|
|
111810
112192
|
continue;
|
|
111811
112193
|
}
|
|
111812
112194
|
const stat8 = fs92.lstatSync(evidenceFilePath);
|
|
@@ -111840,7 +112222,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
111840
112222
|
if (Array.isArray(diffEntry.files_changed)) {
|
|
111841
112223
|
for (const file3 of diffEntry.files_changed) {
|
|
111842
112224
|
if (typeof file3 === "string") {
|
|
111843
|
-
touchedFiles.add(
|
|
112225
|
+
touchedFiles.add(path124.resolve(cwd, file3));
|
|
111844
112226
|
}
|
|
111845
112227
|
}
|
|
111846
112228
|
}
|
|
@@ -111853,8 +112235,8 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
111853
112235
|
}
|
|
111854
112236
|
function searchFileForKeywords(filePath, keywords, cwd) {
|
|
111855
112237
|
try {
|
|
111856
|
-
const resolvedPath =
|
|
111857
|
-
const cwdResolved =
|
|
112238
|
+
const resolvedPath = path124.resolve(filePath);
|
|
112239
|
+
const cwdResolved = path124.resolve(cwd);
|
|
111858
112240
|
if (!resolvedPath.startsWith(cwdResolved)) {
|
|
111859
112241
|
return false;
|
|
111860
112242
|
}
|
|
@@ -111988,7 +112370,7 @@ var req_coverage = createSwarmTool({
|
|
|
111988
112370
|
}, null, 2);
|
|
111989
112371
|
}
|
|
111990
112372
|
const cwd = inputDirectory || directory;
|
|
111991
|
-
const specPath =
|
|
112373
|
+
const specPath = path124.join(cwd, SPEC_FILE);
|
|
111992
112374
|
let specContent;
|
|
111993
112375
|
try {
|
|
111994
112376
|
specContent = fs92.readFileSync(specPath, "utf-8");
|
|
@@ -112015,7 +112397,7 @@ var req_coverage = createSwarmTool({
|
|
|
112015
112397
|
message: "No FR requirements found in spec.md"
|
|
112016
112398
|
}, null, 2);
|
|
112017
112399
|
}
|
|
112018
|
-
const evidenceDir =
|
|
112400
|
+
const evidenceDir = path124.join(cwd, EVIDENCE_DIR4);
|
|
112019
112401
|
const touchedFiles = readTouchedFiles(evidenceDir, phase, cwd);
|
|
112020
112402
|
const analyzedRequirements = [];
|
|
112021
112403
|
let coveredCount = 0;
|
|
@@ -112041,7 +112423,7 @@ var req_coverage = createSwarmTool({
|
|
|
112041
112423
|
requirements: analyzedRequirements
|
|
112042
112424
|
};
|
|
112043
112425
|
const reportFilename = `req-coverage-phase-${phase}.json`;
|
|
112044
|
-
const reportPath =
|
|
112426
|
+
const reportPath = path124.join(evidenceDir, reportFilename);
|
|
112045
112427
|
try {
|
|
112046
112428
|
if (!fs92.existsSync(evidenceDir)) {
|
|
112047
112429
|
fs92.mkdirSync(evidenceDir, { recursive: true });
|
|
@@ -112129,7 +112511,7 @@ init_qa_gate_profile();
|
|
|
112129
112511
|
init_file_locks();
|
|
112130
112512
|
import * as crypto11 from "node:crypto";
|
|
112131
112513
|
import * as fs93 from "node:fs";
|
|
112132
|
-
import * as
|
|
112514
|
+
import * as path125 from "node:path";
|
|
112133
112515
|
init_ledger();
|
|
112134
112516
|
init_manager();
|
|
112135
112517
|
init_state();
|
|
@@ -112207,8 +112589,8 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
112207
112589
|
};
|
|
112208
112590
|
}
|
|
112209
112591
|
if (args2.working_directory && fallbackDir) {
|
|
112210
|
-
const resolvedTarget =
|
|
112211
|
-
const resolvedRoot =
|
|
112592
|
+
const resolvedTarget = path125.resolve(args2.working_directory);
|
|
112593
|
+
const resolvedRoot = path125.resolve(fallbackDir);
|
|
112212
112594
|
let fallbackExists = false;
|
|
112213
112595
|
try {
|
|
112214
112596
|
fs93.accessSync(resolvedRoot, fs93.constants.F_OK);
|
|
@@ -112217,7 +112599,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
112217
112599
|
fallbackExists = false;
|
|
112218
112600
|
}
|
|
112219
112601
|
if (fallbackExists) {
|
|
112220
|
-
const isSubdirectory = resolvedTarget.startsWith(resolvedRoot +
|
|
112602
|
+
const isSubdirectory = resolvedTarget.startsWith(resolvedRoot + path125.sep);
|
|
112221
112603
|
if (isSubdirectory) {
|
|
112222
112604
|
return {
|
|
112223
112605
|
success: false,
|
|
@@ -112233,7 +112615,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
112233
112615
|
let specMtime;
|
|
112234
112616
|
let specHash;
|
|
112235
112617
|
if (process.env.SWARM_SKIP_SPEC_GATE !== "1") {
|
|
112236
|
-
const specPath =
|
|
112618
|
+
const specPath = path125.join(targetWorkspace, ".swarm", "spec.md");
|
|
112237
112619
|
try {
|
|
112238
112620
|
const stat8 = await fs93.promises.stat(specPath);
|
|
112239
112621
|
specMtime = stat8.mtime.toISOString();
|
|
@@ -112249,7 +112631,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
112249
112631
|
}
|
|
112250
112632
|
}
|
|
112251
112633
|
if (process.env.SWARM_SKIP_GATE_SELECTION !== "1") {
|
|
112252
|
-
const contextPath =
|
|
112634
|
+
const contextPath = path125.join(targetWorkspace, ".swarm", "context.md");
|
|
112253
112635
|
let contextContent = "";
|
|
112254
112636
|
try {
|
|
112255
112637
|
contextContent = await fs93.promises.readFile(contextPath, "utf8");
|
|
@@ -112506,7 +112888,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
112506
112888
|
}
|
|
112507
112889
|
await writeCheckpoint(dir).catch(() => {});
|
|
112508
112890
|
try {
|
|
112509
|
-
const markerPath =
|
|
112891
|
+
const markerPath = path125.join(dir, ".swarm", ".plan-write-marker");
|
|
112510
112892
|
const marker = JSON.stringify({
|
|
112511
112893
|
source: "save_plan",
|
|
112512
112894
|
timestamp: new Date().toISOString(),
|
|
@@ -112529,7 +112911,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
112529
112911
|
return {
|
|
112530
112912
|
success: true,
|
|
112531
112913
|
message: "Plan saved successfully",
|
|
112532
|
-
plan_path:
|
|
112914
|
+
plan_path: path125.join(dir, ".swarm", "plan.json"),
|
|
112533
112915
|
phases_count: plan.phases.length,
|
|
112534
112916
|
tasks_count: tasksCount,
|
|
112535
112917
|
...resolvedProfile !== undefined ? { execution_profile: resolvedProfile } : {},
|
|
@@ -112594,7 +112976,7 @@ var save_plan = createSwarmTool({
|
|
|
112594
112976
|
init_zod();
|
|
112595
112977
|
init_manager2();
|
|
112596
112978
|
import * as fs94 from "node:fs";
|
|
112597
|
-
import * as
|
|
112979
|
+
import * as path126 from "node:path";
|
|
112598
112980
|
|
|
112599
112981
|
// src/sbom/detectors/index.ts
|
|
112600
112982
|
init_utils();
|
|
@@ -113444,7 +113826,7 @@ function findManifestFiles(rootDir) {
|
|
|
113444
113826
|
try {
|
|
113445
113827
|
const entries = fs94.readdirSync(dir, { withFileTypes: true });
|
|
113446
113828
|
for (const entry of entries) {
|
|
113447
|
-
const fullPath =
|
|
113829
|
+
const fullPath = path126.join(dir, entry.name);
|
|
113448
113830
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
|
|
113449
113831
|
continue;
|
|
113450
113832
|
}
|
|
@@ -113453,7 +113835,7 @@ function findManifestFiles(rootDir) {
|
|
|
113453
113835
|
} else if (entry.isFile()) {
|
|
113454
113836
|
for (const pattern of patterns) {
|
|
113455
113837
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
113456
|
-
manifestFiles.push(
|
|
113838
|
+
manifestFiles.push(path126.relative(rootDir, fullPath));
|
|
113457
113839
|
break;
|
|
113458
113840
|
}
|
|
113459
113841
|
}
|
|
@@ -113471,11 +113853,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
113471
113853
|
try {
|
|
113472
113854
|
const entries = fs94.readdirSync(dir, { withFileTypes: true });
|
|
113473
113855
|
for (const entry of entries) {
|
|
113474
|
-
const fullPath =
|
|
113856
|
+
const fullPath = path126.join(dir, entry.name);
|
|
113475
113857
|
if (entry.isFile()) {
|
|
113476
113858
|
for (const pattern of patterns) {
|
|
113477
113859
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
113478
|
-
found.push(
|
|
113860
|
+
found.push(path126.relative(workingDir, fullPath));
|
|
113479
113861
|
break;
|
|
113480
113862
|
}
|
|
113481
113863
|
}
|
|
@@ -113488,11 +113870,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
113488
113870
|
function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
|
|
113489
113871
|
const dirs = new Set;
|
|
113490
113872
|
for (const file3 of changedFiles) {
|
|
113491
|
-
let currentDir =
|
|
113873
|
+
let currentDir = path126.dirname(file3);
|
|
113492
113874
|
while (true) {
|
|
113493
|
-
if (currentDir && currentDir !== "." && currentDir !==
|
|
113494
|
-
dirs.add(
|
|
113495
|
-
const parent =
|
|
113875
|
+
if (currentDir && currentDir !== "." && currentDir !== path126.sep) {
|
|
113876
|
+
dirs.add(path126.join(workingDir, currentDir));
|
|
113877
|
+
const parent = path126.dirname(currentDir);
|
|
113496
113878
|
if (parent === currentDir)
|
|
113497
113879
|
break;
|
|
113498
113880
|
currentDir = parent;
|
|
@@ -113576,7 +113958,7 @@ var sbom_generate = createSwarmTool({
|
|
|
113576
113958
|
const changedFiles = obj.changed_files;
|
|
113577
113959
|
const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
|
|
113578
113960
|
const workingDir = directory;
|
|
113579
|
-
const outputDir =
|
|
113961
|
+
const outputDir = path126.isAbsolute(relativeOutputDir) ? relativeOutputDir : path126.join(workingDir, relativeOutputDir);
|
|
113580
113962
|
let manifestFiles = [];
|
|
113581
113963
|
if (scope === "all") {
|
|
113582
113964
|
manifestFiles = findManifestFiles(workingDir);
|
|
@@ -113599,7 +113981,7 @@ var sbom_generate = createSwarmTool({
|
|
|
113599
113981
|
const processedFiles = [];
|
|
113600
113982
|
for (const manifestFile of manifestFiles) {
|
|
113601
113983
|
try {
|
|
113602
|
-
const fullPath =
|
|
113984
|
+
const fullPath = path126.isAbsolute(manifestFile) ? manifestFile : path126.join(workingDir, manifestFile);
|
|
113603
113985
|
if (!fs94.existsSync(fullPath)) {
|
|
113604
113986
|
continue;
|
|
113605
113987
|
}
|
|
@@ -113616,7 +113998,7 @@ var sbom_generate = createSwarmTool({
|
|
|
113616
113998
|
const bom = generateCycloneDX(allComponents);
|
|
113617
113999
|
const bomJson = serializeCycloneDX(bom);
|
|
113618
114000
|
const filename = generateSbomFilename();
|
|
113619
|
-
const outputPath =
|
|
114001
|
+
const outputPath = path126.join(outputDir, filename);
|
|
113620
114002
|
fs94.writeFileSync(outputPath, bomJson, "utf-8");
|
|
113621
114003
|
const verdict = processedFiles.length > 0 ? "pass" : "pass";
|
|
113622
114004
|
try {
|
|
@@ -113660,7 +114042,7 @@ var sbom_generate = createSwarmTool({
|
|
|
113660
114042
|
init_zod();
|
|
113661
114043
|
init_create_tool();
|
|
113662
114044
|
import * as fs95 from "node:fs";
|
|
113663
|
-
import * as
|
|
114045
|
+
import * as path127 from "node:path";
|
|
113664
114046
|
var SPEC_CANDIDATES = [
|
|
113665
114047
|
"openapi.json",
|
|
113666
114048
|
"openapi.yaml",
|
|
@@ -113692,12 +114074,12 @@ function normalizePath4(p) {
|
|
|
113692
114074
|
}
|
|
113693
114075
|
function discoverSpecFile(cwd, specFileArg) {
|
|
113694
114076
|
if (specFileArg) {
|
|
113695
|
-
const resolvedPath =
|
|
113696
|
-
const normalizedCwd = cwd.endsWith(
|
|
114077
|
+
const resolvedPath = path127.resolve(cwd, specFileArg);
|
|
114078
|
+
const normalizedCwd = cwd.endsWith(path127.sep) ? cwd : cwd + path127.sep;
|
|
113697
114079
|
if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
|
|
113698
114080
|
throw new Error("Invalid spec_file: path traversal detected");
|
|
113699
114081
|
}
|
|
113700
|
-
const ext =
|
|
114082
|
+
const ext = path127.extname(resolvedPath).toLowerCase();
|
|
113701
114083
|
if (!ALLOWED_EXTENSIONS.includes(ext)) {
|
|
113702
114084
|
throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
|
|
113703
114085
|
}
|
|
@@ -113711,7 +114093,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
113711
114093
|
return resolvedPath;
|
|
113712
114094
|
}
|
|
113713
114095
|
for (const candidate of SPEC_CANDIDATES) {
|
|
113714
|
-
const candidatePath =
|
|
114096
|
+
const candidatePath = path127.resolve(cwd, candidate);
|
|
113715
114097
|
if (fs95.existsSync(candidatePath)) {
|
|
113716
114098
|
const stats = fs95.statSync(candidatePath);
|
|
113717
114099
|
if (stats.size <= MAX_SPEC_SIZE) {
|
|
@@ -113723,7 +114105,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
113723
114105
|
}
|
|
113724
114106
|
function parseSpec(specFile) {
|
|
113725
114107
|
const content = fs95.readFileSync(specFile, "utf-8");
|
|
113726
|
-
const ext =
|
|
114108
|
+
const ext = path127.extname(specFile).toLowerCase();
|
|
113727
114109
|
if (ext === ".json") {
|
|
113728
114110
|
return parseJsonSpec(content);
|
|
113729
114111
|
}
|
|
@@ -113799,7 +114181,7 @@ function extractRoutes(cwd) {
|
|
|
113799
114181
|
return;
|
|
113800
114182
|
}
|
|
113801
114183
|
for (const entry of entries) {
|
|
113802
|
-
const fullPath =
|
|
114184
|
+
const fullPath = path127.join(dir, entry.name);
|
|
113803
114185
|
if (entry.isSymbolicLink()) {
|
|
113804
114186
|
continue;
|
|
113805
114187
|
}
|
|
@@ -113809,7 +114191,7 @@ function extractRoutes(cwd) {
|
|
|
113809
114191
|
}
|
|
113810
114192
|
walkDir(fullPath);
|
|
113811
114193
|
} else if (entry.isFile()) {
|
|
113812
|
-
const ext =
|
|
114194
|
+
const ext = path127.extname(entry.name).toLowerCase();
|
|
113813
114195
|
const baseName = entry.name.toLowerCase();
|
|
113814
114196
|
if (![".ts", ".js", ".mjs"].includes(ext)) {
|
|
113815
114197
|
continue;
|
|
@@ -113977,7 +114359,7 @@ init_bun_compat();
|
|
|
113977
114359
|
init_path_security();
|
|
113978
114360
|
init_create_tool();
|
|
113979
114361
|
import * as fs96 from "node:fs";
|
|
113980
|
-
import * as
|
|
114362
|
+
import * as path128 from "node:path";
|
|
113981
114363
|
var DEFAULT_MAX_RESULTS = 100;
|
|
113982
114364
|
var DEFAULT_MAX_LINES = 200;
|
|
113983
114365
|
var REGEX_TIMEOUT_MS = 5000;
|
|
@@ -114013,11 +114395,11 @@ function containsWindowsAttacks3(str) {
|
|
|
114013
114395
|
}
|
|
114014
114396
|
function isPathInWorkspace3(filePath, workspace) {
|
|
114015
114397
|
try {
|
|
114016
|
-
const resolvedPath =
|
|
114398
|
+
const resolvedPath = path128.resolve(workspace, filePath);
|
|
114017
114399
|
const realWorkspace = fs96.realpathSync(workspace);
|
|
114018
114400
|
const realResolvedPath = fs96.realpathSync(resolvedPath);
|
|
114019
|
-
const relativePath =
|
|
114020
|
-
if (relativePath.startsWith("..") ||
|
|
114401
|
+
const relativePath = path128.relative(realWorkspace, realResolvedPath);
|
|
114402
|
+
if (relativePath.startsWith("..") || path128.isAbsolute(relativePath)) {
|
|
114021
114403
|
return false;
|
|
114022
114404
|
}
|
|
114023
114405
|
return true;
|
|
@@ -114030,11 +114412,11 @@ function validatePathForRead2(filePath, workspace) {
|
|
|
114030
114412
|
}
|
|
114031
114413
|
function findRgInEnvPath() {
|
|
114032
114414
|
const searchPath = process.env.PATH ?? "";
|
|
114033
|
-
for (const dir of searchPath.split(
|
|
114415
|
+
for (const dir of searchPath.split(path128.delimiter)) {
|
|
114034
114416
|
if (!dir)
|
|
114035
114417
|
continue;
|
|
114036
114418
|
const isWindows = process.platform === "win32";
|
|
114037
|
-
const candidate =
|
|
114419
|
+
const candidate = path128.join(dir, isWindows ? "rg.exe" : "rg");
|
|
114038
114420
|
if (fs96.existsSync(candidate))
|
|
114039
114421
|
return candidate;
|
|
114040
114422
|
}
|
|
@@ -114164,8 +114546,8 @@ function collectFiles(dir, workspace, includeGlobs, excludeGlobs) {
|
|
|
114164
114546
|
try {
|
|
114165
114547
|
const entries = fs96.readdirSync(dir, { withFileTypes: true });
|
|
114166
114548
|
for (const entry of entries) {
|
|
114167
|
-
const fullPath =
|
|
114168
|
-
const relativePath =
|
|
114549
|
+
const fullPath = path128.join(dir, entry.name);
|
|
114550
|
+
const relativePath = path128.relative(workspace, fullPath);
|
|
114169
114551
|
if (!validatePathForRead2(fullPath, workspace)) {
|
|
114170
114552
|
continue;
|
|
114171
114553
|
}
|
|
@@ -114206,7 +114588,7 @@ async function fallbackSearch(opts) {
|
|
|
114206
114588
|
const matches = [];
|
|
114207
114589
|
let total = 0;
|
|
114208
114590
|
for (const file3 of files) {
|
|
114209
|
-
const fullPath =
|
|
114591
|
+
const fullPath = path128.join(opts.workspace, file3);
|
|
114210
114592
|
if (!validatePathForRead2(fullPath, opts.workspace)) {
|
|
114211
114593
|
continue;
|
|
114212
114594
|
}
|
|
@@ -114574,7 +114956,7 @@ init_config();
|
|
|
114574
114956
|
init_schema();
|
|
114575
114957
|
init_create_tool();
|
|
114576
114958
|
import { mkdir as mkdir21, rename as rename9, writeFile as writeFile16 } from "node:fs/promises";
|
|
114577
|
-
import * as
|
|
114959
|
+
import * as path129 from "node:path";
|
|
114578
114960
|
var MAX_SPEC_BYTES = 256 * 1024;
|
|
114579
114961
|
var spec_write = createSwarmTool({
|
|
114580
114962
|
description: "Write the canonical project spec to .swarm/spec.md. Atomic write, size-bounded (256 KiB), heading-required. Honors spec_writer.allow_spec_write.",
|
|
@@ -114615,8 +114997,8 @@ var spec_write = createSwarmTool({
|
|
|
114615
114997
|
reason: 'spec must contain at least one top-level "# Heading"'
|
|
114616
114998
|
}, null, 2);
|
|
114617
114999
|
}
|
|
114618
|
-
const target =
|
|
114619
|
-
await mkdir21(
|
|
115000
|
+
const target = path129.join(directory, ".swarm", "spec.md");
|
|
115001
|
+
await mkdir21(path129.dirname(target), { recursive: true });
|
|
114620
115002
|
const tmp = `${target}.tmp-${process.pid}-${Date.now()}`;
|
|
114621
115003
|
let finalContent = content;
|
|
114622
115004
|
if (mode === "append") {
|
|
@@ -114645,13 +115027,13 @@ init_zod();
|
|
|
114645
115027
|
init_loader();
|
|
114646
115028
|
import {
|
|
114647
115029
|
existsSync as existsSync74,
|
|
114648
|
-
mkdirSync as
|
|
115030
|
+
mkdirSync as mkdirSync33,
|
|
114649
115031
|
readFileSync as readFileSync64,
|
|
114650
115032
|
renameSync as renameSync20,
|
|
114651
115033
|
unlinkSync as unlinkSync16,
|
|
114652
115034
|
writeFileSync as writeFileSync24
|
|
114653
115035
|
} from "node:fs";
|
|
114654
|
-
import
|
|
115036
|
+
import path130 from "node:path";
|
|
114655
115037
|
init_create_tool();
|
|
114656
115038
|
init_resolve_working_directory();
|
|
114657
115039
|
var VerdictSchema2 = exports_external.object({
|
|
@@ -114781,7 +115163,7 @@ var submit_phase_council_verdicts = createSwarmTool({
|
|
|
114781
115163
|
}
|
|
114782
115164
|
});
|
|
114783
115165
|
function getPhaseMutationGapFinding(phaseNumber, workingDir) {
|
|
114784
|
-
const mutationGatePath =
|
|
115166
|
+
const mutationGatePath = path130.join(workingDir, ".swarm", "evidence", String(phaseNumber), "mutation-gate.json");
|
|
114785
115167
|
try {
|
|
114786
115168
|
const raw = readFileSync64(mutationGatePath, "utf-8");
|
|
114787
115169
|
const parsed = JSON.parse(raw);
|
|
@@ -114843,9 +115225,9 @@ function getPhaseMutationGapFinding(phaseNumber, workingDir) {
|
|
|
114843
115225
|
}
|
|
114844
115226
|
}
|
|
114845
115227
|
function writePhaseCouncilEvidence(workingDir, synthesis) {
|
|
114846
|
-
const evidenceDir =
|
|
114847
|
-
|
|
114848
|
-
const evidenceFile =
|
|
115228
|
+
const evidenceDir = path130.join(workingDir, ".swarm", "evidence", String(synthesis.phaseNumber));
|
|
115229
|
+
mkdirSync33(evidenceDir, { recursive: true });
|
|
115230
|
+
const evidenceFile = path130.join(evidenceDir, "phase-council.json");
|
|
114849
115231
|
const evidenceBundle = {
|
|
114850
115232
|
entries: [
|
|
114851
115233
|
{
|
|
@@ -114998,16 +115380,20 @@ var swarm_memory_propose = createSwarmTool({
|
|
|
114998
115380
|
}, {
|
|
114999
115381
|
config: config3.memory
|
|
115000
115382
|
});
|
|
115001
|
-
|
|
115002
|
-
|
|
115003
|
-
|
|
115004
|
-
|
|
115005
|
-
|
|
115006
|
-
|
|
115007
|
-
|
|
115008
|
-
|
|
115009
|
-
|
|
115010
|
-
|
|
115383
|
+
try {
|
|
115384
|
+
const proposal = await gateway.propose(parsed.data);
|
|
115385
|
+
return JSON.stringify({
|
|
115386
|
+
success: proposal.status !== "rejected",
|
|
115387
|
+
proposal_id: proposal.id,
|
|
115388
|
+
status: proposal.status,
|
|
115389
|
+
operation: proposal.operation,
|
|
115390
|
+
memory_id: proposal.proposedRecord?.id,
|
|
115391
|
+
rejection_reason: proposal.rejectionReason,
|
|
115392
|
+
message: proposal.status === "pending" ? "Memory proposal created. Durable memory was not written." : "Memory proposal was captured with policy rejection metadata."
|
|
115393
|
+
}, null, 2);
|
|
115394
|
+
} finally {
|
|
115395
|
+
await gateway.dispose();
|
|
115396
|
+
}
|
|
115011
115397
|
}
|
|
115012
115398
|
});
|
|
115013
115399
|
var _internals51 = {
|
|
@@ -115071,19 +115457,23 @@ var swarm_memory_recall = createSwarmTool({
|
|
|
115071
115457
|
}, {
|
|
115072
115458
|
config: config3.memory
|
|
115073
115459
|
});
|
|
115074
|
-
|
|
115075
|
-
|
|
115076
|
-
|
|
115077
|
-
|
|
115078
|
-
|
|
115079
|
-
|
|
115080
|
-
|
|
115081
|
-
|
|
115082
|
-
|
|
115083
|
-
|
|
115084
|
-
|
|
115085
|
-
|
|
115086
|
-
|
|
115460
|
+
try {
|
|
115461
|
+
const bundle = await gateway.recall(parsed.data);
|
|
115462
|
+
return JSON.stringify({
|
|
115463
|
+
success: true,
|
|
115464
|
+
bundle_id: bundle.id,
|
|
115465
|
+
memory_ids: bundle.items.map((item) => item.record.id),
|
|
115466
|
+
total: bundle.items.length,
|
|
115467
|
+
token_estimate: bundle.tokenEstimate,
|
|
115468
|
+
signals: bundle.items.map((item) => ({
|
|
115469
|
+
memory_id: item.record.id,
|
|
115470
|
+
...item.signals
|
|
115471
|
+
})),
|
|
115472
|
+
prompt_block: bundle.promptBlock
|
|
115473
|
+
}, null, 2);
|
|
115474
|
+
} finally {
|
|
115475
|
+
await gateway.dispose();
|
|
115476
|
+
}
|
|
115087
115477
|
}
|
|
115088
115478
|
});
|
|
115089
115479
|
var RecallArgsSchema = exports_external.object({
|
|
@@ -115106,7 +115496,7 @@ init_zod();
|
|
|
115106
115496
|
init_path_security();
|
|
115107
115497
|
init_create_tool();
|
|
115108
115498
|
import * as fs97 from "node:fs";
|
|
115109
|
-
import * as
|
|
115499
|
+
import * as path131 from "node:path";
|
|
115110
115500
|
var WINDOWS_RESERVED_NAMES4 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
115111
115501
|
function containsWindowsAttacks4(str) {
|
|
115112
115502
|
if (/:[^\\/]/.test(str))
|
|
@@ -115120,14 +115510,14 @@ function containsWindowsAttacks4(str) {
|
|
|
115120
115510
|
}
|
|
115121
115511
|
function isPathInWorkspace4(filePath, workspace) {
|
|
115122
115512
|
try {
|
|
115123
|
-
const resolvedPath =
|
|
115513
|
+
const resolvedPath = path131.resolve(workspace, filePath);
|
|
115124
115514
|
if (!fs97.existsSync(resolvedPath)) {
|
|
115125
115515
|
return true;
|
|
115126
115516
|
}
|
|
115127
115517
|
const realWorkspace = fs97.realpathSync(workspace);
|
|
115128
115518
|
const realResolvedPath = fs97.realpathSync(resolvedPath);
|
|
115129
|
-
const relativePath =
|
|
115130
|
-
if (relativePath.startsWith("..") ||
|
|
115519
|
+
const relativePath = path131.relative(realWorkspace, realResolvedPath);
|
|
115520
|
+
if (relativePath.startsWith("..") || path131.isAbsolute(relativePath)) {
|
|
115131
115521
|
return false;
|
|
115132
115522
|
}
|
|
115133
115523
|
return true;
|
|
@@ -115335,7 +115725,7 @@ var suggestPatch = createSwarmTool({
|
|
|
115335
115725
|
});
|
|
115336
115726
|
continue;
|
|
115337
115727
|
}
|
|
115338
|
-
const fullPath =
|
|
115728
|
+
const fullPath = path131.resolve(directory, change.file);
|
|
115339
115729
|
if (!fs97.existsSync(fullPath)) {
|
|
115340
115730
|
errors5.push({
|
|
115341
115731
|
success: false,
|
|
@@ -115639,11 +116029,11 @@ var lean_turbo_acquire_locks = createSwarmTool({
|
|
|
115639
116029
|
init_zod();
|
|
115640
116030
|
init_constants();
|
|
115641
116031
|
import * as fs99 from "node:fs";
|
|
115642
|
-
import * as
|
|
116032
|
+
import * as path133 from "node:path";
|
|
115643
116033
|
|
|
115644
116034
|
// src/turbo/lean/conflicts.ts
|
|
115645
116035
|
import * as fs98 from "node:fs";
|
|
115646
|
-
import * as
|
|
116036
|
+
import * as path132 from "node:path";
|
|
115647
116037
|
var DEFAULT_GLOBAL_FILES = [
|
|
115648
116038
|
"package.json",
|
|
115649
116039
|
"package-lock.json",
|
|
@@ -115770,7 +116160,7 @@ function isProtectedPath2(normalizedPath) {
|
|
|
115770
116160
|
return false;
|
|
115771
116161
|
}
|
|
115772
116162
|
function readTaskScopes(directory, taskId) {
|
|
115773
|
-
const scopePath =
|
|
116163
|
+
const scopePath = path132.join(directory, ".swarm", "scopes", `scope-${taskId}.json`);
|
|
115774
116164
|
try {
|
|
115775
116165
|
if (!fs98.existsSync(scopePath)) {
|
|
115776
116166
|
return null;
|
|
@@ -116158,7 +116548,7 @@ function createEmptyPlan(phaseNumber, planId) {
|
|
|
116158
116548
|
// src/tools/lean-turbo-plan-lanes.ts
|
|
116159
116549
|
init_create_tool();
|
|
116160
116550
|
function readPlanJson(directory) {
|
|
116161
|
-
const planPath =
|
|
116551
|
+
const planPath = path133.join(directory, ".swarm", "plan.json");
|
|
116162
116552
|
if (!fs99.existsSync(planPath)) {
|
|
116163
116553
|
return null;
|
|
116164
116554
|
}
|
|
@@ -116213,7 +116603,7 @@ init_config();
|
|
|
116213
116603
|
// src/turbo/lean/reviewer.ts
|
|
116214
116604
|
init_state();
|
|
116215
116605
|
import * as fs100 from "node:fs/promises";
|
|
116216
|
-
import * as
|
|
116606
|
+
import * as path134 from "node:path";
|
|
116217
116607
|
init_state3();
|
|
116218
116608
|
var DEFAULT_CONFIG3 = {
|
|
116219
116609
|
reviewerAgent: "",
|
|
@@ -116329,9 +116719,9 @@ function parseReviewerVerdict(responseText) {
|
|
|
116329
116719
|
return { verdict, reason };
|
|
116330
116720
|
}
|
|
116331
116721
|
async function writeReviewerEvidence(directory, phase, verdict, reason) {
|
|
116332
|
-
const evidenceDir =
|
|
116722
|
+
const evidenceDir = path134.join(directory, ".swarm", "evidence", String(phase));
|
|
116333
116723
|
await fs100.mkdir(evidenceDir, { recursive: true });
|
|
116334
|
-
const evidencePath =
|
|
116724
|
+
const evidencePath = path134.join(evidenceDir, "lean-turbo-reviewer.json");
|
|
116335
116725
|
const content = JSON.stringify({
|
|
116336
116726
|
phase,
|
|
116337
116727
|
verdict,
|
|
@@ -117136,7 +117526,7 @@ var lean_turbo_status = createSwarmTool({
|
|
|
117136
117526
|
init_spec_schema();
|
|
117137
117527
|
init_create_tool();
|
|
117138
117528
|
import * as fs101 from "node:fs";
|
|
117139
|
-
import * as
|
|
117529
|
+
import * as path135 from "node:path";
|
|
117140
117530
|
var SPEC_FILE_NAME = "spec.md";
|
|
117141
117531
|
var SWARM_DIR2 = ".swarm";
|
|
117142
117532
|
var OBLIGATION_KEYWORDS2 = ["MUST", "SHALL", "SHOULD", "MAY"];
|
|
@@ -117189,7 +117579,7 @@ var lint_spec = createSwarmTool({
|
|
|
117189
117579
|
async execute(_args, directory) {
|
|
117190
117580
|
const errors5 = [];
|
|
117191
117581
|
const warnings = [];
|
|
117192
|
-
const specPath =
|
|
117582
|
+
const specPath = path135.join(directory, SWARM_DIR2, SPEC_FILE_NAME);
|
|
117193
117583
|
if (!fs101.existsSync(specPath)) {
|
|
117194
117584
|
const result2 = {
|
|
117195
117585
|
valid: false,
|
|
@@ -117260,12 +117650,12 @@ var lint_spec = createSwarmTool({
|
|
|
117260
117650
|
// src/tools/mutation-test.ts
|
|
117261
117651
|
init_zod();
|
|
117262
117652
|
import * as fs102 from "node:fs";
|
|
117263
|
-
import * as
|
|
117653
|
+
import * as path137 from "node:path";
|
|
117264
117654
|
|
|
117265
117655
|
// src/mutation/engine.ts
|
|
117266
117656
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
117267
117657
|
import { unlinkSync as unlinkSync17, writeFileSync as writeFileSync25 } from "node:fs";
|
|
117268
|
-
import * as
|
|
117658
|
+
import * as path136 from "node:path";
|
|
117269
117659
|
|
|
117270
117660
|
// src/mutation/equivalence.ts
|
|
117271
117661
|
function isStaticallyEquivalent(originalCode, mutatedCode) {
|
|
@@ -117411,7 +117801,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
|
|
|
117411
117801
|
let patchFile;
|
|
117412
117802
|
try {
|
|
117413
117803
|
const safeId2 = patch.id.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
117414
|
-
patchFile =
|
|
117804
|
+
patchFile = path136.join(workingDir, `.mutation_patch_${safeId2}.diff`);
|
|
117415
117805
|
try {
|
|
117416
117806
|
writeFileSync25(patchFile, patch.patch);
|
|
117417
117807
|
} catch (writeErr) {
|
|
@@ -117815,7 +118205,7 @@ var mutation_test = createSwarmTool({
|
|
|
117815
118205
|
];
|
|
117816
118206
|
for (const filePath of uniquePaths) {
|
|
117817
118207
|
try {
|
|
117818
|
-
const resolvedPath =
|
|
118208
|
+
const resolvedPath = path137.resolve(cwd, filePath);
|
|
117819
118209
|
sourceFiles.set(filePath, fs102.readFileSync(resolvedPath, "utf-8"));
|
|
117820
118210
|
} catch {}
|
|
117821
118211
|
}
|
|
@@ -117835,7 +118225,7 @@ init_zod();
|
|
|
117835
118225
|
init_manager2();
|
|
117836
118226
|
init_detector();
|
|
117837
118227
|
import * as fs103 from "node:fs";
|
|
117838
|
-
import * as
|
|
118228
|
+
import * as path138 from "node:path";
|
|
117839
118229
|
init_create_tool();
|
|
117840
118230
|
var MAX_FILE_SIZE2 = 2 * 1024 * 1024;
|
|
117841
118231
|
var BINARY_CHECK_BYTES = 8192;
|
|
@@ -117901,7 +118291,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
117901
118291
|
if (languages?.length) {
|
|
117902
118292
|
const lowerLangs = languages.map((l) => l.toLowerCase());
|
|
117903
118293
|
filesToCheck = filesToCheck.filter((file3) => {
|
|
117904
|
-
const ext =
|
|
118294
|
+
const ext = path138.extname(file3.path).toLowerCase();
|
|
117905
118295
|
const langDef = getLanguageForExtension(ext);
|
|
117906
118296
|
const fileProfile = getProfileForFile(file3.path);
|
|
117907
118297
|
const langId = fileProfile?.id || langDef?.id;
|
|
@@ -117914,7 +118304,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
117914
118304
|
let skippedCount = 0;
|
|
117915
118305
|
for (const fileInfo of filesToCheck) {
|
|
117916
118306
|
const { path: filePath } = fileInfo;
|
|
117917
|
-
const fullPath =
|
|
118307
|
+
const fullPath = path138.isAbsolute(filePath) ? filePath : path138.join(directory, filePath);
|
|
117918
118308
|
const result = {
|
|
117919
118309
|
path: filePath,
|
|
117920
118310
|
language: "",
|
|
@@ -117963,7 +118353,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
117963
118353
|
results.push(result);
|
|
117964
118354
|
continue;
|
|
117965
118355
|
}
|
|
117966
|
-
const ext =
|
|
118356
|
+
const ext = path138.extname(filePath).toLowerCase();
|
|
117967
118357
|
const langDef = getLanguageForExtension(ext);
|
|
117968
118358
|
result.language = profile?.id || langDef?.id || "unknown";
|
|
117969
118359
|
const errors5 = extractSyntaxErrors(parser, content);
|
|
@@ -118061,7 +118451,7 @@ init_utils();
|
|
|
118061
118451
|
init_create_tool();
|
|
118062
118452
|
init_path_security();
|
|
118063
118453
|
import * as fs104 from "node:fs";
|
|
118064
|
-
import * as
|
|
118454
|
+
import * as path139 from "node:path";
|
|
118065
118455
|
var MAX_TEXT_LENGTH = 200;
|
|
118066
118456
|
var MAX_FILE_SIZE_BYTES11 = 1024 * 1024;
|
|
118067
118457
|
var SUPPORTED_EXTENSIONS4 = new Set([
|
|
@@ -118127,9 +118517,9 @@ function validatePathsInput(paths, cwd) {
|
|
|
118127
118517
|
return { error: "paths contains path traversal", resolvedPath: null };
|
|
118128
118518
|
}
|
|
118129
118519
|
try {
|
|
118130
|
-
const resolvedPath =
|
|
118131
|
-
const normalizedCwd =
|
|
118132
|
-
const normalizedResolved =
|
|
118520
|
+
const resolvedPath = path139.resolve(paths);
|
|
118521
|
+
const normalizedCwd = path139.resolve(cwd);
|
|
118522
|
+
const normalizedResolved = path139.resolve(resolvedPath);
|
|
118133
118523
|
if (!normalizedResolved.startsWith(normalizedCwd)) {
|
|
118134
118524
|
return {
|
|
118135
118525
|
error: "paths must be within the current working directory",
|
|
@@ -118145,7 +118535,7 @@ function validatePathsInput(paths, cwd) {
|
|
|
118145
118535
|
}
|
|
118146
118536
|
}
|
|
118147
118537
|
function isSupportedExtension(filePath) {
|
|
118148
|
-
const ext =
|
|
118538
|
+
const ext = path139.extname(filePath).toLowerCase();
|
|
118149
118539
|
return SUPPORTED_EXTENSIONS4.has(ext);
|
|
118150
118540
|
}
|
|
118151
118541
|
function findSourceFiles3(dir, files = []) {
|
|
@@ -118160,7 +118550,7 @@ function findSourceFiles3(dir, files = []) {
|
|
|
118160
118550
|
if (SKIP_DIRECTORIES5.has(entry)) {
|
|
118161
118551
|
continue;
|
|
118162
118552
|
}
|
|
118163
|
-
const fullPath =
|
|
118553
|
+
const fullPath = path139.join(dir, entry);
|
|
118164
118554
|
let stat8;
|
|
118165
118555
|
try {
|
|
118166
118556
|
stat8 = fs104.statSync(fullPath);
|
|
@@ -118272,7 +118662,7 @@ var todo_extract = createSwarmTool({
|
|
|
118272
118662
|
filesToScan.push(scanPath);
|
|
118273
118663
|
} else {
|
|
118274
118664
|
const errorResult = {
|
|
118275
|
-
error: `unsupported file extension: ${
|
|
118665
|
+
error: `unsupported file extension: ${path139.extname(scanPath)}`,
|
|
118276
118666
|
total: 0,
|
|
118277
118667
|
byPriority: { high: 0, medium: 0, low: 0 },
|
|
118278
118668
|
entries: []
|
|
@@ -118321,17 +118711,17 @@ init_schema();
|
|
|
118321
118711
|
init_qa_gate_profile();
|
|
118322
118712
|
init_gate_evidence();
|
|
118323
118713
|
import * as fs108 from "node:fs";
|
|
118324
|
-
import * as
|
|
118714
|
+
import * as path143 from "node:path";
|
|
118325
118715
|
|
|
118326
118716
|
// src/hooks/diff-scope.ts
|
|
118327
118717
|
init_bun_compat();
|
|
118328
118718
|
import * as fs106 from "node:fs";
|
|
118329
|
-
import * as
|
|
118719
|
+
import * as path141 from "node:path";
|
|
118330
118720
|
|
|
118331
118721
|
// src/utils/gitignore-warning.ts
|
|
118332
118722
|
init_bun_compat();
|
|
118333
118723
|
import * as fs105 from "node:fs";
|
|
118334
|
-
import * as
|
|
118724
|
+
import * as path140 from "node:path";
|
|
118335
118725
|
var _internals58 = { bunSpawn };
|
|
118336
118726
|
var _swarmGitExcludedChecked = false;
|
|
118337
118727
|
function fileCoversSwarm(content) {
|
|
@@ -118405,10 +118795,10 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
118405
118795
|
const excludeRelPath = excludePathRaw.trim();
|
|
118406
118796
|
if (!excludeRelPath)
|
|
118407
118797
|
return;
|
|
118408
|
-
const excludePath =
|
|
118798
|
+
const excludePath = path140.isAbsolute(excludeRelPath) ? excludeRelPath : path140.join(directory, excludeRelPath);
|
|
118409
118799
|
if (checkIgnoreExitCode !== 0) {
|
|
118410
118800
|
try {
|
|
118411
|
-
fs105.mkdirSync(
|
|
118801
|
+
fs105.mkdirSync(path140.dirname(excludePath), { recursive: true });
|
|
118412
118802
|
let existing = "";
|
|
118413
118803
|
try {
|
|
118414
118804
|
existing = fs105.readFileSync(excludePath, "utf8");
|
|
@@ -118452,7 +118842,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
118452
118842
|
var _internals59 = { bunSpawn };
|
|
118453
118843
|
function getDeclaredScope(taskId, directory) {
|
|
118454
118844
|
try {
|
|
118455
|
-
const planPath =
|
|
118845
|
+
const planPath = path141.join(directory, ".swarm", "plan.json");
|
|
118456
118846
|
if (!fs106.existsSync(planPath))
|
|
118457
118847
|
return null;
|
|
118458
118848
|
const raw = fs106.readFileSync(planPath, "utf-8");
|
|
@@ -118558,7 +118948,7 @@ init_telemetry();
|
|
|
118558
118948
|
// src/turbo/lean/task-completion.ts
|
|
118559
118949
|
init_file_locks();
|
|
118560
118950
|
import * as fs107 from "node:fs";
|
|
118561
|
-
import * as
|
|
118951
|
+
import * as path142 from "node:path";
|
|
118562
118952
|
var _internals60 = {
|
|
118563
118953
|
listActiveLocks,
|
|
118564
118954
|
verifyLeanTurboTaskCompletion
|
|
@@ -118577,7 +118967,7 @@ var TIER_3_PATTERNS = [
|
|
|
118577
118967
|
];
|
|
118578
118968
|
function matchesTier3Pattern(files) {
|
|
118579
118969
|
for (const file3 of files) {
|
|
118580
|
-
const fileName =
|
|
118970
|
+
const fileName = path142.basename(file3);
|
|
118581
118971
|
for (const pattern of TIER_3_PATTERNS) {
|
|
118582
118972
|
if (pattern.test(fileName)) {
|
|
118583
118973
|
return true;
|
|
@@ -118589,7 +118979,7 @@ function matchesTier3Pattern(files) {
|
|
|
118589
118979
|
function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
118590
118980
|
let persisted = null;
|
|
118591
118981
|
try {
|
|
118592
|
-
const statePath =
|
|
118982
|
+
const statePath = path142.join(directory, ".swarm", "turbo-state.json");
|
|
118593
118983
|
if (!fs107.existsSync(statePath)) {
|
|
118594
118984
|
return {
|
|
118595
118985
|
ok: false,
|
|
@@ -118673,11 +119063,11 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
|
118673
119063
|
};
|
|
118674
119064
|
}
|
|
118675
119065
|
const phase = runState.phase ?? 0;
|
|
118676
|
-
const evidencePath =
|
|
118677
|
-
const expectedDir =
|
|
118678
|
-
const resolvedPath =
|
|
118679
|
-
const resolvedDir =
|
|
118680
|
-
if (!resolvedPath.startsWith(resolvedDir +
|
|
119066
|
+
const evidencePath = path142.join(directory, ".swarm", "evidence", String(phase), "lean-turbo", `${lane.laneId}.json`);
|
|
119067
|
+
const expectedDir = path142.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
|
|
119068
|
+
const resolvedPath = path142.resolve(evidencePath);
|
|
119069
|
+
const resolvedDir = path142.resolve(expectedDir);
|
|
119070
|
+
if (!resolvedPath.startsWith(resolvedDir + path142.sep) && resolvedPath !== resolvedDir) {
|
|
118681
119071
|
return {
|
|
118682
119072
|
ok: false,
|
|
118683
119073
|
reason: `Lane ID causes path traversal: ${lane.laneId}`,
|
|
@@ -118717,7 +119107,7 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
|
118717
119107
|
}
|
|
118718
119108
|
let filesTouched = [];
|
|
118719
119109
|
try {
|
|
118720
|
-
const planPath =
|
|
119110
|
+
const planPath = path142.join(directory, ".swarm", "plan.json");
|
|
118721
119111
|
const planRaw = fs107.readFileSync(planPath, "utf-8");
|
|
118722
119112
|
const plan = JSON.parse(planRaw);
|
|
118723
119113
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -118801,7 +119191,7 @@ var TIER_3_PATTERNS2 = [
|
|
|
118801
119191
|
];
|
|
118802
119192
|
function matchesTier3Pattern2(files) {
|
|
118803
119193
|
for (const file3 of files) {
|
|
118804
|
-
const fileName =
|
|
119194
|
+
const fileName = path143.basename(file3);
|
|
118805
119195
|
for (const pattern of TIER_3_PATTERNS2) {
|
|
118806
119196
|
if (pattern.test(fileName)) {
|
|
118807
119197
|
return true;
|
|
@@ -118840,7 +119230,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
118840
119230
|
if (!skipStandardTurboBypass && hasActiveTurboMode()) {
|
|
118841
119231
|
const resolvedDir2 = workingDirectory;
|
|
118842
119232
|
try {
|
|
118843
|
-
const planPath =
|
|
119233
|
+
const planPath = path143.join(resolvedDir2, ".swarm", "plan.json");
|
|
118844
119234
|
const planRaw = fs108.readFileSync(planPath, "utf-8");
|
|
118845
119235
|
const plan = JSON.parse(planRaw);
|
|
118846
119236
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -118918,7 +119308,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
118918
119308
|
}
|
|
118919
119309
|
if (resolvedDir) {
|
|
118920
119310
|
try {
|
|
118921
|
-
const planPath =
|
|
119311
|
+
const planPath = path143.join(resolvedDir, ".swarm", "plan.json");
|
|
118922
119312
|
const planRaw = fs108.readFileSync(planPath, "utf-8");
|
|
118923
119313
|
const plan = JSON.parse(planRaw);
|
|
118924
119314
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -119155,8 +119545,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
119155
119545
|
};
|
|
119156
119546
|
}
|
|
119157
119547
|
}
|
|
119158
|
-
normalizedDir =
|
|
119159
|
-
const pathParts = normalizedDir.split(
|
|
119548
|
+
normalizedDir = path143.normalize(args2.working_directory);
|
|
119549
|
+
const pathParts = normalizedDir.split(path143.sep);
|
|
119160
119550
|
if (pathParts.includes("..")) {
|
|
119161
119551
|
return {
|
|
119162
119552
|
success: false,
|
|
@@ -119166,10 +119556,10 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
119166
119556
|
]
|
|
119167
119557
|
};
|
|
119168
119558
|
}
|
|
119169
|
-
const resolvedDir =
|
|
119559
|
+
const resolvedDir = path143.resolve(normalizedDir);
|
|
119170
119560
|
try {
|
|
119171
119561
|
const realPath = fs108.realpathSync(resolvedDir);
|
|
119172
|
-
const planPath =
|
|
119562
|
+
const planPath = path143.join(realPath, ".swarm", "plan.json");
|
|
119173
119563
|
if (!fs108.existsSync(planPath)) {
|
|
119174
119564
|
return {
|
|
119175
119565
|
success: false,
|
|
@@ -119200,9 +119590,9 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
119200
119590
|
directory = fallbackDir;
|
|
119201
119591
|
}
|
|
119202
119592
|
if (fallbackDir && directory !== fallbackDir) {
|
|
119203
|
-
const canonicalDir = fs108.realpathSync(
|
|
119204
|
-
const canonicalRoot = fs108.realpathSync(
|
|
119205
|
-
if (canonicalDir.startsWith(canonicalRoot +
|
|
119593
|
+
const canonicalDir = fs108.realpathSync(path143.resolve(directory));
|
|
119594
|
+
const canonicalRoot = fs108.realpathSync(path143.resolve(fallbackDir));
|
|
119595
|
+
if (canonicalDir.startsWith(canonicalRoot + path143.sep)) {
|
|
119206
119596
|
return {
|
|
119207
119597
|
success: false,
|
|
119208
119598
|
message: `Invalid working_directory: "${directory}" is a subdirectory of ` + `the project root "${fallbackDir}". Pass the project root path or ` + `omit working_directory entirely.`,
|
|
@@ -119214,8 +119604,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
119214
119604
|
}
|
|
119215
119605
|
if (args2.status === "in_progress") {
|
|
119216
119606
|
try {
|
|
119217
|
-
const evidencePath =
|
|
119218
|
-
fs108.mkdirSync(
|
|
119607
|
+
const evidencePath = path143.join(directory, ".swarm", "evidence", `${args2.task_id}.json`);
|
|
119608
|
+
fs108.mkdirSync(path143.dirname(evidencePath), { recursive: true });
|
|
119219
119609
|
const fd = fs108.openSync(evidencePath, "wx");
|
|
119220
119610
|
let writeOk = false;
|
|
119221
119611
|
try {
|
|
@@ -119239,7 +119629,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
119239
119629
|
recoverTaskStateFromDelegations(args2.task_id, directory);
|
|
119240
119630
|
let phaseRequiresReviewer = true;
|
|
119241
119631
|
try {
|
|
119242
|
-
const planPath =
|
|
119632
|
+
const planPath = path143.join(directory, ".swarm", "plan.json");
|
|
119243
119633
|
const planRaw = fs108.readFileSync(planPath, "utf-8");
|
|
119244
119634
|
const plan = JSON.parse(planRaw);
|
|
119245
119635
|
const taskPhase = plan.phases.find((p) => p.tasks.some((t) => t.id === args2.task_id));
|
|
@@ -119551,7 +119941,7 @@ init_ledger();
|
|
|
119551
119941
|
init_manager();
|
|
119552
119942
|
init_create_tool();
|
|
119553
119943
|
import fs109 from "node:fs";
|
|
119554
|
-
import
|
|
119944
|
+
import path144 from "node:path";
|
|
119555
119945
|
function normalizeVerdict(verdict) {
|
|
119556
119946
|
switch (verdict) {
|
|
119557
119947
|
case "APPROVED":
|
|
@@ -119599,7 +119989,7 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
119599
119989
|
entries: [evidenceEntry]
|
|
119600
119990
|
};
|
|
119601
119991
|
const filename = "drift-verifier.json";
|
|
119602
|
-
const relativePath =
|
|
119992
|
+
const relativePath = path144.join("evidence", String(phase), filename);
|
|
119603
119993
|
let validatedPath;
|
|
119604
119994
|
try {
|
|
119605
119995
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -119610,10 +120000,10 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
119610
120000
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
119611
120001
|
}, null, 2);
|
|
119612
120002
|
}
|
|
119613
|
-
const evidenceDir =
|
|
120003
|
+
const evidenceDir = path144.dirname(validatedPath);
|
|
119614
120004
|
try {
|
|
119615
120005
|
await fs109.promises.mkdir(evidenceDir, { recursive: true });
|
|
119616
|
-
const tempPath =
|
|
120006
|
+
const tempPath = path144.join(evidenceDir, `.${filename}.tmp`);
|
|
119617
120007
|
await fs109.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
119618
120008
|
await fs109.promises.rename(tempPath, validatedPath);
|
|
119619
120009
|
let snapshotInfo;
|
|
@@ -119709,7 +120099,7 @@ var write_drift_evidence = createSwarmTool({
|
|
|
119709
120099
|
init_zod();
|
|
119710
120100
|
init_loader();
|
|
119711
120101
|
import fs110 from "node:fs";
|
|
119712
|
-
import
|
|
120102
|
+
import path145 from "node:path";
|
|
119713
120103
|
init_utils2();
|
|
119714
120104
|
init_manager();
|
|
119715
120105
|
init_create_tool();
|
|
@@ -119797,7 +120187,7 @@ async function executeWriteFinalCouncilEvidence(args2, directory) {
|
|
|
119797
120187
|
timestamp: synthesis.timestamp
|
|
119798
120188
|
};
|
|
119799
120189
|
const filename = "final-council.json";
|
|
119800
|
-
const relativePath =
|
|
120190
|
+
const relativePath = path145.join("evidence", filename);
|
|
119801
120191
|
let validatedPath;
|
|
119802
120192
|
try {
|
|
119803
120193
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -119811,10 +120201,10 @@ async function executeWriteFinalCouncilEvidence(args2, directory) {
|
|
|
119811
120201
|
const evidenceContent = {
|
|
119812
120202
|
entries: [evidenceEntry]
|
|
119813
120203
|
};
|
|
119814
|
-
const evidenceDir =
|
|
120204
|
+
const evidenceDir = path145.dirname(validatedPath);
|
|
119815
120205
|
try {
|
|
119816
120206
|
await fs110.promises.mkdir(evidenceDir, { recursive: true });
|
|
119817
|
-
const tempPath =
|
|
120207
|
+
const tempPath = path145.join(evidenceDir, `.${filename}.tmp`);
|
|
119818
120208
|
await fs110.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
119819
120209
|
await fs110.promises.rename(tempPath, validatedPath);
|
|
119820
120210
|
return JSON.stringify({
|
|
@@ -119873,7 +120263,7 @@ init_zod();
|
|
|
119873
120263
|
init_utils2();
|
|
119874
120264
|
init_create_tool();
|
|
119875
120265
|
import fs111 from "node:fs";
|
|
119876
|
-
import
|
|
120266
|
+
import path146 from "node:path";
|
|
119877
120267
|
function normalizeVerdict2(verdict) {
|
|
119878
120268
|
switch (verdict) {
|
|
119879
120269
|
case "APPROVED":
|
|
@@ -119921,7 +120311,7 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
119921
120311
|
entries: [evidenceEntry]
|
|
119922
120312
|
};
|
|
119923
120313
|
const filename = "hallucination-guard.json";
|
|
119924
|
-
const relativePath =
|
|
120314
|
+
const relativePath = path146.join("evidence", String(phase), filename);
|
|
119925
120315
|
let validatedPath;
|
|
119926
120316
|
try {
|
|
119927
120317
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -119932,10 +120322,10 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
119932
120322
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
119933
120323
|
}, null, 2);
|
|
119934
120324
|
}
|
|
119935
|
-
const evidenceDir =
|
|
120325
|
+
const evidenceDir = path146.dirname(validatedPath);
|
|
119936
120326
|
try {
|
|
119937
120327
|
await fs111.promises.mkdir(evidenceDir, { recursive: true });
|
|
119938
|
-
const tempPath =
|
|
120328
|
+
const tempPath = path146.join(evidenceDir, `.${filename}.tmp`);
|
|
119939
120329
|
await fs111.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
119940
120330
|
await fs111.promises.rename(tempPath, validatedPath);
|
|
119941
120331
|
return JSON.stringify({
|
|
@@ -119984,7 +120374,7 @@ init_zod();
|
|
|
119984
120374
|
init_utils2();
|
|
119985
120375
|
init_create_tool();
|
|
119986
120376
|
import fs112 from "node:fs";
|
|
119987
|
-
import
|
|
120377
|
+
import path147 from "node:path";
|
|
119988
120378
|
function normalizeVerdict3(verdict) {
|
|
119989
120379
|
switch (verdict) {
|
|
119990
120380
|
case "PASS":
|
|
@@ -120058,7 +120448,7 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
120058
120448
|
entries: [evidenceEntry]
|
|
120059
120449
|
};
|
|
120060
120450
|
const filename = "mutation-gate.json";
|
|
120061
|
-
const relativePath =
|
|
120451
|
+
const relativePath = path147.join("evidence", String(phase), filename);
|
|
120062
120452
|
let validatedPath;
|
|
120063
120453
|
try {
|
|
120064
120454
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -120069,10 +120459,10 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
120069
120459
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
120070
120460
|
}, null, 2);
|
|
120071
120461
|
}
|
|
120072
|
-
const evidenceDir =
|
|
120462
|
+
const evidenceDir = path147.dirname(validatedPath);
|
|
120073
120463
|
try {
|
|
120074
120464
|
await fs112.promises.mkdir(evidenceDir, { recursive: true });
|
|
120075
|
-
const tempPath =
|
|
120465
|
+
const tempPath = path147.join(evidenceDir, `.${filename}.tmp`);
|
|
120076
120466
|
await fs112.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
120077
120467
|
await fs112.promises.rename(tempPath, validatedPath);
|
|
120078
120468
|
return JSON.stringify({
|
|
@@ -120422,7 +120812,7 @@ async function initializeOpenCodeSwarm(ctx) {
|
|
|
120422
120812
|
const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
|
|
120423
120813
|
preflightTriggerManager = new PTM(automationConfig);
|
|
120424
120814
|
const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
|
|
120425
|
-
const swarmDir =
|
|
120815
|
+
const swarmDir = path149.resolve(ctx.directory, ".swarm");
|
|
120426
120816
|
statusArtifact = new ASA(swarmDir);
|
|
120427
120817
|
statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
|
|
120428
120818
|
if (automationConfig.capabilities?.evidence_auto_summaries === true) {
|
|
@@ -120601,30 +120991,29 @@ async function initializeOpenCodeSwarm(ctx) {
|
|
|
120601
120991
|
swarm_command: createSwarmCommandTool(agentDefinitionMap)
|
|
120602
120992
|
},
|
|
120603
120993
|
config: async (opencodeConfig) => {
|
|
120604
|
-
|
|
120605
|
-
|
|
120606
|
-
|
|
120607
|
-
|
|
120608
|
-
opencodeConfig.agent = { ...agents };
|
|
120609
|
-
} else {
|
|
120610
|
-
Object.assign(opencodeConfig.agent, agents);
|
|
120994
|
+
const isObjectRecord = (value) => typeof value === "object" && value !== null;
|
|
120995
|
+
const pluginConfig = opencodeConfig;
|
|
120996
|
+
if (!isObjectRecord(pluginConfig.agent)) {
|
|
120997
|
+
pluginConfig.agent = {};
|
|
120611
120998
|
}
|
|
120999
|
+
const agentConfig = pluginConfig.agent;
|
|
121000
|
+
Object.assign(agentConfig, agents);
|
|
120612
121001
|
const autoSelect = config3?.auto_select_architect;
|
|
120613
121002
|
if (autoSelect) {
|
|
120614
121003
|
const hasArchitect = Object.keys(agents).some((name2) => stripKnownSwarmPrefix(name2) === "architect");
|
|
120615
121004
|
if (hasArchitect) {
|
|
120616
121005
|
for (const builtin of ["build", "plan"]) {
|
|
120617
|
-
const existing =
|
|
120618
|
-
if (existing &&
|
|
121006
|
+
const existing = agentConfig[builtin];
|
|
121007
|
+
if (isObjectRecord(existing) && existing.disable === true) {
|
|
120619
121008
|
continue;
|
|
120620
121009
|
}
|
|
120621
|
-
|
|
120622
|
-
...existing
|
|
121010
|
+
agentConfig[builtin] = {
|
|
121011
|
+
...isObjectRecord(existing) ? existing : {},
|
|
120623
121012
|
disable: true
|
|
120624
121013
|
};
|
|
120625
121014
|
}
|
|
120626
121015
|
if (autoSelect === true) {
|
|
120627
|
-
const primaryArchitects = Object.entries(agents).filter(([name2, cfg]) => stripKnownSwarmPrefix(name2) === "architect" && cfg.mode === "primary");
|
|
121016
|
+
const primaryArchitects = Object.entries(agents).filter(([name2, cfg]) => stripKnownSwarmPrefix(name2) === "architect" && isObjectRecord(cfg) && cfg.mode === "primary");
|
|
120628
121017
|
if (primaryArchitects.length > 1) {
|
|
120629
121018
|
const names = primaryArchitects.map(([n]) => n).join(", ");
|
|
120630
121019
|
addDeferredWarning(`[swarm] auto_select_architect is true but ${primaryArchitects.length} architect agents are primary (${names}). Consider setting auto_select_architect to a specific agent name.`);
|
|
@@ -120636,22 +121025,19 @@ async function initializeOpenCodeSwarm(ctx) {
|
|
|
120636
121025
|
if (targetIsArchitect) {
|
|
120637
121026
|
for (const [name2, cfg] of Object.entries(agents)) {
|
|
120638
121027
|
if (stripKnownSwarmPrefix(name2) === "architect" && name2 !== targetName) {
|
|
120639
|
-
|
|
120640
|
-
|
|
120641
|
-
|
|
120642
|
-
|
|
120643
|
-
};
|
|
120644
|
-
}
|
|
121028
|
+
agentConfig[name2] = {
|
|
121029
|
+
...isObjectRecord(cfg) ? cfg : {},
|
|
121030
|
+
mode: "subagent"
|
|
121031
|
+
};
|
|
120645
121032
|
}
|
|
120646
121033
|
}
|
|
120647
|
-
|
|
120648
|
-
|
|
120649
|
-
|
|
120650
|
-
|
|
120651
|
-
|
|
120652
|
-
|
|
120653
|
-
|
|
120654
|
-
}
|
|
121034
|
+
const targetExisting = agentConfig[targetName];
|
|
121035
|
+
const targetAgent = agents[targetName];
|
|
121036
|
+
agentConfig[targetName] = {
|
|
121037
|
+
...isObjectRecord(targetExisting) ? targetExisting : {},
|
|
121038
|
+
...isObjectRecord(targetAgent) ? targetAgent : {},
|
|
121039
|
+
mode: "primary"
|
|
121040
|
+
};
|
|
120655
121041
|
} else {
|
|
120656
121042
|
addDeferredWarning(`[swarm] auto_select_architect is set to "${targetName}" but that is not a known architect agent. No architect demotion applied.`);
|
|
120657
121043
|
}
|
|
@@ -121006,7 +121392,7 @@ ${promptRaw}`;
|
|
|
121006
121392
|
"ci-failure-resolver": "CI/CD failure resolution"
|
|
121007
121393
|
};
|
|
121008
121394
|
const skillPaths = topSkills.map((s) => {
|
|
121009
|
-
const dirName =
|
|
121395
|
+
const dirName = path149.basename(path149.dirname(s.skillPath));
|
|
121010
121396
|
const desc = SKILL_DESCRIPTIONS[dirName] ?? dirName;
|
|
121011
121397
|
return `file:${s.skillPath} (-- ${desc})`;
|
|
121012
121398
|
}).join(", ");
|
|
@@ -121015,7 +121401,7 @@ ${promptRaw}`;
|
|
|
121015
121401
|
|
|
121016
121402
|
${promptRaw}`;
|
|
121017
121403
|
argsRecord.prompt = newPrompt;
|
|
121018
|
-
const skillNames = topSkills.map((s) => `${
|
|
121404
|
+
const skillNames = topSkills.map((s) => `${path149.basename(s.skillPath)} (score: ${s.score.toFixed(2)})`).join(", ");
|
|
121019
121405
|
console.warn(`[skill-propagation-gate] Injected skills: ${skillNames}`);
|
|
121020
121406
|
for (const skill of topSkills) {
|
|
121021
121407
|
try {
|