opencode-swarm 6.29.3 → 6.29.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -9
- package/dist/cli/index.js +15 -12
- package/dist/index.js +267 -203
- package/dist/tools/test-runner.d.ts +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -35193,7 +35193,8 @@ var init_test_runner = __esm(() => {
|
|
|
35193
35193
|
scope: tool.schema.enum(["all", "convention", "graph"]).optional().describe('Test scope: "all" runs full suite, "convention" maps source files to test files by naming, "graph" finds related tests via imports'),
|
|
35194
35194
|
files: tool.schema.array(tool.schema.string()).optional().describe("Specific files to test (used with convention or graph scope)"),
|
|
35195
35195
|
coverage: tool.schema.boolean().optional().describe("Enable coverage reporting if supported"),
|
|
35196
|
-
timeout_ms: tool.schema.number().optional().describe("Timeout in milliseconds (default 60000, max 300000)")
|
|
35196
|
+
timeout_ms: tool.schema.number().optional().describe("Timeout in milliseconds (default 60000, max 300000)"),
|
|
35197
|
+
allow_full_suite: tool.schema.boolean().optional().describe('Explicit opt-in for scope "all". Required because full-suite output can destabilize SSE streaming.')
|
|
35197
35198
|
},
|
|
35198
35199
|
async execute(args2, directory) {
|
|
35199
35200
|
const workingDir = directory.trim() || directory;
|
|
@@ -35245,14 +35246,16 @@ var init_test_runner = __esm(() => {
|
|
|
35245
35246
|
}
|
|
35246
35247
|
const scope = args2.scope || "all";
|
|
35247
35248
|
if (scope === "all") {
|
|
35248
|
-
|
|
35249
|
-
|
|
35250
|
-
|
|
35251
|
-
|
|
35252
|
-
|
|
35253
|
-
|
|
35254
|
-
|
|
35255
|
-
|
|
35249
|
+
if (!args2.allow_full_suite) {
|
|
35250
|
+
const errorResult = {
|
|
35251
|
+
success: false,
|
|
35252
|
+
framework: "none",
|
|
35253
|
+
scope: "all",
|
|
35254
|
+
error: 'Full-suite test execution (scope: "all") requires allow_full_suite: true',
|
|
35255
|
+
message: 'Set allow_full_suite: true to confirm intentional full-suite execution. Use scope "convention" or "graph" for targeted tests. Full-suite output is large and may destabilize SSE streaming on some opencode versions.'
|
|
35256
|
+
};
|
|
35257
|
+
return JSON.stringify(errorResult, null, 2);
|
|
35258
|
+
}
|
|
35256
35259
|
}
|
|
35257
35260
|
if ((scope === "convention" || scope === "graph") && (!args2.files || args2.files.length === 0)) {
|
|
35258
35261
|
const errorResult = {
|
|
@@ -35287,7 +35290,7 @@ var init_test_runner = __esm(() => {
|
|
|
35287
35290
|
let testFiles = [];
|
|
35288
35291
|
let graphFallbackReason;
|
|
35289
35292
|
let effectiveScope = scope;
|
|
35290
|
-
if (scope === "convention") {
|
|
35293
|
+
if (scope === "all") {} else if (scope === "convention") {
|
|
35291
35294
|
const sourceFiles = args2.files.filter((f) => {
|
|
35292
35295
|
const ext = path23.extname(f).toLowerCase();
|
|
35293
35296
|
return SOURCE_EXTENSIONS.has(ext);
|
|
@@ -35327,7 +35330,7 @@ var init_test_runner = __esm(() => {
|
|
|
35327
35330
|
testFiles = getTestFilesFromConvention(sourceFiles);
|
|
35328
35331
|
}
|
|
35329
35332
|
}
|
|
35330
|
-
if (testFiles.length === 0) {
|
|
35333
|
+
if (scope !== "all" && testFiles.length === 0) {
|
|
35331
35334
|
const errorResult = {
|
|
35332
35335
|
success: false,
|
|
35333
35336
|
framework,
|
|
@@ -35337,7 +35340,7 @@ var init_test_runner = __esm(() => {
|
|
|
35337
35340
|
};
|
|
35338
35341
|
return JSON.stringify(errorResult, null, 2);
|
|
35339
35342
|
}
|
|
35340
|
-
if (testFiles.length > MAX_SAFE_TEST_FILES) {
|
|
35343
|
+
if (scope !== "all" && testFiles.length > MAX_SAFE_TEST_FILES) {
|
|
35341
35344
|
const sampleFiles = testFiles.slice(0, 5);
|
|
35342
35345
|
const errorResult = {
|
|
35343
35346
|
success: false,
|
|
@@ -37601,11 +37604,11 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
37601
37604
|
throw toThrow;
|
|
37602
37605
|
}, "quit_");
|
|
37603
37606
|
var scriptDirectory = "";
|
|
37604
|
-
function locateFile(
|
|
37607
|
+
function locateFile(path47) {
|
|
37605
37608
|
if (Module["locateFile"]) {
|
|
37606
|
-
return Module["locateFile"](
|
|
37609
|
+
return Module["locateFile"](path47, scriptDirectory);
|
|
37607
37610
|
}
|
|
37608
|
-
return scriptDirectory +
|
|
37611
|
+
return scriptDirectory + path47;
|
|
37609
37612
|
}
|
|
37610
37613
|
__name(locateFile, "locateFile");
|
|
37611
37614
|
var readAsync, readBinary;
|
|
@@ -39353,7 +39356,7 @@ var init_runtime = __esm(() => {
|
|
|
39353
39356
|
});
|
|
39354
39357
|
|
|
39355
39358
|
// src/index.ts
|
|
39356
|
-
import * as
|
|
39359
|
+
import * as path57 from "path";
|
|
39357
39360
|
|
|
39358
39361
|
// src/agents/index.ts
|
|
39359
39362
|
init_config();
|
|
@@ -40412,6 +40415,22 @@ TASK GRANULARITY RULES:
|
|
|
40412
40415
|
- Compound verbs are OK when they describe a single logical change: "add validation to handler and update its test" = 1 task. "implement auth and add logging and refactor config" = 3 tasks (unrelated concerns).
|
|
40413
40416
|
- Coder receives ONE task. You make ALL scope decisions in the plan. Coder makes zero scope decisions.
|
|
40414
40417
|
|
|
40418
|
+
TEST TASK DEDUPLICATION:
|
|
40419
|
+
The QA gate (Stage B, step 5l) runs test_engineer-verification on EVERY implementation task.
|
|
40420
|
+
This means tests are written, run, and verified as part of the gate \u2014 NOT as separate plan tasks.
|
|
40421
|
+
|
|
40422
|
+
DO NOT create separate "write tests for X" or "add test coverage for X" tasks. They are redundant with the gate and waste execution budget.
|
|
40423
|
+
|
|
40424
|
+
Research confirms this: controlled experiments across 6 LLMs (arXiv:2602.07900) found that large shifts in test-writing volume yielded only 0\u20132.6% resolution change while consuming 20\u201349% more tokens. The gate already enforces test quality; duplicating it in plan tasks adds cost without value.
|
|
40425
|
+
|
|
40426
|
+
CREATE a dedicated test task ONLY when:
|
|
40427
|
+
- The work is PURE test infrastructure (new fixtures, test helpers, mock factories, CI config) with no implementation
|
|
40428
|
+
- Integration tests span multiple modules changed across different implementation tasks within the same phase
|
|
40429
|
+
- Coverage is explicitly below threshold and the user requests a dedicated coverage pass
|
|
40430
|
+
|
|
40431
|
+
If in doubt, do NOT create a test task. The gate handles it.
|
|
40432
|
+
Note: this is prompt-level guidance for the architect's planning behavior, not a hard gate \u2014 the behavioral enforcement is that test_engineer already writes tests at the QA gate level.
|
|
40433
|
+
|
|
40415
40434
|
PHASE COUNT GUIDANCE:
|
|
40416
40435
|
- Plans with 5+ tasks SHOULD be split into at least 2 phases.
|
|
40417
40436
|
- Plans with 10+ tasks MUST be split into at least 3 phases.
|
|
@@ -40531,6 +40550,18 @@ Treating pre_check_batch as a substitute for {{AGENT_PREFIX}}reviewer is a PROCE
|
|
|
40531
40550
|
\u2192 If TRIGGERED: Print "security-reviewer: [APPROVED | REJECTED \u2014 reason]"
|
|
40532
40551
|
5l. {{AGENT_PREFIX}}test_engineer - Verification tests. FAIL \u2192 coder retry from 5g.
|
|
40533
40552
|
\u2192 REQUIRED: Print "testengineer-verification: [PASS N/N | FAIL \u2014 details]"
|
|
40553
|
+
5l-bis. REGRESSION SWEEP (automatic after test_engineer-verification PASS):
|
|
40554
|
+
Run test_runner with { scope: "graph", files: [<all source files changed by coder in this task>] }.
|
|
40555
|
+
scope:"graph" traces imports to discover test files beyond the task's own tests that may be affected by this change.
|
|
40556
|
+
|
|
40557
|
+
Outcomes:
|
|
40558
|
+
- If scope:"graph" returns ONLY the same test files test_engineer already ran \u2192 SKIP (no additional tests found). Print "regression-sweep: SKIPPED \u2014 no related tests beyond task scope"
|
|
40559
|
+
- If scope:"graph" returns additional test files AND all pass \u2192 PASS. Print "regression-sweep: PASS [N additional tests, M files]"
|
|
40560
|
+
- If scope:"graph" returns additional test files AND any FAIL \u2192 return to coder with: "REGRESSION DETECTED: Your changes in [files] broke [N] tests in [test files]. The failing tests are CORRECT \u2014 fix the source code, not the tests." Coder retry from 5g.
|
|
40561
|
+
- If test_runner fails to execute (error, timeout, no framework detected) \u2192 SKIP. Print "regression-sweep: SKIPPED \u2014 test_runner error" and continue pipeline. Do NOT block on test_runner infrastructure failures.
|
|
40562
|
+
|
|
40563
|
+
IMPORTANT: The regression sweep runs test_runner DIRECTLY (architect calls the tool). Do NOT delegate to test_engineer for this \u2014 the test_engineer's EXECUTION BOUNDARY restricts it to its own test files. The architect has unrestricted test_runner access.
|
|
40564
|
+
\u2192 REQUIRED: Print "regression-sweep: [PASS N additional tests | SKIPPED \u2014 no related tests beyond task scope | SKIPPED \u2014 test_runner error | FAIL \u2014 REGRESSION DETECTED in files]"
|
|
40534
40565
|
{{ADVERSARIAL_TEST_STEP}}
|
|
40535
40566
|
5n. COVERAGE CHECK: If {{AGENT_PREFIX}}test_engineer reports coverage < 70% \u2192 delegate {{AGENT_PREFIX}}test_engineer for an additional test pass targeting uncovered paths. This is a soft guideline; use judgment for trivial tasks.
|
|
40536
40567
|
|
|
@@ -40540,6 +40571,7 @@ PRE-COMMIT RULE \u2014 Before ANY commit or push:
|
|
|
40540
40571
|
[ ] Did {{AGENT_PREFIX}}test_engineer run and return PASS? (not "the code looks correct" \u2014 the agent must have run)
|
|
40541
40572
|
[ ] Did pre_check_batch run with gates_passed true?
|
|
40542
40573
|
[ ] Did the diff step run?
|
|
40574
|
+
[ ] Did regression-sweep run (or SKIP with no related tests or test_runner error)?
|
|
40543
40575
|
|
|
40544
40576
|
If ANY box is unchecked: DO NOT COMMIT. Return to step 5b.
|
|
40545
40577
|
There is no override. A commit without a completed QA gate is a workflow violation.
|
|
@@ -40555,6 +40587,7 @@ PRE-COMMIT RULE \u2014 Before ANY commit or push:
|
|
|
40555
40587
|
[GATE] reviewer: APPROVED \u2014 value: ___
|
|
40556
40588
|
[GATE] security-reviewer: APPROVED / SKIPPED \u2014 value: ___
|
|
40557
40589
|
[GATE] test_engineer-verification: PASS \u2014 value: ___
|
|
40590
|
+
[GATE] regression-sweep: PASS / SKIPPED \u2014 value: ___
|
|
40558
40591
|
{{ADVERSARIAL_TEST_CHECKLIST}}
|
|
40559
40592
|
[GATE] coverage: \u226570% / soft-skip \u2014 value: ___
|
|
40560
40593
|
|
|
@@ -41787,7 +41820,8 @@ WORKFLOW:
|
|
|
41787
41820
|
EXECUTION BOUNDARY:
|
|
41788
41821
|
- Blast radius is the FILE path(s) in input
|
|
41789
41822
|
- When calling test_runner, use: { scope: "convention", files: ["<your-test-file-path>"] }
|
|
41790
|
-
-
|
|
41823
|
+
- scope: "all" is PROHIBITED for test_engineer \u2014 full-suite output can destabilize opencode's SSE streaming, and the architect handles regression sweeps separately via scope: "graph"
|
|
41824
|
+
- If you need to verify tests beyond your assigned file, report the concern in your VERDICT and the architect will handle it
|
|
41791
41825
|
- If you wrote tests/foo.test.ts for src/foo.ts, you MUST run only tests/foo.test.ts
|
|
41792
41826
|
|
|
41793
41827
|
TOOL USAGE:
|
|
@@ -50766,6 +50800,7 @@ function consolidateSystemMessages(messages) {
|
|
|
50766
50800
|
// src/hooks/phase-monitor.ts
|
|
50767
50801
|
init_schema();
|
|
50768
50802
|
init_manager2();
|
|
50803
|
+
import * as path31 from "path";
|
|
50769
50804
|
init_utils2();
|
|
50770
50805
|
function createPhaseMonitorHook(directory, preflightManager, curatorRunner = runCuratorInit) {
|
|
50771
50806
|
let lastKnownPhase = null;
|
|
@@ -50781,7 +50816,13 @@ function createPhaseMonitorHook(directory, preflightManager, curatorRunner = run
|
|
|
50781
50816
|
const { config: config3 } = loadPluginConfigWithMeta2(directory);
|
|
50782
50817
|
const curatorConfig = CuratorConfigSchema.parse(config3.curator ?? {});
|
|
50783
50818
|
if (curatorConfig.enabled && curatorConfig.init_enabled) {
|
|
50784
|
-
await curatorRunner(directory, curatorConfig);
|
|
50819
|
+
const initResult = await curatorRunner(directory, curatorConfig);
|
|
50820
|
+
if (initResult.briefing) {
|
|
50821
|
+
const briefingPath = path31.join(directory, ".swarm", "curator-briefing.md");
|
|
50822
|
+
const fs18 = await import("fs");
|
|
50823
|
+
fs18.mkdirSync(path31.dirname(briefingPath), { recursive: true });
|
|
50824
|
+
fs18.writeFileSync(briefingPath, initResult.briefing, "utf-8");
|
|
50825
|
+
}
|
|
50785
50826
|
}
|
|
50786
50827
|
} catch {}
|
|
50787
50828
|
return;
|
|
@@ -50897,7 +50938,7 @@ import * as fs19 from "fs";
|
|
|
50897
50938
|
init_utils2();
|
|
50898
50939
|
init_manager2();
|
|
50899
50940
|
import * as fs18 from "fs";
|
|
50900
|
-
import * as
|
|
50941
|
+
import * as path32 from "path";
|
|
50901
50942
|
var DEFAULT_DRIFT_CONFIG = {
|
|
50902
50943
|
staleThresholdPhases: 1,
|
|
50903
50944
|
detectContradictions: true,
|
|
@@ -51051,7 +51092,7 @@ async function analyzeDecisionDrift(directory, config3 = {}) {
|
|
|
51051
51092
|
currentPhase = legacyPhase;
|
|
51052
51093
|
}
|
|
51053
51094
|
}
|
|
51054
|
-
const contextPath =
|
|
51095
|
+
const contextPath = path32.join(directory, ".swarm", "context.md");
|
|
51055
51096
|
let contextContent = "";
|
|
51056
51097
|
try {
|
|
51057
51098
|
if (fs18.existsSync(contextPath)) {
|
|
@@ -52516,7 +52557,7 @@ function createDarkMatterDetectorHook(directory) {
|
|
|
52516
52557
|
|
|
52517
52558
|
// src/hooks/incremental-verify.ts
|
|
52518
52559
|
import * as fs20 from "fs";
|
|
52519
|
-
import * as
|
|
52560
|
+
import * as path33 from "path";
|
|
52520
52561
|
|
|
52521
52562
|
// src/hooks/spawn-helper.ts
|
|
52522
52563
|
import { spawn } from "child_process";
|
|
@@ -52572,7 +52613,7 @@ function spawnAsync(command, cwd, timeoutMs) {
|
|
|
52572
52613
|
// src/hooks/incremental-verify.ts
|
|
52573
52614
|
var emittedSkipAdvisories = new Set;
|
|
52574
52615
|
function detectTypecheckCommand(projectDir) {
|
|
52575
|
-
const pkgPath =
|
|
52616
|
+
const pkgPath = path33.join(projectDir, "package.json");
|
|
52576
52617
|
if (fs20.existsSync(pkgPath)) {
|
|
52577
52618
|
try {
|
|
52578
52619
|
const pkg = JSON.parse(fs20.readFileSync(pkgPath, "utf8"));
|
|
@@ -52588,8 +52629,8 @@ function detectTypecheckCommand(projectDir) {
|
|
|
52588
52629
|
...pkg.dependencies,
|
|
52589
52630
|
...pkg.devDependencies
|
|
52590
52631
|
};
|
|
52591
|
-
if (!deps?.typescript && !fs20.existsSync(
|
|
52592
|
-
const hasTSMarkers = deps?.typescript || fs20.existsSync(
|
|
52632
|
+
if (!deps?.typescript && !fs20.existsSync(path33.join(projectDir, "tsconfig.json"))) {}
|
|
52633
|
+
const hasTSMarkers = deps?.typescript || fs20.existsSync(path33.join(projectDir, "tsconfig.json"));
|
|
52593
52634
|
if (hasTSMarkers) {
|
|
52594
52635
|
return { command: ["npx", "tsc", "--noEmit"], language: "typescript" };
|
|
52595
52636
|
}
|
|
@@ -52597,13 +52638,13 @@ function detectTypecheckCommand(projectDir) {
|
|
|
52597
52638
|
return null;
|
|
52598
52639
|
}
|
|
52599
52640
|
}
|
|
52600
|
-
if (fs20.existsSync(
|
|
52641
|
+
if (fs20.existsSync(path33.join(projectDir, "go.mod"))) {
|
|
52601
52642
|
return { command: ["go", "vet", "./..."], language: "go" };
|
|
52602
52643
|
}
|
|
52603
|
-
if (fs20.existsSync(
|
|
52644
|
+
if (fs20.existsSync(path33.join(projectDir, "Cargo.toml"))) {
|
|
52604
52645
|
return { command: ["cargo", "check"], language: "rust" };
|
|
52605
52646
|
}
|
|
52606
|
-
if (fs20.existsSync(
|
|
52647
|
+
if (fs20.existsSync(path33.join(projectDir, "pyproject.toml")) || fs20.existsSync(path33.join(projectDir, "requirements.txt")) || fs20.existsSync(path33.join(projectDir, "setup.py"))) {
|
|
52607
52648
|
return { command: null, language: "python" };
|
|
52608
52649
|
}
|
|
52609
52650
|
try {
|
|
@@ -52674,7 +52715,7 @@ ${errorSummary}`);
|
|
|
52674
52715
|
// src/hooks/knowledge-reader.ts
|
|
52675
52716
|
import { existsSync as existsSync19 } from "fs";
|
|
52676
52717
|
import { mkdir as mkdir4, readFile as readFile5, writeFile as writeFile4 } from "fs/promises";
|
|
52677
|
-
import * as
|
|
52718
|
+
import * as path34 from "path";
|
|
52678
52719
|
var JACCARD_THRESHOLD = 0.6;
|
|
52679
52720
|
var HIVE_TIER_BOOST = 0.05;
|
|
52680
52721
|
var SAME_PROJECT_PENALTY = -0.05;
|
|
@@ -52722,7 +52763,7 @@ function inferCategoriesFromPhase(phaseDescription) {
|
|
|
52722
52763
|
return ["process", "tooling"];
|
|
52723
52764
|
}
|
|
52724
52765
|
async function recordLessonsShown(directory, lessonIds, currentPhase) {
|
|
52725
|
-
const shownFile =
|
|
52766
|
+
const shownFile = path34.join(directory, ".swarm", ".knowledge-shown.json");
|
|
52726
52767
|
try {
|
|
52727
52768
|
let shownData = {};
|
|
52728
52769
|
if (existsSync19(shownFile)) {
|
|
@@ -52730,7 +52771,7 @@ async function recordLessonsShown(directory, lessonIds, currentPhase) {
|
|
|
52730
52771
|
shownData = JSON.parse(content);
|
|
52731
52772
|
}
|
|
52732
52773
|
shownData[currentPhase] = lessonIds;
|
|
52733
|
-
await mkdir4(
|
|
52774
|
+
await mkdir4(path34.dirname(shownFile), { recursive: true });
|
|
52734
52775
|
await writeFile4(shownFile, JSON.stringify(shownData, null, 2), "utf-8");
|
|
52735
52776
|
} catch {
|
|
52736
52777
|
console.warn("[swarm] Knowledge: failed to record shown lessons");
|
|
@@ -52825,7 +52866,7 @@ async function readMergedKnowledge(directory, config3, context) {
|
|
|
52825
52866
|
return topN;
|
|
52826
52867
|
}
|
|
52827
52868
|
async function updateRetrievalOutcome(directory, phaseInfo, phaseSucceeded) {
|
|
52828
|
-
const shownFile =
|
|
52869
|
+
const shownFile = path34.join(directory, ".swarm", ".knowledge-shown.json");
|
|
52829
52870
|
try {
|
|
52830
52871
|
if (!existsSync19(shownFile)) {
|
|
52831
52872
|
return;
|
|
@@ -53298,10 +53339,10 @@ Use this data to avoid repeating known failure patterns.`;
|
|
|
53298
53339
|
init_event_bus();
|
|
53299
53340
|
init_utils2();
|
|
53300
53341
|
import * as fs21 from "fs";
|
|
53301
|
-
import * as
|
|
53342
|
+
import * as path35 from "path";
|
|
53302
53343
|
var DRIFT_REPORT_PREFIX = "drift-report-phase-";
|
|
53303
53344
|
async function readPriorDriftReports(directory) {
|
|
53304
|
-
const swarmDir =
|
|
53345
|
+
const swarmDir = path35.join(directory, ".swarm");
|
|
53305
53346
|
const entries = await fs21.promises.readdir(swarmDir).catch(() => null);
|
|
53306
53347
|
if (entries === null)
|
|
53307
53348
|
return [];
|
|
@@ -53328,7 +53369,7 @@ async function readPriorDriftReports(directory) {
|
|
|
53328
53369
|
async function writeDriftReport(directory, report) {
|
|
53329
53370
|
const filename = `${DRIFT_REPORT_PREFIX}${report.phase}.json`;
|
|
53330
53371
|
const filePath = validateSwarmPath(directory, filename);
|
|
53331
|
-
const swarmDir =
|
|
53372
|
+
const swarmDir = path35.dirname(filePath);
|
|
53332
53373
|
await fs21.promises.mkdir(swarmDir, { recursive: true });
|
|
53333
53374
|
try {
|
|
53334
53375
|
await fs21.promises.writeFile(filePath, JSON.stringify(report, null, 2), "utf-8");
|
|
@@ -53482,7 +53523,7 @@ function isOrchestratorAgent(agentName) {
|
|
|
53482
53523
|
function injectKnowledgeMessage(output, text) {
|
|
53483
53524
|
if (!output.messages)
|
|
53484
53525
|
return;
|
|
53485
|
-
const alreadyInjected = output.messages.some((m) => m.parts?.some((p) => p.text?.includes("\uD83D\uDCDA Knowledge")));
|
|
53526
|
+
const alreadyInjected = output.messages.some((m) => m.parts?.some((p) => p.text?.includes("\uD83D\uDCDA Knowledge") || p.text?.includes("<drift_report>") || p.text?.includes("<curator_briefing>")));
|
|
53486
53527
|
if (alreadyInjected)
|
|
53487
53528
|
return;
|
|
53488
53529
|
const systemIdx = output.messages.findIndex((m) => m.info?.role === "system");
|
|
@@ -53528,8 +53569,33 @@ function createKnowledgeInjectorHook(directory, config3) {
|
|
|
53528
53569
|
currentPhase: phaseDescription
|
|
53529
53570
|
};
|
|
53530
53571
|
const entries = await readMergedKnowledge(directory, config3, context);
|
|
53531
|
-
|
|
53572
|
+
try {
|
|
53573
|
+
const driftReports = await readPriorDriftReports(directory);
|
|
53574
|
+
if (driftReports.length > 0) {
|
|
53575
|
+
const latestReport = driftReports[driftReports.length - 1];
|
|
53576
|
+
const driftText = buildDriftInjectionText(latestReport, 500);
|
|
53577
|
+
if (driftText) {
|
|
53578
|
+
cachedInjectionText = cachedInjectionText ? `${driftText}
|
|
53579
|
+
|
|
53580
|
+
${cachedInjectionText}` : driftText;
|
|
53581
|
+
}
|
|
53582
|
+
}
|
|
53583
|
+
} catch {}
|
|
53584
|
+
try {
|
|
53585
|
+
const briefingContent = await readSwarmFileAsync(directory, "curator-briefing.md");
|
|
53586
|
+
if (briefingContent) {
|
|
53587
|
+
const truncatedBriefing = briefingContent.slice(0, 500);
|
|
53588
|
+
cachedInjectionText = cachedInjectionText ? `<curator_briefing>${truncatedBriefing}</curator_briefing>
|
|
53589
|
+
|
|
53590
|
+
${cachedInjectionText}` : `<curator_briefing>${truncatedBriefing}</curator_briefing>`;
|
|
53591
|
+
}
|
|
53592
|
+
} catch {}
|
|
53593
|
+
if (entries.length === 0) {
|
|
53594
|
+
if (cachedInjectionText === null)
|
|
53595
|
+
return;
|
|
53596
|
+
injectKnowledgeMessage(output, cachedInjectionText);
|
|
53532
53597
|
return;
|
|
53598
|
+
}
|
|
53533
53599
|
const runMemory = await getRunMemorySummary(directory);
|
|
53534
53600
|
const lines = entries.map((entry) => {
|
|
53535
53601
|
const stars = formatStars(entry.confidence);
|
|
@@ -53548,13 +53614,15 @@ function createKnowledgeInjectorHook(directory, config3) {
|
|
|
53548
53614
|
"These are lessons learned from this project and past projects. Consider them as context but use your judgment \u2014 they may not all apply."
|
|
53549
53615
|
].join(`
|
|
53550
53616
|
`);
|
|
53617
|
+
let injectionText = cachedInjectionText ? `${cachedInjectionText}
|
|
53618
|
+
|
|
53619
|
+
${knowledgeSection}` : knowledgeSection;
|
|
53551
53620
|
if (runMemory) {
|
|
53552
|
-
|
|
53621
|
+
injectionText = `${runMemory}
|
|
53553
53622
|
|
|
53554
|
-
${
|
|
53555
|
-
} else {
|
|
53556
|
-
cachedInjectionText = knowledgeSection;
|
|
53623
|
+
${injectionText}`;
|
|
53557
53624
|
}
|
|
53625
|
+
cachedInjectionText = injectionText;
|
|
53558
53626
|
const rejected = await readRejectedLessons(directory);
|
|
53559
53627
|
if (rejected.length > 0) {
|
|
53560
53628
|
const recentRejected = rejected.slice(-3);
|
|
@@ -53565,25 +53633,13 @@ ${knowledgeSection}`;
|
|
|
53565
53633
|
` + rejectedLines.join(`
|
|
53566
53634
|
`);
|
|
53567
53635
|
}
|
|
53568
|
-
try {
|
|
53569
|
-
const driftReports = await readPriorDriftReports(directory);
|
|
53570
|
-
if (driftReports.length > 0 && cachedInjectionText !== null) {
|
|
53571
|
-
const latestReport = driftReports[driftReports.length - 1];
|
|
53572
|
-
const driftText = buildDriftInjectionText(latestReport, 500);
|
|
53573
|
-
if (driftText) {
|
|
53574
|
-
cachedInjectionText = `${driftText}
|
|
53575
|
-
|
|
53576
|
-
${cachedInjectionText}`;
|
|
53577
|
-
}
|
|
53578
|
-
}
|
|
53579
|
-
} catch {}
|
|
53580
53636
|
injectKnowledgeMessage(output, cachedInjectionText);
|
|
53581
53637
|
});
|
|
53582
53638
|
}
|
|
53583
53639
|
|
|
53584
53640
|
// src/hooks/slop-detector.ts
|
|
53585
53641
|
import * as fs22 from "fs";
|
|
53586
|
-
import * as
|
|
53642
|
+
import * as path36 from "path";
|
|
53587
53643
|
var WRITE_EDIT_TOOLS = new Set([
|
|
53588
53644
|
"write",
|
|
53589
53645
|
"edit",
|
|
@@ -53633,7 +53689,7 @@ function walkFiles(dir, exts, deadline) {
|
|
|
53633
53689
|
break;
|
|
53634
53690
|
if (entry.isSymbolicLink())
|
|
53635
53691
|
continue;
|
|
53636
|
-
const full =
|
|
53692
|
+
const full = path36.join(dir, entry.name);
|
|
53637
53693
|
if (entry.isDirectory()) {
|
|
53638
53694
|
if (entry.name === "node_modules" || entry.name === ".git")
|
|
53639
53695
|
continue;
|
|
@@ -53648,7 +53704,7 @@ function walkFiles(dir, exts, deadline) {
|
|
|
53648
53704
|
return results;
|
|
53649
53705
|
}
|
|
53650
53706
|
function checkDeadExports(content, projectDir, startTime) {
|
|
53651
|
-
const hasPackageJson = fs22.existsSync(
|
|
53707
|
+
const hasPackageJson = fs22.existsSync(path36.join(projectDir, "package.json"));
|
|
53652
53708
|
if (!hasPackageJson)
|
|
53653
53709
|
return null;
|
|
53654
53710
|
const exportMatches = content.matchAll(/^\+(?:export)\s+(?:function|class|const|type|interface)\s+(\w{3,})/gm);
|
|
@@ -53798,7 +53854,7 @@ init_config_doctor();
|
|
|
53798
53854
|
|
|
53799
53855
|
// src/session/snapshot-reader.ts
|
|
53800
53856
|
init_utils2();
|
|
53801
|
-
import
|
|
53857
|
+
import path37 from "path";
|
|
53802
53858
|
var VALID_TASK_WORKFLOW_STATES = [
|
|
53803
53859
|
"idle",
|
|
53804
53860
|
"coder_delegated",
|
|
@@ -53923,7 +53979,7 @@ function rehydrateState(snapshot) {
|
|
|
53923
53979
|
async function reconcileTaskStatesFromPlan(directory) {
|
|
53924
53980
|
let raw;
|
|
53925
53981
|
try {
|
|
53926
|
-
raw = await Bun.file(
|
|
53982
|
+
raw = await Bun.file(path37.join(directory, ".swarm/plan.json")).text();
|
|
53927
53983
|
} catch {
|
|
53928
53984
|
return;
|
|
53929
53985
|
}
|
|
@@ -54146,7 +54202,7 @@ var build_check = createSwarmTool({
|
|
|
54146
54202
|
init_dist();
|
|
54147
54203
|
init_create_tool();
|
|
54148
54204
|
import * as fs24 from "fs";
|
|
54149
|
-
import * as
|
|
54205
|
+
import * as path38 from "path";
|
|
54150
54206
|
var EVIDENCE_DIR = ".swarm/evidence";
|
|
54151
54207
|
var TASK_ID_PATTERN2 = /^\d+\.\d+(\.\d+)*$/;
|
|
54152
54208
|
function isValidTaskId3(taskId) {
|
|
@@ -54163,9 +54219,9 @@ function isValidTaskId3(taskId) {
|
|
|
54163
54219
|
return TASK_ID_PATTERN2.test(taskId);
|
|
54164
54220
|
}
|
|
54165
54221
|
function isPathWithinSwarm(filePath, workspaceRoot) {
|
|
54166
|
-
const normalizedWorkspace =
|
|
54167
|
-
const swarmPath =
|
|
54168
|
-
const normalizedPath =
|
|
54222
|
+
const normalizedWorkspace = path38.resolve(workspaceRoot);
|
|
54223
|
+
const swarmPath = path38.join(normalizedWorkspace, ".swarm", "evidence");
|
|
54224
|
+
const normalizedPath = path38.resolve(filePath);
|
|
54169
54225
|
return normalizedPath.startsWith(swarmPath);
|
|
54170
54226
|
}
|
|
54171
54227
|
function readEvidenceFile(evidencePath) {
|
|
@@ -54226,7 +54282,7 @@ var check_gate_status = createSwarmTool({
|
|
|
54226
54282
|
};
|
|
54227
54283
|
return JSON.stringify(errorResult, null, 2);
|
|
54228
54284
|
}
|
|
54229
|
-
const evidencePath =
|
|
54285
|
+
const evidencePath = path38.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
|
|
54230
54286
|
if (!isPathWithinSwarm(evidencePath, directory)) {
|
|
54231
54287
|
const errorResult = {
|
|
54232
54288
|
taskId: taskIdInput,
|
|
@@ -54287,7 +54343,7 @@ init_tool();
|
|
|
54287
54343
|
init_create_tool();
|
|
54288
54344
|
import { spawnSync } from "child_process";
|
|
54289
54345
|
import * as fs25 from "fs";
|
|
54290
|
-
import * as
|
|
54346
|
+
import * as path39 from "path";
|
|
54291
54347
|
var CHECKPOINT_LOG_PATH = ".swarm/checkpoints.json";
|
|
54292
54348
|
var MAX_LABEL_LENGTH = 100;
|
|
54293
54349
|
var GIT_TIMEOUT_MS = 30000;
|
|
@@ -54338,7 +54394,7 @@ function validateLabel(label) {
|
|
|
54338
54394
|
return null;
|
|
54339
54395
|
}
|
|
54340
54396
|
function getCheckpointLogPath(directory) {
|
|
54341
|
-
return
|
|
54397
|
+
return path39.join(directory, CHECKPOINT_LOG_PATH);
|
|
54342
54398
|
}
|
|
54343
54399
|
function readCheckpointLog(directory) {
|
|
54344
54400
|
const logPath = getCheckpointLogPath(directory);
|
|
@@ -54356,7 +54412,7 @@ function readCheckpointLog(directory) {
|
|
|
54356
54412
|
}
|
|
54357
54413
|
function writeCheckpointLog(log2, directory) {
|
|
54358
54414
|
const logPath = getCheckpointLogPath(directory);
|
|
54359
|
-
const dir =
|
|
54415
|
+
const dir = path39.dirname(logPath);
|
|
54360
54416
|
if (!fs25.existsSync(dir)) {
|
|
54361
54417
|
fs25.mkdirSync(dir, { recursive: true });
|
|
54362
54418
|
}
|
|
@@ -54564,7 +54620,7 @@ var checkpoint = createSwarmTool({
|
|
|
54564
54620
|
init_dist();
|
|
54565
54621
|
init_create_tool();
|
|
54566
54622
|
import * as fs26 from "fs";
|
|
54567
|
-
import * as
|
|
54623
|
+
import * as path40 from "path";
|
|
54568
54624
|
var MAX_FILE_SIZE_BYTES2 = 256 * 1024;
|
|
54569
54625
|
var DEFAULT_DAYS = 90;
|
|
54570
54626
|
var DEFAULT_TOP_N = 20;
|
|
@@ -54708,7 +54764,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
54708
54764
|
const extSet = new Set(extensions.map((e) => e.startsWith(".") ? e : `.${e}`));
|
|
54709
54765
|
const filteredChurn = new Map;
|
|
54710
54766
|
for (const [file3, count] of churnMap) {
|
|
54711
|
-
const ext =
|
|
54767
|
+
const ext = path40.extname(file3).toLowerCase();
|
|
54712
54768
|
if (extSet.has(ext)) {
|
|
54713
54769
|
filteredChurn.set(file3, count);
|
|
54714
54770
|
}
|
|
@@ -54719,7 +54775,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
54719
54775
|
for (const [file3, churnCount] of filteredChurn) {
|
|
54720
54776
|
let fullPath = file3;
|
|
54721
54777
|
if (!fs26.existsSync(fullPath)) {
|
|
54722
|
-
fullPath =
|
|
54778
|
+
fullPath = path40.join(cwd, file3);
|
|
54723
54779
|
}
|
|
54724
54780
|
const complexity = getComplexityForFile(fullPath);
|
|
54725
54781
|
if (complexity !== null) {
|
|
@@ -54867,7 +54923,7 @@ var complexity_hotspots = createSwarmTool({
|
|
|
54867
54923
|
// src/tools/declare-scope.ts
|
|
54868
54924
|
init_tool();
|
|
54869
54925
|
import * as fs27 from "fs";
|
|
54870
|
-
import * as
|
|
54926
|
+
import * as path41 from "path";
|
|
54871
54927
|
init_create_tool();
|
|
54872
54928
|
function validateTaskIdFormat(taskId) {
|
|
54873
54929
|
const taskIdPattern = /^\d+\.\d+(\.\d+)*$/;
|
|
@@ -54946,8 +55002,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
54946
55002
|
};
|
|
54947
55003
|
}
|
|
54948
55004
|
}
|
|
54949
|
-
normalizedDir =
|
|
54950
|
-
const pathParts = normalizedDir.split(
|
|
55005
|
+
normalizedDir = path41.normalize(args2.working_directory);
|
|
55006
|
+
const pathParts = normalizedDir.split(path41.sep);
|
|
54951
55007
|
if (pathParts.includes("..")) {
|
|
54952
55008
|
return {
|
|
54953
55009
|
success: false,
|
|
@@ -54957,10 +55013,10 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
54957
55013
|
]
|
|
54958
55014
|
};
|
|
54959
55015
|
}
|
|
54960
|
-
const resolvedDir =
|
|
55016
|
+
const resolvedDir = path41.resolve(normalizedDir);
|
|
54961
55017
|
try {
|
|
54962
55018
|
const realPath = fs27.realpathSync(resolvedDir);
|
|
54963
|
-
const planPath2 =
|
|
55019
|
+
const planPath2 = path41.join(realPath, ".swarm", "plan.json");
|
|
54964
55020
|
if (!fs27.existsSync(planPath2)) {
|
|
54965
55021
|
return {
|
|
54966
55022
|
success: false,
|
|
@@ -54981,7 +55037,7 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
54981
55037
|
}
|
|
54982
55038
|
}
|
|
54983
55039
|
const directory = normalizedDir ?? fallbackDir ?? process.cwd();
|
|
54984
|
-
const planPath =
|
|
55040
|
+
const planPath = path41.resolve(directory, ".swarm", "plan.json");
|
|
54985
55041
|
if (!fs27.existsSync(planPath)) {
|
|
54986
55042
|
return {
|
|
54987
55043
|
success: false,
|
|
@@ -55071,20 +55127,20 @@ function validateBase(base) {
|
|
|
55071
55127
|
function validatePaths(paths) {
|
|
55072
55128
|
if (!paths)
|
|
55073
55129
|
return null;
|
|
55074
|
-
for (const
|
|
55075
|
-
if (!
|
|
55130
|
+
for (const path42 of paths) {
|
|
55131
|
+
if (!path42 || path42.length === 0) {
|
|
55076
55132
|
return "empty path not allowed";
|
|
55077
55133
|
}
|
|
55078
|
-
if (
|
|
55134
|
+
if (path42.length > MAX_PATH_LENGTH) {
|
|
55079
55135
|
return `path exceeds maximum length of ${MAX_PATH_LENGTH}`;
|
|
55080
55136
|
}
|
|
55081
|
-
if (SHELL_METACHARACTERS2.test(
|
|
55137
|
+
if (SHELL_METACHARACTERS2.test(path42)) {
|
|
55082
55138
|
return "path contains shell metacharacters";
|
|
55083
55139
|
}
|
|
55084
|
-
if (
|
|
55140
|
+
if (path42.startsWith("-")) {
|
|
55085
55141
|
return 'path cannot start with "-" (option-like arguments not allowed)';
|
|
55086
55142
|
}
|
|
55087
|
-
if (CONTROL_CHAR_PATTERN2.test(
|
|
55143
|
+
if (CONTROL_CHAR_PATTERN2.test(path42)) {
|
|
55088
55144
|
return "path contains control characters";
|
|
55089
55145
|
}
|
|
55090
55146
|
}
|
|
@@ -55164,8 +55220,8 @@ var diff = tool({
|
|
|
55164
55220
|
if (parts2.length >= 3) {
|
|
55165
55221
|
const additions = parseInt(parts2[0], 10) || 0;
|
|
55166
55222
|
const deletions = parseInt(parts2[1], 10) || 0;
|
|
55167
|
-
const
|
|
55168
|
-
files.push({ path:
|
|
55223
|
+
const path42 = parts2[2];
|
|
55224
|
+
files.push({ path: path42, additions, deletions });
|
|
55169
55225
|
}
|
|
55170
55226
|
}
|
|
55171
55227
|
const contractChanges = [];
|
|
@@ -55395,7 +55451,7 @@ Use these as DOMAIN values when delegating to @sme.`;
|
|
|
55395
55451
|
init_dist();
|
|
55396
55452
|
init_create_tool();
|
|
55397
55453
|
import * as fs28 from "fs";
|
|
55398
|
-
import * as
|
|
55454
|
+
import * as path42 from "path";
|
|
55399
55455
|
var MAX_FILE_SIZE_BYTES3 = 1024 * 1024;
|
|
55400
55456
|
var MAX_EVIDENCE_FILES = 1000;
|
|
55401
55457
|
var EVIDENCE_DIR2 = ".swarm/evidence";
|
|
@@ -55425,9 +55481,9 @@ function validateRequiredTypes(input) {
|
|
|
55425
55481
|
return null;
|
|
55426
55482
|
}
|
|
55427
55483
|
function isPathWithinSwarm2(filePath, cwd) {
|
|
55428
|
-
const normalizedCwd =
|
|
55429
|
-
const swarmPath =
|
|
55430
|
-
const normalizedPath =
|
|
55484
|
+
const normalizedCwd = path42.resolve(cwd);
|
|
55485
|
+
const swarmPath = path42.join(normalizedCwd, ".swarm");
|
|
55486
|
+
const normalizedPath = path42.resolve(filePath);
|
|
55431
55487
|
return normalizedPath.startsWith(swarmPath);
|
|
55432
55488
|
}
|
|
55433
55489
|
function parseCompletedTasks(planContent) {
|
|
@@ -55457,10 +55513,10 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
55457
55513
|
if (!VALID_EVIDENCE_FILENAME_REGEX.test(filename)) {
|
|
55458
55514
|
continue;
|
|
55459
55515
|
}
|
|
55460
|
-
const filePath =
|
|
55516
|
+
const filePath = path42.join(evidenceDir, filename);
|
|
55461
55517
|
try {
|
|
55462
|
-
const resolvedPath =
|
|
55463
|
-
const evidenceDirResolved =
|
|
55518
|
+
const resolvedPath = path42.resolve(filePath);
|
|
55519
|
+
const evidenceDirResolved = path42.resolve(evidenceDir);
|
|
55464
55520
|
if (!resolvedPath.startsWith(evidenceDirResolved)) {
|
|
55465
55521
|
continue;
|
|
55466
55522
|
}
|
|
@@ -55578,7 +55634,7 @@ var evidence_check = createSwarmTool({
|
|
|
55578
55634
|
return JSON.stringify(errorResult, null, 2);
|
|
55579
55635
|
}
|
|
55580
55636
|
const requiredTypes = requiredTypesValue.split(",").map((t) => t.trim()).filter((t) => t.length > 0).map(normalizeEvidenceType);
|
|
55581
|
-
const planPath =
|
|
55637
|
+
const planPath = path42.join(cwd, PLAN_FILE);
|
|
55582
55638
|
if (!isPathWithinSwarm2(planPath, cwd)) {
|
|
55583
55639
|
const errorResult = {
|
|
55584
55640
|
error: "plan file path validation failed",
|
|
@@ -55610,7 +55666,7 @@ var evidence_check = createSwarmTool({
|
|
|
55610
55666
|
};
|
|
55611
55667
|
return JSON.stringify(result2, null, 2);
|
|
55612
55668
|
}
|
|
55613
|
-
const evidenceDir =
|
|
55669
|
+
const evidenceDir = path42.join(cwd, EVIDENCE_DIR2);
|
|
55614
55670
|
const evidence = readEvidenceFiles(evidenceDir, cwd);
|
|
55615
55671
|
const { tasksWithFullEvidence, gaps } = analyzeGaps(completedTasks, evidence, requiredTypes);
|
|
55616
55672
|
const completeness = completedTasks.length > 0 ? Math.round(tasksWithFullEvidence.length / completedTasks.length * 100) / 100 : 1;
|
|
@@ -55628,7 +55684,7 @@ var evidence_check = createSwarmTool({
|
|
|
55628
55684
|
init_tool();
|
|
55629
55685
|
init_create_tool();
|
|
55630
55686
|
import * as fs29 from "fs";
|
|
55631
|
-
import * as
|
|
55687
|
+
import * as path43 from "path";
|
|
55632
55688
|
var EXT_MAP = {
|
|
55633
55689
|
python: ".py",
|
|
55634
55690
|
py: ".py",
|
|
@@ -55709,12 +55765,12 @@ var extract_code_blocks = createSwarmTool({
|
|
|
55709
55765
|
if (prefix) {
|
|
55710
55766
|
filename = `${prefix}_${filename}`;
|
|
55711
55767
|
}
|
|
55712
|
-
let filepath =
|
|
55713
|
-
const base =
|
|
55714
|
-
const ext =
|
|
55768
|
+
let filepath = path43.join(targetDir, filename);
|
|
55769
|
+
const base = path43.basename(filepath, path43.extname(filepath));
|
|
55770
|
+
const ext = path43.extname(filepath);
|
|
55715
55771
|
let counter = 1;
|
|
55716
55772
|
while (fs29.existsSync(filepath)) {
|
|
55717
|
-
filepath =
|
|
55773
|
+
filepath = path43.join(targetDir, `${base}_${counter}${ext}`);
|
|
55718
55774
|
counter++;
|
|
55719
55775
|
}
|
|
55720
55776
|
try {
|
|
@@ -55832,7 +55888,7 @@ var gitingest = tool({
|
|
|
55832
55888
|
// src/tools/imports.ts
|
|
55833
55889
|
init_dist();
|
|
55834
55890
|
import * as fs30 from "fs";
|
|
55835
|
-
import * as
|
|
55891
|
+
import * as path44 from "path";
|
|
55836
55892
|
var MAX_FILE_PATH_LENGTH2 = 500;
|
|
55837
55893
|
var MAX_SYMBOL_LENGTH = 256;
|
|
55838
55894
|
var MAX_FILE_SIZE_BYTES4 = 1024 * 1024;
|
|
@@ -55886,7 +55942,7 @@ function validateSymbolInput(symbol3) {
|
|
|
55886
55942
|
return null;
|
|
55887
55943
|
}
|
|
55888
55944
|
function isBinaryFile2(filePath, buffer) {
|
|
55889
|
-
const ext =
|
|
55945
|
+
const ext = path44.extname(filePath).toLowerCase();
|
|
55890
55946
|
if (ext === ".json" || ext === ".md" || ext === ".txt") {
|
|
55891
55947
|
return false;
|
|
55892
55948
|
}
|
|
@@ -55910,15 +55966,15 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
55910
55966
|
const imports = [];
|
|
55911
55967
|
let _resolvedTarget;
|
|
55912
55968
|
try {
|
|
55913
|
-
_resolvedTarget =
|
|
55969
|
+
_resolvedTarget = path44.resolve(targetFile);
|
|
55914
55970
|
} catch {
|
|
55915
55971
|
_resolvedTarget = targetFile;
|
|
55916
55972
|
}
|
|
55917
|
-
const targetBasename =
|
|
55973
|
+
const targetBasename = path44.basename(targetFile, path44.extname(targetFile));
|
|
55918
55974
|
const targetWithExt = targetFile;
|
|
55919
55975
|
const targetWithoutExt = targetFile.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
55920
|
-
const normalizedTargetWithExt =
|
|
55921
|
-
const normalizedTargetWithoutExt =
|
|
55976
|
+
const normalizedTargetWithExt = path44.normalize(targetWithExt).replace(/\\/g, "/");
|
|
55977
|
+
const normalizedTargetWithoutExt = path44.normalize(targetWithoutExt).replace(/\\/g, "/");
|
|
55922
55978
|
const importRegex = /import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
|
|
55923
55979
|
for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
|
|
55924
55980
|
const modulePath = match[1] || match[2] || match[3];
|
|
@@ -55941,9 +55997,9 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
55941
55997
|
}
|
|
55942
55998
|
const _normalizedModule = modulePath.replace(/^\.\//, "").replace(/^\.\.\\/, "../");
|
|
55943
55999
|
let isMatch = false;
|
|
55944
|
-
const _targetDir =
|
|
55945
|
-
const targetExt =
|
|
55946
|
-
const targetBasenameNoExt =
|
|
56000
|
+
const _targetDir = path44.dirname(targetFile);
|
|
56001
|
+
const targetExt = path44.extname(targetFile);
|
|
56002
|
+
const targetBasenameNoExt = path44.basename(targetFile, targetExt);
|
|
55947
56003
|
const moduleNormalized = modulePath.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
55948
56004
|
const moduleName = modulePath.split(/[/\\]/).pop() || "";
|
|
55949
56005
|
const moduleNameNoExt = moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
@@ -56011,10 +56067,10 @@ function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFile
|
|
|
56011
56067
|
entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
|
|
56012
56068
|
for (const entry of entries) {
|
|
56013
56069
|
if (SKIP_DIRECTORIES2.has(entry)) {
|
|
56014
|
-
stats.skippedDirs.push(
|
|
56070
|
+
stats.skippedDirs.push(path44.join(dir, entry));
|
|
56015
56071
|
continue;
|
|
56016
56072
|
}
|
|
56017
|
-
const fullPath =
|
|
56073
|
+
const fullPath = path44.join(dir, entry);
|
|
56018
56074
|
let stat2;
|
|
56019
56075
|
try {
|
|
56020
56076
|
stat2 = fs30.statSync(fullPath);
|
|
@@ -56028,7 +56084,7 @@ function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFile
|
|
|
56028
56084
|
if (stat2.isDirectory()) {
|
|
56029
56085
|
findSourceFiles(fullPath, files, stats);
|
|
56030
56086
|
} else if (stat2.isFile()) {
|
|
56031
|
-
const ext =
|
|
56087
|
+
const ext = path44.extname(fullPath).toLowerCase();
|
|
56032
56088
|
if (SUPPORTED_EXTENSIONS.includes(ext)) {
|
|
56033
56089
|
files.push(fullPath);
|
|
56034
56090
|
}
|
|
@@ -56084,7 +56140,7 @@ var imports = tool({
|
|
|
56084
56140
|
return JSON.stringify(errorResult, null, 2);
|
|
56085
56141
|
}
|
|
56086
56142
|
try {
|
|
56087
|
-
const targetFile =
|
|
56143
|
+
const targetFile = path44.resolve(file3);
|
|
56088
56144
|
if (!fs30.existsSync(targetFile)) {
|
|
56089
56145
|
const errorResult = {
|
|
56090
56146
|
error: `target file not found: ${file3}`,
|
|
@@ -56106,7 +56162,7 @@ var imports = tool({
|
|
|
56106
56162
|
};
|
|
56107
56163
|
return JSON.stringify(errorResult, null, 2);
|
|
56108
56164
|
}
|
|
56109
|
-
const baseDir =
|
|
56165
|
+
const baseDir = path44.dirname(targetFile);
|
|
56110
56166
|
const scanStats = {
|
|
56111
56167
|
skippedDirs: [],
|
|
56112
56168
|
skippedFiles: 0,
|
|
@@ -56428,7 +56484,7 @@ init_config();
|
|
|
56428
56484
|
init_schema();
|
|
56429
56485
|
init_manager();
|
|
56430
56486
|
import * as fs31 from "fs";
|
|
56431
|
-
import * as
|
|
56487
|
+
import * as path45 from "path";
|
|
56432
56488
|
init_utils2();
|
|
56433
56489
|
init_create_tool();
|
|
56434
56490
|
function safeWarn(message, error93) {
|
|
@@ -56623,7 +56679,7 @@ async function executePhaseComplete(args2, workingDirectory) {
|
|
|
56623
56679
|
}
|
|
56624
56680
|
if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
|
|
56625
56681
|
try {
|
|
56626
|
-
const projectName =
|
|
56682
|
+
const projectName = path45.basename(dir);
|
|
56627
56683
|
const knowledgeConfig = {
|
|
56628
56684
|
enabled: true,
|
|
56629
56685
|
swarm_max_entries: 100,
|
|
@@ -56652,12 +56708,17 @@ async function executePhaseComplete(args2, workingDirectory) {
|
|
|
56652
56708
|
safeWarn("[phase_complete] Failed to curate lessons from retrospective:", error93);
|
|
56653
56709
|
}
|
|
56654
56710
|
}
|
|
56711
|
+
let complianceWarnings = [];
|
|
56655
56712
|
try {
|
|
56656
56713
|
const curatorConfig = CuratorConfigSchema.parse(config3.curator ?? {});
|
|
56657
56714
|
if (curatorConfig.enabled && curatorConfig.phase_enabled) {
|
|
56658
56715
|
const curatorResult = await runCuratorPhase(dir, phase, agentsDispatched, curatorConfig, {});
|
|
56659
56716
|
await applyCuratorKnowledgeUpdates(dir, curatorResult.knowledge_recommendations, {});
|
|
56660
56717
|
await runCriticDriftCheck(dir, phase, curatorResult, curatorConfig);
|
|
56718
|
+
if (curatorResult.compliance.length > 0 && !curatorConfig.suppress_warnings) {
|
|
56719
|
+
const complianceLines = curatorResult.compliance.map((obs) => `[${obs.severity.toUpperCase()}] ${obs.description}`).slice(0, 5);
|
|
56720
|
+
complianceWarnings = complianceLines;
|
|
56721
|
+
}
|
|
56661
56722
|
}
|
|
56662
56723
|
} catch (curatorError) {
|
|
56663
56724
|
safeWarn("[phase_complete] Curator pipeline error (non-blocking):", curatorError);
|
|
@@ -56743,6 +56804,9 @@ async function executePhaseComplete(args2, workingDirectory) {
|
|
|
56743
56804
|
warnings.push(`Warning: failed to update plan.json phase status: ${error93 instanceof Error ? error93.message : String(error93)}`);
|
|
56744
56805
|
}
|
|
56745
56806
|
}
|
|
56807
|
+
if (complianceWarnings.length > 0) {
|
|
56808
|
+
warnings.push(`Curator compliance: ${complianceWarnings.join("; ")}`);
|
|
56809
|
+
}
|
|
56746
56810
|
const result = {
|
|
56747
56811
|
success: success3,
|
|
56748
56812
|
phase,
|
|
@@ -56787,7 +56851,7 @@ init_discovery();
|
|
|
56787
56851
|
init_utils();
|
|
56788
56852
|
init_create_tool();
|
|
56789
56853
|
import * as fs32 from "fs";
|
|
56790
|
-
import * as
|
|
56854
|
+
import * as path46 from "path";
|
|
56791
56855
|
var MAX_OUTPUT_BYTES5 = 52428800;
|
|
56792
56856
|
var AUDIT_TIMEOUT_MS = 120000;
|
|
56793
56857
|
function isValidEcosystem(value) {
|
|
@@ -56805,16 +56869,16 @@ function validateArgs3(args2) {
|
|
|
56805
56869
|
function detectEcosystems(directory) {
|
|
56806
56870
|
const ecosystems = [];
|
|
56807
56871
|
const cwd = directory;
|
|
56808
|
-
if (fs32.existsSync(
|
|
56872
|
+
if (fs32.existsSync(path46.join(cwd, "package.json"))) {
|
|
56809
56873
|
ecosystems.push("npm");
|
|
56810
56874
|
}
|
|
56811
|
-
if (fs32.existsSync(
|
|
56875
|
+
if (fs32.existsSync(path46.join(cwd, "pyproject.toml")) || fs32.existsSync(path46.join(cwd, "requirements.txt"))) {
|
|
56812
56876
|
ecosystems.push("pip");
|
|
56813
56877
|
}
|
|
56814
|
-
if (fs32.existsSync(
|
|
56878
|
+
if (fs32.existsSync(path46.join(cwd, "Cargo.toml"))) {
|
|
56815
56879
|
ecosystems.push("cargo");
|
|
56816
56880
|
}
|
|
56817
|
-
if (fs32.existsSync(
|
|
56881
|
+
if (fs32.existsSync(path46.join(cwd, "go.mod"))) {
|
|
56818
56882
|
ecosystems.push("go");
|
|
56819
56883
|
}
|
|
56820
56884
|
try {
|
|
@@ -56823,10 +56887,10 @@ function detectEcosystems(directory) {
|
|
|
56823
56887
|
ecosystems.push("dotnet");
|
|
56824
56888
|
}
|
|
56825
56889
|
} catch {}
|
|
56826
|
-
if (fs32.existsSync(
|
|
56890
|
+
if (fs32.existsSync(path46.join(cwd, "Gemfile")) || fs32.existsSync(path46.join(cwd, "Gemfile.lock"))) {
|
|
56827
56891
|
ecosystems.push("ruby");
|
|
56828
56892
|
}
|
|
56829
|
-
if (fs32.existsSync(
|
|
56893
|
+
if (fs32.existsSync(path46.join(cwd, "pubspec.yaml"))) {
|
|
56830
56894
|
ecosystems.push("dart");
|
|
56831
56895
|
}
|
|
56832
56896
|
return ecosystems;
|
|
@@ -57889,7 +57953,7 @@ var SUPPORTED_PARSER_EXTENSIONS = new Set([
|
|
|
57889
57953
|
// src/tools/pre-check-batch.ts
|
|
57890
57954
|
init_dist();
|
|
57891
57955
|
import * as fs35 from "fs";
|
|
57892
|
-
import * as
|
|
57956
|
+
import * as path49 from "path";
|
|
57893
57957
|
|
|
57894
57958
|
// node_modules/yocto-queue/index.js
|
|
57895
57959
|
class Node2 {
|
|
@@ -58057,7 +58121,7 @@ init_manager();
|
|
|
58057
58121
|
|
|
58058
58122
|
// src/quality/metrics.ts
|
|
58059
58123
|
import * as fs33 from "fs";
|
|
58060
|
-
import * as
|
|
58124
|
+
import * as path47 from "path";
|
|
58061
58125
|
var MAX_FILE_SIZE_BYTES5 = 256 * 1024;
|
|
58062
58126
|
var MIN_DUPLICATION_LINES = 10;
|
|
58063
58127
|
function estimateCyclomaticComplexity(content) {
|
|
@@ -58109,7 +58173,7 @@ async function computeComplexityDelta(files, workingDir) {
|
|
|
58109
58173
|
let totalComplexity = 0;
|
|
58110
58174
|
const analyzedFiles = [];
|
|
58111
58175
|
for (const file3 of files) {
|
|
58112
|
-
const fullPath =
|
|
58176
|
+
const fullPath = path47.isAbsolute(file3) ? file3 : path47.join(workingDir, file3);
|
|
58113
58177
|
if (!fs33.existsSync(fullPath)) {
|
|
58114
58178
|
continue;
|
|
58115
58179
|
}
|
|
@@ -58232,7 +58296,7 @@ function countGoExports(content) {
|
|
|
58232
58296
|
function getExportCountForFile(filePath) {
|
|
58233
58297
|
try {
|
|
58234
58298
|
const content = fs33.readFileSync(filePath, "utf-8");
|
|
58235
|
-
const ext =
|
|
58299
|
+
const ext = path47.extname(filePath).toLowerCase();
|
|
58236
58300
|
switch (ext) {
|
|
58237
58301
|
case ".ts":
|
|
58238
58302
|
case ".tsx":
|
|
@@ -58258,7 +58322,7 @@ async function computePublicApiDelta(files, workingDir) {
|
|
|
58258
58322
|
let totalExports = 0;
|
|
58259
58323
|
const analyzedFiles = [];
|
|
58260
58324
|
for (const file3 of files) {
|
|
58261
|
-
const fullPath =
|
|
58325
|
+
const fullPath = path47.isAbsolute(file3) ? file3 : path47.join(workingDir, file3);
|
|
58262
58326
|
if (!fs33.existsSync(fullPath)) {
|
|
58263
58327
|
continue;
|
|
58264
58328
|
}
|
|
@@ -58292,7 +58356,7 @@ async function computeDuplicationRatio(files, workingDir) {
|
|
|
58292
58356
|
let duplicateLines = 0;
|
|
58293
58357
|
const analyzedFiles = [];
|
|
58294
58358
|
for (const file3 of files) {
|
|
58295
|
-
const fullPath =
|
|
58359
|
+
const fullPath = path47.isAbsolute(file3) ? file3 : path47.join(workingDir, file3);
|
|
58296
58360
|
if (!fs33.existsSync(fullPath)) {
|
|
58297
58361
|
continue;
|
|
58298
58362
|
}
|
|
@@ -58325,8 +58389,8 @@ function countCodeLines(content) {
|
|
|
58325
58389
|
return lines.length;
|
|
58326
58390
|
}
|
|
58327
58391
|
function isTestFile(filePath) {
|
|
58328
|
-
const basename8 =
|
|
58329
|
-
const _ext =
|
|
58392
|
+
const basename8 = path47.basename(filePath);
|
|
58393
|
+
const _ext = path47.extname(filePath).toLowerCase();
|
|
58330
58394
|
const testPatterns = [
|
|
58331
58395
|
".test.",
|
|
58332
58396
|
".spec.",
|
|
@@ -58407,8 +58471,8 @@ function matchGlobSegment(globSegments, pathSegments) {
|
|
|
58407
58471
|
}
|
|
58408
58472
|
return gIndex === globSegments.length && pIndex === pathSegments.length;
|
|
58409
58473
|
}
|
|
58410
|
-
function matchesGlobSegment(
|
|
58411
|
-
const normalizedPath =
|
|
58474
|
+
function matchesGlobSegment(path48, glob) {
|
|
58475
|
+
const normalizedPath = path48.replace(/\\/g, "/");
|
|
58412
58476
|
const normalizedGlob = glob.replace(/\\/g, "/");
|
|
58413
58477
|
if (normalizedPath.includes("//")) {
|
|
58414
58478
|
return false;
|
|
@@ -58439,8 +58503,8 @@ function simpleGlobToRegex2(glob) {
|
|
|
58439
58503
|
function hasGlobstar(glob) {
|
|
58440
58504
|
return glob.includes("**");
|
|
58441
58505
|
}
|
|
58442
|
-
function globMatches(
|
|
58443
|
-
const normalizedPath =
|
|
58506
|
+
function globMatches(path48, glob) {
|
|
58507
|
+
const normalizedPath = path48.replace(/\\/g, "/");
|
|
58444
58508
|
if (!glob || glob === "") {
|
|
58445
58509
|
if (normalizedPath.includes("//")) {
|
|
58446
58510
|
return false;
|
|
@@ -58476,7 +58540,7 @@ function shouldExcludeFile(filePath, excludeGlobs) {
|
|
|
58476
58540
|
async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
58477
58541
|
let testLines = 0;
|
|
58478
58542
|
let codeLines = 0;
|
|
58479
|
-
const srcDir =
|
|
58543
|
+
const srcDir = path47.join(workingDir, "src");
|
|
58480
58544
|
if (fs33.existsSync(srcDir)) {
|
|
58481
58545
|
await scanDirectoryForLines(srcDir, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
58482
58546
|
codeLines += lines;
|
|
@@ -58484,14 +58548,14 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
58484
58548
|
}
|
|
58485
58549
|
const possibleSrcDirs = ["lib", "app", "source", "core"];
|
|
58486
58550
|
for (const dir of possibleSrcDirs) {
|
|
58487
|
-
const dirPath =
|
|
58551
|
+
const dirPath = path47.join(workingDir, dir);
|
|
58488
58552
|
if (fs33.existsSync(dirPath)) {
|
|
58489
58553
|
await scanDirectoryForLines(dirPath, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
58490
58554
|
codeLines += lines;
|
|
58491
58555
|
});
|
|
58492
58556
|
}
|
|
58493
58557
|
}
|
|
58494
|
-
const testsDir =
|
|
58558
|
+
const testsDir = path47.join(workingDir, "tests");
|
|
58495
58559
|
if (fs33.existsSync(testsDir)) {
|
|
58496
58560
|
await scanDirectoryForLines(testsDir, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
58497
58561
|
testLines += lines;
|
|
@@ -58499,7 +58563,7 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
58499
58563
|
}
|
|
58500
58564
|
const possibleTestDirs = ["test", "__tests__", "specs"];
|
|
58501
58565
|
for (const dir of possibleTestDirs) {
|
|
58502
|
-
const dirPath =
|
|
58566
|
+
const dirPath = path47.join(workingDir, dir);
|
|
58503
58567
|
if (fs33.existsSync(dirPath) && dirPath !== testsDir) {
|
|
58504
58568
|
await scanDirectoryForLines(dirPath, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
58505
58569
|
testLines += lines;
|
|
@@ -58514,7 +58578,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
58514
58578
|
try {
|
|
58515
58579
|
const entries = fs33.readdirSync(dirPath, { withFileTypes: true });
|
|
58516
58580
|
for (const entry of entries) {
|
|
58517
|
-
const fullPath =
|
|
58581
|
+
const fullPath = path47.join(dirPath, entry.name);
|
|
58518
58582
|
if (entry.isDirectory()) {
|
|
58519
58583
|
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === ".git") {
|
|
58520
58584
|
continue;
|
|
@@ -58522,7 +58586,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
58522
58586
|
await scanDirectoryForLines(fullPath, includeGlobs, excludeGlobs, isTestScan, callback);
|
|
58523
58587
|
} else if (entry.isFile()) {
|
|
58524
58588
|
const relativePath = fullPath.replace(`${process.cwd()}/`, "");
|
|
58525
|
-
const ext =
|
|
58589
|
+
const ext = path47.extname(entry.name).toLowerCase();
|
|
58526
58590
|
const validExts = [
|
|
58527
58591
|
".ts",
|
|
58528
58592
|
".tsx",
|
|
@@ -58773,7 +58837,7 @@ init_dist();
|
|
|
58773
58837
|
init_manager();
|
|
58774
58838
|
init_detector();
|
|
58775
58839
|
import * as fs34 from "fs";
|
|
58776
|
-
import * as
|
|
58840
|
+
import * as path48 from "path";
|
|
58777
58841
|
import { extname as extname9 } from "path";
|
|
58778
58842
|
|
|
58779
58843
|
// src/sast/rules/c.ts
|
|
@@ -59736,7 +59800,7 @@ async function sastScan(input, directory, config3) {
|
|
|
59736
59800
|
_filesSkipped++;
|
|
59737
59801
|
continue;
|
|
59738
59802
|
}
|
|
59739
|
-
const resolvedPath =
|
|
59803
|
+
const resolvedPath = path48.isAbsolute(filePath) ? filePath : path48.resolve(directory, filePath);
|
|
59740
59804
|
if (!fs34.existsSync(resolvedPath)) {
|
|
59741
59805
|
_filesSkipped++;
|
|
59742
59806
|
continue;
|
|
@@ -59935,18 +59999,18 @@ function validatePath(inputPath, baseDir, workspaceDir) {
|
|
|
59935
59999
|
let resolved;
|
|
59936
60000
|
const isWinAbs = isWindowsAbsolutePath(inputPath);
|
|
59937
60001
|
if (isWinAbs) {
|
|
59938
|
-
resolved =
|
|
59939
|
-
} else if (
|
|
59940
|
-
resolved =
|
|
60002
|
+
resolved = path49.win32.resolve(inputPath);
|
|
60003
|
+
} else if (path49.isAbsolute(inputPath)) {
|
|
60004
|
+
resolved = path49.resolve(inputPath);
|
|
59941
60005
|
} else {
|
|
59942
|
-
resolved =
|
|
60006
|
+
resolved = path49.resolve(baseDir, inputPath);
|
|
59943
60007
|
}
|
|
59944
|
-
const workspaceResolved =
|
|
60008
|
+
const workspaceResolved = path49.resolve(workspaceDir);
|
|
59945
60009
|
let relative5;
|
|
59946
60010
|
if (isWinAbs) {
|
|
59947
|
-
relative5 =
|
|
60011
|
+
relative5 = path49.win32.relative(workspaceResolved, resolved);
|
|
59948
60012
|
} else {
|
|
59949
|
-
relative5 =
|
|
60013
|
+
relative5 = path49.relative(workspaceResolved, resolved);
|
|
59950
60014
|
}
|
|
59951
60015
|
if (relative5.startsWith("..")) {
|
|
59952
60016
|
return "path traversal detected";
|
|
@@ -60007,13 +60071,13 @@ async function runLintWrapped(files, directory, _config) {
|
|
|
60007
60071
|
}
|
|
60008
60072
|
async function runLintOnFiles(linter, files, workspaceDir) {
|
|
60009
60073
|
const isWindows = process.platform === "win32";
|
|
60010
|
-
const binDir =
|
|
60074
|
+
const binDir = path49.join(workspaceDir, "node_modules", ".bin");
|
|
60011
60075
|
const validatedFiles = [];
|
|
60012
60076
|
for (const file3 of files) {
|
|
60013
60077
|
if (typeof file3 !== "string") {
|
|
60014
60078
|
continue;
|
|
60015
60079
|
}
|
|
60016
|
-
const resolvedPath =
|
|
60080
|
+
const resolvedPath = path49.resolve(file3);
|
|
60017
60081
|
const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
|
|
60018
60082
|
if (validationError) {
|
|
60019
60083
|
continue;
|
|
@@ -60031,10 +60095,10 @@ async function runLintOnFiles(linter, files, workspaceDir) {
|
|
|
60031
60095
|
}
|
|
60032
60096
|
let command;
|
|
60033
60097
|
if (linter === "biome") {
|
|
60034
|
-
const biomeBin = isWindows ?
|
|
60098
|
+
const biomeBin = isWindows ? path49.join(binDir, "biome.EXE") : path49.join(binDir, "biome");
|
|
60035
60099
|
command = [biomeBin, "check", ...validatedFiles];
|
|
60036
60100
|
} else {
|
|
60037
|
-
const eslintBin = isWindows ?
|
|
60101
|
+
const eslintBin = isWindows ? path49.join(binDir, "eslint.cmd") : path49.join(binDir, "eslint");
|
|
60038
60102
|
command = [eslintBin, ...validatedFiles];
|
|
60039
60103
|
}
|
|
60040
60104
|
try {
|
|
@@ -60171,7 +60235,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
60171
60235
|
skippedFiles++;
|
|
60172
60236
|
continue;
|
|
60173
60237
|
}
|
|
60174
|
-
const resolvedPath =
|
|
60238
|
+
const resolvedPath = path49.resolve(file3);
|
|
60175
60239
|
const validationError = validatePath(resolvedPath, directory, directory);
|
|
60176
60240
|
if (validationError) {
|
|
60177
60241
|
skippedFiles++;
|
|
@@ -60189,7 +60253,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
60189
60253
|
};
|
|
60190
60254
|
}
|
|
60191
60255
|
for (const file3 of validatedFiles) {
|
|
60192
|
-
const ext =
|
|
60256
|
+
const ext = path49.extname(file3).toLowerCase();
|
|
60193
60257
|
if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
|
|
60194
60258
|
skippedFiles++;
|
|
60195
60259
|
continue;
|
|
@@ -60348,7 +60412,7 @@ async function runPreCheckBatch(input, workspaceDir) {
|
|
|
60348
60412
|
warn(`pre_check_batch: Invalid file path: ${file3}`);
|
|
60349
60413
|
continue;
|
|
60350
60414
|
}
|
|
60351
|
-
changedFiles.push(
|
|
60415
|
+
changedFiles.push(path49.resolve(directory, file3));
|
|
60352
60416
|
}
|
|
60353
60417
|
if (changedFiles.length === 0) {
|
|
60354
60418
|
warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
|
|
@@ -60499,7 +60563,7 @@ var pre_check_batch = createSwarmTool({
|
|
|
60499
60563
|
};
|
|
60500
60564
|
return JSON.stringify(errorResult, null, 2);
|
|
60501
60565
|
}
|
|
60502
|
-
const resolvedDirectory =
|
|
60566
|
+
const resolvedDirectory = path49.resolve(typedArgs.directory);
|
|
60503
60567
|
const workspaceAnchor = resolvedDirectory;
|
|
60504
60568
|
const dirError = validateDirectory3(resolvedDirectory, workspaceAnchor);
|
|
60505
60569
|
if (dirError) {
|
|
@@ -60607,7 +60671,7 @@ init_tool();
|
|
|
60607
60671
|
init_manager2();
|
|
60608
60672
|
init_create_tool();
|
|
60609
60673
|
import * as fs36 from "fs";
|
|
60610
|
-
import * as
|
|
60674
|
+
import * as path50 from "path";
|
|
60611
60675
|
function detectPlaceholderContent(args2) {
|
|
60612
60676
|
const issues = [];
|
|
60613
60677
|
const placeholderPattern = /^\[\w[\w\s]*\]$/;
|
|
@@ -60711,7 +60775,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
60711
60775
|
try {
|
|
60712
60776
|
await savePlan(dir, plan);
|
|
60713
60777
|
try {
|
|
60714
|
-
const markerPath =
|
|
60778
|
+
const markerPath = path50.join(dir, ".swarm", ".plan-write-marker");
|
|
60715
60779
|
const marker = JSON.stringify({
|
|
60716
60780
|
source: "save_plan",
|
|
60717
60781
|
timestamp: new Date().toISOString(),
|
|
@@ -60723,7 +60787,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
60723
60787
|
return {
|
|
60724
60788
|
success: true,
|
|
60725
60789
|
message: "Plan saved successfully",
|
|
60726
|
-
plan_path:
|
|
60790
|
+
plan_path: path50.join(dir, ".swarm", "plan.json"),
|
|
60727
60791
|
phases_count: plan.phases.length,
|
|
60728
60792
|
tasks_count: tasksCount
|
|
60729
60793
|
};
|
|
@@ -60762,7 +60826,7 @@ var save_plan = createSwarmTool({
|
|
|
60762
60826
|
init_dist();
|
|
60763
60827
|
init_manager();
|
|
60764
60828
|
import * as fs37 from "fs";
|
|
60765
|
-
import * as
|
|
60829
|
+
import * as path51 from "path";
|
|
60766
60830
|
|
|
60767
60831
|
// src/sbom/detectors/index.ts
|
|
60768
60832
|
init_utils();
|
|
@@ -61610,7 +61674,7 @@ function findManifestFiles(rootDir) {
|
|
|
61610
61674
|
try {
|
|
61611
61675
|
const entries = fs37.readdirSync(dir, { withFileTypes: true });
|
|
61612
61676
|
for (const entry of entries) {
|
|
61613
|
-
const fullPath =
|
|
61677
|
+
const fullPath = path51.join(dir, entry.name);
|
|
61614
61678
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
|
|
61615
61679
|
continue;
|
|
61616
61680
|
}
|
|
@@ -61619,7 +61683,7 @@ function findManifestFiles(rootDir) {
|
|
|
61619
61683
|
} else if (entry.isFile()) {
|
|
61620
61684
|
for (const pattern of patterns) {
|
|
61621
61685
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
61622
|
-
manifestFiles.push(
|
|
61686
|
+
manifestFiles.push(path51.relative(rootDir, fullPath));
|
|
61623
61687
|
break;
|
|
61624
61688
|
}
|
|
61625
61689
|
}
|
|
@@ -61637,11 +61701,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
61637
61701
|
try {
|
|
61638
61702
|
const entries = fs37.readdirSync(dir, { withFileTypes: true });
|
|
61639
61703
|
for (const entry of entries) {
|
|
61640
|
-
const fullPath =
|
|
61704
|
+
const fullPath = path51.join(dir, entry.name);
|
|
61641
61705
|
if (entry.isFile()) {
|
|
61642
61706
|
for (const pattern of patterns) {
|
|
61643
61707
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
61644
|
-
found.push(
|
|
61708
|
+
found.push(path51.relative(workingDir, fullPath));
|
|
61645
61709
|
break;
|
|
61646
61710
|
}
|
|
61647
61711
|
}
|
|
@@ -61654,11 +61718,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
61654
61718
|
function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
|
|
61655
61719
|
const dirs = new Set;
|
|
61656
61720
|
for (const file3 of changedFiles) {
|
|
61657
|
-
let currentDir =
|
|
61721
|
+
let currentDir = path51.dirname(file3);
|
|
61658
61722
|
while (true) {
|
|
61659
|
-
if (currentDir && currentDir !== "." && currentDir !==
|
|
61660
|
-
dirs.add(
|
|
61661
|
-
const parent =
|
|
61723
|
+
if (currentDir && currentDir !== "." && currentDir !== path51.sep) {
|
|
61724
|
+
dirs.add(path51.join(workingDir, currentDir));
|
|
61725
|
+
const parent = path51.dirname(currentDir);
|
|
61662
61726
|
if (parent === currentDir)
|
|
61663
61727
|
break;
|
|
61664
61728
|
currentDir = parent;
|
|
@@ -61742,7 +61806,7 @@ var sbom_generate = createSwarmTool({
|
|
|
61742
61806
|
const changedFiles = obj.changed_files;
|
|
61743
61807
|
const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
|
|
61744
61808
|
const workingDir = directory;
|
|
61745
|
-
const outputDir =
|
|
61809
|
+
const outputDir = path51.isAbsolute(relativeOutputDir) ? relativeOutputDir : path51.join(workingDir, relativeOutputDir);
|
|
61746
61810
|
let manifestFiles = [];
|
|
61747
61811
|
if (scope === "all") {
|
|
61748
61812
|
manifestFiles = findManifestFiles(workingDir);
|
|
@@ -61765,7 +61829,7 @@ var sbom_generate = createSwarmTool({
|
|
|
61765
61829
|
const processedFiles = [];
|
|
61766
61830
|
for (const manifestFile of manifestFiles) {
|
|
61767
61831
|
try {
|
|
61768
|
-
const fullPath =
|
|
61832
|
+
const fullPath = path51.isAbsolute(manifestFile) ? manifestFile : path51.join(workingDir, manifestFile);
|
|
61769
61833
|
if (!fs37.existsSync(fullPath)) {
|
|
61770
61834
|
continue;
|
|
61771
61835
|
}
|
|
@@ -61782,7 +61846,7 @@ var sbom_generate = createSwarmTool({
|
|
|
61782
61846
|
const bom = generateCycloneDX(allComponents);
|
|
61783
61847
|
const bomJson = serializeCycloneDX(bom);
|
|
61784
61848
|
const filename = generateSbomFilename();
|
|
61785
|
-
const outputPath =
|
|
61849
|
+
const outputPath = path51.join(outputDir, filename);
|
|
61786
61850
|
fs37.writeFileSync(outputPath, bomJson, "utf-8");
|
|
61787
61851
|
const verdict = processedFiles.length > 0 ? "pass" : "pass";
|
|
61788
61852
|
try {
|
|
@@ -61826,7 +61890,7 @@ var sbom_generate = createSwarmTool({
|
|
|
61826
61890
|
init_dist();
|
|
61827
61891
|
init_create_tool();
|
|
61828
61892
|
import * as fs38 from "fs";
|
|
61829
|
-
import * as
|
|
61893
|
+
import * as path52 from "path";
|
|
61830
61894
|
var SPEC_CANDIDATES = [
|
|
61831
61895
|
"openapi.json",
|
|
61832
61896
|
"openapi.yaml",
|
|
@@ -61858,12 +61922,12 @@ function normalizePath2(p) {
|
|
|
61858
61922
|
}
|
|
61859
61923
|
function discoverSpecFile(cwd, specFileArg) {
|
|
61860
61924
|
if (specFileArg) {
|
|
61861
|
-
const resolvedPath =
|
|
61862
|
-
const normalizedCwd = cwd.endsWith(
|
|
61925
|
+
const resolvedPath = path52.resolve(cwd, specFileArg);
|
|
61926
|
+
const normalizedCwd = cwd.endsWith(path52.sep) ? cwd : cwd + path52.sep;
|
|
61863
61927
|
if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
|
|
61864
61928
|
throw new Error("Invalid spec_file: path traversal detected");
|
|
61865
61929
|
}
|
|
61866
|
-
const ext =
|
|
61930
|
+
const ext = path52.extname(resolvedPath).toLowerCase();
|
|
61867
61931
|
if (!ALLOWED_EXTENSIONS.includes(ext)) {
|
|
61868
61932
|
throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
|
|
61869
61933
|
}
|
|
@@ -61877,7 +61941,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
61877
61941
|
return resolvedPath;
|
|
61878
61942
|
}
|
|
61879
61943
|
for (const candidate of SPEC_CANDIDATES) {
|
|
61880
|
-
const candidatePath =
|
|
61944
|
+
const candidatePath = path52.resolve(cwd, candidate);
|
|
61881
61945
|
if (fs38.existsSync(candidatePath)) {
|
|
61882
61946
|
const stats = fs38.statSync(candidatePath);
|
|
61883
61947
|
if (stats.size <= MAX_SPEC_SIZE) {
|
|
@@ -61889,7 +61953,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
61889
61953
|
}
|
|
61890
61954
|
function parseSpec(specFile) {
|
|
61891
61955
|
const content = fs38.readFileSync(specFile, "utf-8");
|
|
61892
|
-
const ext =
|
|
61956
|
+
const ext = path52.extname(specFile).toLowerCase();
|
|
61893
61957
|
if (ext === ".json") {
|
|
61894
61958
|
return parseJsonSpec(content);
|
|
61895
61959
|
}
|
|
@@ -61965,7 +62029,7 @@ function extractRoutes(cwd) {
|
|
|
61965
62029
|
return;
|
|
61966
62030
|
}
|
|
61967
62031
|
for (const entry of entries) {
|
|
61968
|
-
const fullPath =
|
|
62032
|
+
const fullPath = path52.join(dir, entry.name);
|
|
61969
62033
|
if (entry.isSymbolicLink()) {
|
|
61970
62034
|
continue;
|
|
61971
62035
|
}
|
|
@@ -61975,7 +62039,7 @@ function extractRoutes(cwd) {
|
|
|
61975
62039
|
}
|
|
61976
62040
|
walkDir(fullPath);
|
|
61977
62041
|
} else if (entry.isFile()) {
|
|
61978
|
-
const ext =
|
|
62042
|
+
const ext = path52.extname(entry.name).toLowerCase();
|
|
61979
62043
|
const baseName = entry.name.toLowerCase();
|
|
61980
62044
|
if (![".ts", ".js", ".mjs"].includes(ext)) {
|
|
61981
62045
|
continue;
|
|
@@ -62145,7 +62209,7 @@ init_secretscan();
|
|
|
62145
62209
|
init_tool();
|
|
62146
62210
|
init_create_tool();
|
|
62147
62211
|
import * as fs39 from "fs";
|
|
62148
|
-
import * as
|
|
62212
|
+
import * as path53 from "path";
|
|
62149
62213
|
var MAX_FILE_SIZE_BYTES7 = 1024 * 1024;
|
|
62150
62214
|
var WINDOWS_RESERVED_NAMES = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
62151
62215
|
function containsControlCharacters(str) {
|
|
@@ -62174,11 +62238,11 @@ function containsWindowsAttacks(str) {
|
|
|
62174
62238
|
}
|
|
62175
62239
|
function isPathInWorkspace(filePath, workspace) {
|
|
62176
62240
|
try {
|
|
62177
|
-
const resolvedPath =
|
|
62241
|
+
const resolvedPath = path53.resolve(workspace, filePath);
|
|
62178
62242
|
const realWorkspace = fs39.realpathSync(workspace);
|
|
62179
62243
|
const realResolvedPath = fs39.realpathSync(resolvedPath);
|
|
62180
|
-
const relativePath =
|
|
62181
|
-
if (relativePath.startsWith("..") ||
|
|
62244
|
+
const relativePath = path53.relative(realWorkspace, realResolvedPath);
|
|
62245
|
+
if (relativePath.startsWith("..") || path53.isAbsolute(relativePath)) {
|
|
62182
62246
|
return false;
|
|
62183
62247
|
}
|
|
62184
62248
|
return true;
|
|
@@ -62190,7 +62254,7 @@ function validatePathForRead(filePath, workspace) {
|
|
|
62190
62254
|
return isPathInWorkspace(filePath, workspace);
|
|
62191
62255
|
}
|
|
62192
62256
|
function extractTSSymbols(filePath, cwd) {
|
|
62193
|
-
const fullPath =
|
|
62257
|
+
const fullPath = path53.join(cwd, filePath);
|
|
62194
62258
|
if (!validatePathForRead(fullPath, cwd)) {
|
|
62195
62259
|
return [];
|
|
62196
62260
|
}
|
|
@@ -62342,7 +62406,7 @@ function extractTSSymbols(filePath, cwd) {
|
|
|
62342
62406
|
});
|
|
62343
62407
|
}
|
|
62344
62408
|
function extractPythonSymbols(filePath, cwd) {
|
|
62345
|
-
const fullPath =
|
|
62409
|
+
const fullPath = path53.join(cwd, filePath);
|
|
62346
62410
|
if (!validatePathForRead(fullPath, cwd)) {
|
|
62347
62411
|
return [];
|
|
62348
62412
|
}
|
|
@@ -62425,7 +62489,7 @@ var symbols = createSwarmTool({
|
|
|
62425
62489
|
}, null, 2);
|
|
62426
62490
|
}
|
|
62427
62491
|
const cwd = directory;
|
|
62428
|
-
const ext =
|
|
62492
|
+
const ext = path53.extname(file3);
|
|
62429
62493
|
if (containsControlCharacters(file3)) {
|
|
62430
62494
|
return JSON.stringify({
|
|
62431
62495
|
file: file3,
|
|
@@ -62497,7 +62561,7 @@ init_dist();
|
|
|
62497
62561
|
init_utils();
|
|
62498
62562
|
init_create_tool();
|
|
62499
62563
|
import * as fs40 from "fs";
|
|
62500
|
-
import * as
|
|
62564
|
+
import * as path54 from "path";
|
|
62501
62565
|
var MAX_TEXT_LENGTH = 200;
|
|
62502
62566
|
var MAX_FILE_SIZE_BYTES8 = 1024 * 1024;
|
|
62503
62567
|
var SUPPORTED_EXTENSIONS2 = new Set([
|
|
@@ -62568,9 +62632,9 @@ function validatePathsInput(paths, cwd) {
|
|
|
62568
62632
|
return { error: "paths contains path traversal", resolvedPath: null };
|
|
62569
62633
|
}
|
|
62570
62634
|
try {
|
|
62571
|
-
const resolvedPath =
|
|
62572
|
-
const normalizedCwd =
|
|
62573
|
-
const normalizedResolved =
|
|
62635
|
+
const resolvedPath = path54.resolve(paths);
|
|
62636
|
+
const normalizedCwd = path54.resolve(cwd);
|
|
62637
|
+
const normalizedResolved = path54.resolve(resolvedPath);
|
|
62574
62638
|
if (!normalizedResolved.startsWith(normalizedCwd)) {
|
|
62575
62639
|
return {
|
|
62576
62640
|
error: "paths must be within the current working directory",
|
|
@@ -62586,7 +62650,7 @@ function validatePathsInput(paths, cwd) {
|
|
|
62586
62650
|
}
|
|
62587
62651
|
}
|
|
62588
62652
|
function isSupportedExtension(filePath) {
|
|
62589
|
-
const ext =
|
|
62653
|
+
const ext = path54.extname(filePath).toLowerCase();
|
|
62590
62654
|
return SUPPORTED_EXTENSIONS2.has(ext);
|
|
62591
62655
|
}
|
|
62592
62656
|
function findSourceFiles2(dir, files = []) {
|
|
@@ -62601,7 +62665,7 @@ function findSourceFiles2(dir, files = []) {
|
|
|
62601
62665
|
if (SKIP_DIRECTORIES3.has(entry)) {
|
|
62602
62666
|
continue;
|
|
62603
62667
|
}
|
|
62604
|
-
const fullPath =
|
|
62668
|
+
const fullPath = path54.join(dir, entry);
|
|
62605
62669
|
let stat2;
|
|
62606
62670
|
try {
|
|
62607
62671
|
stat2 = fs40.statSync(fullPath);
|
|
@@ -62713,7 +62777,7 @@ var todo_extract = createSwarmTool({
|
|
|
62713
62777
|
filesToScan.push(scanPath);
|
|
62714
62778
|
} else {
|
|
62715
62779
|
const errorResult = {
|
|
62716
|
-
error: `unsupported file extension: ${
|
|
62780
|
+
error: `unsupported file extension: ${path54.extname(scanPath)}`,
|
|
62717
62781
|
total: 0,
|
|
62718
62782
|
byPriority: { high: 0, medium: 0, low: 0 },
|
|
62719
62783
|
entries: []
|
|
@@ -62759,14 +62823,14 @@ var todo_extract = createSwarmTool({
|
|
|
62759
62823
|
init_tool();
|
|
62760
62824
|
init_schema();
|
|
62761
62825
|
import * as fs42 from "fs";
|
|
62762
|
-
import * as
|
|
62826
|
+
import * as path56 from "path";
|
|
62763
62827
|
|
|
62764
62828
|
// src/hooks/diff-scope.ts
|
|
62765
62829
|
import * as fs41 from "fs";
|
|
62766
|
-
import * as
|
|
62830
|
+
import * as path55 from "path";
|
|
62767
62831
|
function getDeclaredScope(taskId, directory) {
|
|
62768
62832
|
try {
|
|
62769
|
-
const planPath =
|
|
62833
|
+
const planPath = path55.join(directory, ".swarm", "plan.json");
|
|
62770
62834
|
if (!fs41.existsSync(planPath))
|
|
62771
62835
|
return null;
|
|
62772
62836
|
const raw = fs41.readFileSync(planPath, "utf-8");
|
|
@@ -62881,7 +62945,7 @@ var TIER_3_PATTERNS = [
|
|
|
62881
62945
|
];
|
|
62882
62946
|
function matchesTier3Pattern(files) {
|
|
62883
62947
|
for (const file3 of files) {
|
|
62884
|
-
const fileName =
|
|
62948
|
+
const fileName = path56.basename(file3);
|
|
62885
62949
|
for (const pattern of TIER_3_PATTERNS) {
|
|
62886
62950
|
if (pattern.test(fileName)) {
|
|
62887
62951
|
return true;
|
|
@@ -62903,7 +62967,7 @@ function checkReviewerGate(taskId, workingDirectory) {
|
|
|
62903
62967
|
if (hasActiveTurboMode2()) {
|
|
62904
62968
|
const resolvedDir2 = workingDirectory ?? process.cwd();
|
|
62905
62969
|
try {
|
|
62906
|
-
const planPath =
|
|
62970
|
+
const planPath = path56.join(resolvedDir2, ".swarm", "plan.json");
|
|
62907
62971
|
const planRaw = fs42.readFileSync(planPath, "utf-8");
|
|
62908
62972
|
const plan = JSON.parse(planRaw);
|
|
62909
62973
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -62923,7 +62987,7 @@ function checkReviewerGate(taskId, workingDirectory) {
|
|
|
62923
62987
|
}
|
|
62924
62988
|
const resolvedDir = workingDirectory ?? process.cwd();
|
|
62925
62989
|
try {
|
|
62926
|
-
const evidencePath =
|
|
62990
|
+
const evidencePath = path56.join(resolvedDir, ".swarm", "evidence", `${taskId}.json`);
|
|
62927
62991
|
const raw = fs42.readFileSync(evidencePath, "utf-8");
|
|
62928
62992
|
const evidence = JSON.parse(raw);
|
|
62929
62993
|
if (evidence?.required_gates && Array.isArray(evidence.required_gates) && evidence?.gates) {
|
|
@@ -62964,7 +63028,7 @@ function checkReviewerGate(taskId, workingDirectory) {
|
|
|
62964
63028
|
}
|
|
62965
63029
|
try {
|
|
62966
63030
|
const resolvedDir2 = workingDirectory ?? process.cwd();
|
|
62967
|
-
const planPath =
|
|
63031
|
+
const planPath = path56.join(resolvedDir2, ".swarm", "plan.json");
|
|
62968
63032
|
const planRaw = fs42.readFileSync(planPath, "utf-8");
|
|
62969
63033
|
const plan = JSON.parse(planRaw);
|
|
62970
63034
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -63146,8 +63210,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
63146
63210
|
};
|
|
63147
63211
|
}
|
|
63148
63212
|
}
|
|
63149
|
-
normalizedDir =
|
|
63150
|
-
const pathParts = normalizedDir.split(
|
|
63213
|
+
normalizedDir = path56.normalize(args2.working_directory);
|
|
63214
|
+
const pathParts = normalizedDir.split(path56.sep);
|
|
63151
63215
|
if (pathParts.includes("..")) {
|
|
63152
63216
|
return {
|
|
63153
63217
|
success: false,
|
|
@@ -63157,10 +63221,10 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
63157
63221
|
]
|
|
63158
63222
|
};
|
|
63159
63223
|
}
|
|
63160
|
-
const resolvedDir =
|
|
63224
|
+
const resolvedDir = path56.resolve(normalizedDir);
|
|
63161
63225
|
try {
|
|
63162
63226
|
const realPath = fs42.realpathSync(resolvedDir);
|
|
63163
|
-
const planPath =
|
|
63227
|
+
const planPath = path56.join(realPath, ".swarm", "plan.json");
|
|
63164
63228
|
if (!fs42.existsSync(planPath)) {
|
|
63165
63229
|
return {
|
|
63166
63230
|
success: false,
|
|
@@ -63355,7 +63419,7 @@ var OpenCodeSwarm = async (ctx) => {
|
|
|
63355
63419
|
const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
|
|
63356
63420
|
preflightTriggerManager = new PTM(automationConfig);
|
|
63357
63421
|
const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
|
|
63358
|
-
const swarmDir =
|
|
63422
|
+
const swarmDir = path57.resolve(ctx.directory, ".swarm");
|
|
63359
63423
|
statusArtifact = new ASA(swarmDir);
|
|
63360
63424
|
statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
|
|
63361
63425
|
if (automationConfig.capabilities?.evidence_auto_summaries === true) {
|