opencode-swarm 6.29.3 → 6.29.5
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 +16 -12
- package/dist/index.js +271 -205
- package/dist/session/snapshot-writer.d.ts +1 -0
- 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:
|
|
@@ -46351,6 +46385,7 @@ function serializeAgentSession(s) {
|
|
|
46351
46385
|
lastCompletedPhaseAgentsDispatched,
|
|
46352
46386
|
qaSkipCount: s.qaSkipCount ?? 0,
|
|
46353
46387
|
qaSkipTaskIds: s.qaSkipTaskIds ?? [],
|
|
46388
|
+
pendingAdvisoryMessages: s.pendingAdvisoryMessages ?? [],
|
|
46354
46389
|
taskWorkflowStates: Object.fromEntries(s.taskWorkflowStates ?? new Map),
|
|
46355
46390
|
...s.scopeViolationDetected !== undefined && {
|
|
46356
46391
|
scopeViolationDetected: s.scopeViolationDetected
|
|
@@ -49837,7 +49872,7 @@ ${pending.message}
|
|
|
49837
49872
|
}
|
|
49838
49873
|
}
|
|
49839
49874
|
if (isArchitectSession && (session?.pendingAdvisoryMessages?.length ?? 0) > 0) {
|
|
49840
|
-
const advisories = session.pendingAdvisoryMessages;
|
|
49875
|
+
const advisories = session.pendingAdvisoryMessages ?? [];
|
|
49841
49876
|
let targetMsg = systemMessages[0];
|
|
49842
49877
|
if (!targetMsg) {
|
|
49843
49878
|
const newMsg = {
|
|
@@ -50766,6 +50801,7 @@ function consolidateSystemMessages(messages) {
|
|
|
50766
50801
|
// src/hooks/phase-monitor.ts
|
|
50767
50802
|
init_schema();
|
|
50768
50803
|
init_manager2();
|
|
50804
|
+
import * as path31 from "path";
|
|
50769
50805
|
init_utils2();
|
|
50770
50806
|
function createPhaseMonitorHook(directory, preflightManager, curatorRunner = runCuratorInit) {
|
|
50771
50807
|
let lastKnownPhase = null;
|
|
@@ -50781,7 +50817,13 @@ function createPhaseMonitorHook(directory, preflightManager, curatorRunner = run
|
|
|
50781
50817
|
const { config: config3 } = loadPluginConfigWithMeta2(directory);
|
|
50782
50818
|
const curatorConfig = CuratorConfigSchema.parse(config3.curator ?? {});
|
|
50783
50819
|
if (curatorConfig.enabled && curatorConfig.init_enabled) {
|
|
50784
|
-
await curatorRunner(directory, curatorConfig);
|
|
50820
|
+
const initResult = await curatorRunner(directory, curatorConfig);
|
|
50821
|
+
if (initResult.briefing) {
|
|
50822
|
+
const briefingPath = path31.join(directory, ".swarm", "curator-briefing.md");
|
|
50823
|
+
const { mkdir: mkdir4, writeFile: writeFile4 } = await import("fs/promises");
|
|
50824
|
+
await mkdir4(path31.dirname(briefingPath), { recursive: true });
|
|
50825
|
+
await writeFile4(briefingPath, initResult.briefing, "utf-8");
|
|
50826
|
+
}
|
|
50785
50827
|
}
|
|
50786
50828
|
} catch {}
|
|
50787
50829
|
return;
|
|
@@ -50897,7 +50939,7 @@ import * as fs19 from "fs";
|
|
|
50897
50939
|
init_utils2();
|
|
50898
50940
|
init_manager2();
|
|
50899
50941
|
import * as fs18 from "fs";
|
|
50900
|
-
import * as
|
|
50942
|
+
import * as path32 from "path";
|
|
50901
50943
|
var DEFAULT_DRIFT_CONFIG = {
|
|
50902
50944
|
staleThresholdPhases: 1,
|
|
50903
50945
|
detectContradictions: true,
|
|
@@ -51051,7 +51093,7 @@ async function analyzeDecisionDrift(directory, config3 = {}) {
|
|
|
51051
51093
|
currentPhase = legacyPhase;
|
|
51052
51094
|
}
|
|
51053
51095
|
}
|
|
51054
|
-
const contextPath =
|
|
51096
|
+
const contextPath = path32.join(directory, ".swarm", "context.md");
|
|
51055
51097
|
let contextContent = "";
|
|
51056
51098
|
try {
|
|
51057
51099
|
if (fs18.existsSync(contextPath)) {
|
|
@@ -52516,7 +52558,7 @@ function createDarkMatterDetectorHook(directory) {
|
|
|
52516
52558
|
|
|
52517
52559
|
// src/hooks/incremental-verify.ts
|
|
52518
52560
|
import * as fs20 from "fs";
|
|
52519
|
-
import * as
|
|
52561
|
+
import * as path33 from "path";
|
|
52520
52562
|
|
|
52521
52563
|
// src/hooks/spawn-helper.ts
|
|
52522
52564
|
import { spawn } from "child_process";
|
|
@@ -52572,7 +52614,7 @@ function spawnAsync(command, cwd, timeoutMs) {
|
|
|
52572
52614
|
// src/hooks/incremental-verify.ts
|
|
52573
52615
|
var emittedSkipAdvisories = new Set;
|
|
52574
52616
|
function detectTypecheckCommand(projectDir) {
|
|
52575
|
-
const pkgPath =
|
|
52617
|
+
const pkgPath = path33.join(projectDir, "package.json");
|
|
52576
52618
|
if (fs20.existsSync(pkgPath)) {
|
|
52577
52619
|
try {
|
|
52578
52620
|
const pkg = JSON.parse(fs20.readFileSync(pkgPath, "utf8"));
|
|
@@ -52588,8 +52630,8 @@ function detectTypecheckCommand(projectDir) {
|
|
|
52588
52630
|
...pkg.dependencies,
|
|
52589
52631
|
...pkg.devDependencies
|
|
52590
52632
|
};
|
|
52591
|
-
if (!deps?.typescript && !fs20.existsSync(
|
|
52592
|
-
const hasTSMarkers = deps?.typescript || fs20.existsSync(
|
|
52633
|
+
if (!deps?.typescript && !fs20.existsSync(path33.join(projectDir, "tsconfig.json"))) {}
|
|
52634
|
+
const hasTSMarkers = deps?.typescript || fs20.existsSync(path33.join(projectDir, "tsconfig.json"));
|
|
52593
52635
|
if (hasTSMarkers) {
|
|
52594
52636
|
return { command: ["npx", "tsc", "--noEmit"], language: "typescript" };
|
|
52595
52637
|
}
|
|
@@ -52597,13 +52639,13 @@ function detectTypecheckCommand(projectDir) {
|
|
|
52597
52639
|
return null;
|
|
52598
52640
|
}
|
|
52599
52641
|
}
|
|
52600
|
-
if (fs20.existsSync(
|
|
52642
|
+
if (fs20.existsSync(path33.join(projectDir, "go.mod"))) {
|
|
52601
52643
|
return { command: ["go", "vet", "./..."], language: "go" };
|
|
52602
52644
|
}
|
|
52603
|
-
if (fs20.existsSync(
|
|
52645
|
+
if (fs20.existsSync(path33.join(projectDir, "Cargo.toml"))) {
|
|
52604
52646
|
return { command: ["cargo", "check"], language: "rust" };
|
|
52605
52647
|
}
|
|
52606
|
-
if (fs20.existsSync(
|
|
52648
|
+
if (fs20.existsSync(path33.join(projectDir, "pyproject.toml")) || fs20.existsSync(path33.join(projectDir, "requirements.txt")) || fs20.existsSync(path33.join(projectDir, "setup.py"))) {
|
|
52607
52649
|
return { command: null, language: "python" };
|
|
52608
52650
|
}
|
|
52609
52651
|
try {
|
|
@@ -52674,7 +52716,7 @@ ${errorSummary}`);
|
|
|
52674
52716
|
// src/hooks/knowledge-reader.ts
|
|
52675
52717
|
import { existsSync as existsSync19 } from "fs";
|
|
52676
52718
|
import { mkdir as mkdir4, readFile as readFile5, writeFile as writeFile4 } from "fs/promises";
|
|
52677
|
-
import * as
|
|
52719
|
+
import * as path34 from "path";
|
|
52678
52720
|
var JACCARD_THRESHOLD = 0.6;
|
|
52679
52721
|
var HIVE_TIER_BOOST = 0.05;
|
|
52680
52722
|
var SAME_PROJECT_PENALTY = -0.05;
|
|
@@ -52722,7 +52764,7 @@ function inferCategoriesFromPhase(phaseDescription) {
|
|
|
52722
52764
|
return ["process", "tooling"];
|
|
52723
52765
|
}
|
|
52724
52766
|
async function recordLessonsShown(directory, lessonIds, currentPhase) {
|
|
52725
|
-
const shownFile =
|
|
52767
|
+
const shownFile = path34.join(directory, ".swarm", ".knowledge-shown.json");
|
|
52726
52768
|
try {
|
|
52727
52769
|
let shownData = {};
|
|
52728
52770
|
if (existsSync19(shownFile)) {
|
|
@@ -52730,7 +52772,7 @@ async function recordLessonsShown(directory, lessonIds, currentPhase) {
|
|
|
52730
52772
|
shownData = JSON.parse(content);
|
|
52731
52773
|
}
|
|
52732
52774
|
shownData[currentPhase] = lessonIds;
|
|
52733
|
-
await mkdir4(
|
|
52775
|
+
await mkdir4(path34.dirname(shownFile), { recursive: true });
|
|
52734
52776
|
await writeFile4(shownFile, JSON.stringify(shownData, null, 2), "utf-8");
|
|
52735
52777
|
} catch {
|
|
52736
52778
|
console.warn("[swarm] Knowledge: failed to record shown lessons");
|
|
@@ -52825,7 +52867,7 @@ async function readMergedKnowledge(directory, config3, context) {
|
|
|
52825
52867
|
return topN;
|
|
52826
52868
|
}
|
|
52827
52869
|
async function updateRetrievalOutcome(directory, phaseInfo, phaseSucceeded) {
|
|
52828
|
-
const shownFile =
|
|
52870
|
+
const shownFile = path34.join(directory, ".swarm", ".knowledge-shown.json");
|
|
52829
52871
|
try {
|
|
52830
52872
|
if (!existsSync19(shownFile)) {
|
|
52831
52873
|
return;
|
|
@@ -53298,10 +53340,10 @@ Use this data to avoid repeating known failure patterns.`;
|
|
|
53298
53340
|
init_event_bus();
|
|
53299
53341
|
init_utils2();
|
|
53300
53342
|
import * as fs21 from "fs";
|
|
53301
|
-
import * as
|
|
53343
|
+
import * as path35 from "path";
|
|
53302
53344
|
var DRIFT_REPORT_PREFIX = "drift-report-phase-";
|
|
53303
53345
|
async function readPriorDriftReports(directory) {
|
|
53304
|
-
const swarmDir =
|
|
53346
|
+
const swarmDir = path35.join(directory, ".swarm");
|
|
53305
53347
|
const entries = await fs21.promises.readdir(swarmDir).catch(() => null);
|
|
53306
53348
|
if (entries === null)
|
|
53307
53349
|
return [];
|
|
@@ -53328,7 +53370,7 @@ async function readPriorDriftReports(directory) {
|
|
|
53328
53370
|
async function writeDriftReport(directory, report) {
|
|
53329
53371
|
const filename = `${DRIFT_REPORT_PREFIX}${report.phase}.json`;
|
|
53330
53372
|
const filePath = validateSwarmPath(directory, filename);
|
|
53331
|
-
const swarmDir =
|
|
53373
|
+
const swarmDir = path35.dirname(filePath);
|
|
53332
53374
|
await fs21.promises.mkdir(swarmDir, { recursive: true });
|
|
53333
53375
|
try {
|
|
53334
53376
|
await fs21.promises.writeFile(filePath, JSON.stringify(report, null, 2), "utf-8");
|
|
@@ -53482,7 +53524,7 @@ function isOrchestratorAgent(agentName) {
|
|
|
53482
53524
|
function injectKnowledgeMessage(output, text) {
|
|
53483
53525
|
if (!output.messages)
|
|
53484
53526
|
return;
|
|
53485
|
-
const alreadyInjected = output.messages.some((m) => m.parts?.some((p) => p.text?.includes("\uD83D\uDCDA Knowledge")));
|
|
53527
|
+
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
53528
|
if (alreadyInjected)
|
|
53487
53529
|
return;
|
|
53488
53530
|
const systemIdx = output.messages.findIndex((m) => m.info?.role === "system");
|
|
@@ -53528,8 +53570,33 @@ function createKnowledgeInjectorHook(directory, config3) {
|
|
|
53528
53570
|
currentPhase: phaseDescription
|
|
53529
53571
|
};
|
|
53530
53572
|
const entries = await readMergedKnowledge(directory, config3, context);
|
|
53531
|
-
|
|
53573
|
+
let freshPreamble = null;
|
|
53574
|
+
try {
|
|
53575
|
+
const driftReports = await readPriorDriftReports(directory);
|
|
53576
|
+
if (driftReports.length > 0) {
|
|
53577
|
+
const latestReport = driftReports[driftReports.length - 1];
|
|
53578
|
+
const driftText = buildDriftInjectionText(latestReport, 500);
|
|
53579
|
+
if (driftText) {
|
|
53580
|
+
freshPreamble = 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
|
+
freshPreamble = freshPreamble ? `<curator_briefing>${truncatedBriefing}</curator_briefing>
|
|
53589
|
+
|
|
53590
|
+
${freshPreamble}` : `<curator_briefing>${truncatedBriefing}</curator_briefing>`;
|
|
53591
|
+
}
|
|
53592
|
+
} catch {}
|
|
53593
|
+
if (entries.length === 0) {
|
|
53594
|
+
if (freshPreamble === null)
|
|
53595
|
+
return;
|
|
53596
|
+
cachedInjectionText = freshPreamble;
|
|
53597
|
+
injectKnowledgeMessage(output, cachedInjectionText);
|
|
53532
53598
|
return;
|
|
53599
|
+
}
|
|
53533
53600
|
const runMemory = await getRunMemorySummary(directory);
|
|
53534
53601
|
const lines = entries.map((entry) => {
|
|
53535
53602
|
const stars = formatStars(entry.confidence);
|
|
@@ -53548,13 +53615,15 @@ function createKnowledgeInjectorHook(directory, config3) {
|
|
|
53548
53615
|
"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
53616
|
].join(`
|
|
53550
53617
|
`);
|
|
53618
|
+
let injectionText = freshPreamble ? `${freshPreamble}
|
|
53619
|
+
|
|
53620
|
+
${knowledgeSection}` : knowledgeSection;
|
|
53551
53621
|
if (runMemory) {
|
|
53552
|
-
|
|
53622
|
+
injectionText = `${runMemory}
|
|
53553
53623
|
|
|
53554
|
-
${
|
|
53555
|
-
} else {
|
|
53556
|
-
cachedInjectionText = knowledgeSection;
|
|
53624
|
+
${injectionText}`;
|
|
53557
53625
|
}
|
|
53626
|
+
cachedInjectionText = injectionText;
|
|
53558
53627
|
const rejected = await readRejectedLessons(directory);
|
|
53559
53628
|
if (rejected.length > 0) {
|
|
53560
53629
|
const recentRejected = rejected.slice(-3);
|
|
@@ -53565,25 +53634,13 @@ ${knowledgeSection}`;
|
|
|
53565
53634
|
` + rejectedLines.join(`
|
|
53566
53635
|
`);
|
|
53567
53636
|
}
|
|
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
53637
|
injectKnowledgeMessage(output, cachedInjectionText);
|
|
53581
53638
|
});
|
|
53582
53639
|
}
|
|
53583
53640
|
|
|
53584
53641
|
// src/hooks/slop-detector.ts
|
|
53585
53642
|
import * as fs22 from "fs";
|
|
53586
|
-
import * as
|
|
53643
|
+
import * as path36 from "path";
|
|
53587
53644
|
var WRITE_EDIT_TOOLS = new Set([
|
|
53588
53645
|
"write",
|
|
53589
53646
|
"edit",
|
|
@@ -53633,7 +53690,7 @@ function walkFiles(dir, exts, deadline) {
|
|
|
53633
53690
|
break;
|
|
53634
53691
|
if (entry.isSymbolicLink())
|
|
53635
53692
|
continue;
|
|
53636
|
-
const full =
|
|
53693
|
+
const full = path36.join(dir, entry.name);
|
|
53637
53694
|
if (entry.isDirectory()) {
|
|
53638
53695
|
if (entry.name === "node_modules" || entry.name === ".git")
|
|
53639
53696
|
continue;
|
|
@@ -53648,7 +53705,7 @@ function walkFiles(dir, exts, deadline) {
|
|
|
53648
53705
|
return results;
|
|
53649
53706
|
}
|
|
53650
53707
|
function checkDeadExports(content, projectDir, startTime) {
|
|
53651
|
-
const hasPackageJson = fs22.existsSync(
|
|
53708
|
+
const hasPackageJson = fs22.existsSync(path36.join(projectDir, "package.json"));
|
|
53652
53709
|
if (!hasPackageJson)
|
|
53653
53710
|
return null;
|
|
53654
53711
|
const exportMatches = content.matchAll(/^\+(?:export)\s+(?:function|class|const|type|interface)\s+(\w{3,})/gm);
|
|
@@ -53798,7 +53855,7 @@ init_config_doctor();
|
|
|
53798
53855
|
|
|
53799
53856
|
// src/session/snapshot-reader.ts
|
|
53800
53857
|
init_utils2();
|
|
53801
|
-
import
|
|
53858
|
+
import path37 from "path";
|
|
53802
53859
|
var VALID_TASK_WORKFLOW_STATES = [
|
|
53803
53860
|
"idle",
|
|
53804
53861
|
"coder_delegated",
|
|
@@ -53870,7 +53927,8 @@ function deserializeAgentSession(s) {
|
|
|
53870
53927
|
declaredCoderScope: null,
|
|
53871
53928
|
lastScopeViolation: null,
|
|
53872
53929
|
scopeViolationDetected: s.scopeViolationDetected,
|
|
53873
|
-
modifiedFilesThisCoderTask: []
|
|
53930
|
+
modifiedFilesThisCoderTask: [],
|
|
53931
|
+
pendingAdvisoryMessages: s.pendingAdvisoryMessages ?? []
|
|
53874
53932
|
};
|
|
53875
53933
|
}
|
|
53876
53934
|
async function readSnapshot(directory) {
|
|
@@ -53923,7 +53981,7 @@ function rehydrateState(snapshot) {
|
|
|
53923
53981
|
async function reconcileTaskStatesFromPlan(directory) {
|
|
53924
53982
|
let raw;
|
|
53925
53983
|
try {
|
|
53926
|
-
raw = await Bun.file(
|
|
53984
|
+
raw = await Bun.file(path37.join(directory, ".swarm/plan.json")).text();
|
|
53927
53985
|
} catch {
|
|
53928
53986
|
return;
|
|
53929
53987
|
}
|
|
@@ -54146,7 +54204,7 @@ var build_check = createSwarmTool({
|
|
|
54146
54204
|
init_dist();
|
|
54147
54205
|
init_create_tool();
|
|
54148
54206
|
import * as fs24 from "fs";
|
|
54149
|
-
import * as
|
|
54207
|
+
import * as path38 from "path";
|
|
54150
54208
|
var EVIDENCE_DIR = ".swarm/evidence";
|
|
54151
54209
|
var TASK_ID_PATTERN2 = /^\d+\.\d+(\.\d+)*$/;
|
|
54152
54210
|
function isValidTaskId3(taskId) {
|
|
@@ -54163,9 +54221,9 @@ function isValidTaskId3(taskId) {
|
|
|
54163
54221
|
return TASK_ID_PATTERN2.test(taskId);
|
|
54164
54222
|
}
|
|
54165
54223
|
function isPathWithinSwarm(filePath, workspaceRoot) {
|
|
54166
|
-
const normalizedWorkspace =
|
|
54167
|
-
const swarmPath =
|
|
54168
|
-
const normalizedPath =
|
|
54224
|
+
const normalizedWorkspace = path38.resolve(workspaceRoot);
|
|
54225
|
+
const swarmPath = path38.join(normalizedWorkspace, ".swarm", "evidence");
|
|
54226
|
+
const normalizedPath = path38.resolve(filePath);
|
|
54169
54227
|
return normalizedPath.startsWith(swarmPath);
|
|
54170
54228
|
}
|
|
54171
54229
|
function readEvidenceFile(evidencePath) {
|
|
@@ -54226,7 +54284,7 @@ var check_gate_status = createSwarmTool({
|
|
|
54226
54284
|
};
|
|
54227
54285
|
return JSON.stringify(errorResult, null, 2);
|
|
54228
54286
|
}
|
|
54229
|
-
const evidencePath =
|
|
54287
|
+
const evidencePath = path38.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
|
|
54230
54288
|
if (!isPathWithinSwarm(evidencePath, directory)) {
|
|
54231
54289
|
const errorResult = {
|
|
54232
54290
|
taskId: taskIdInput,
|
|
@@ -54287,7 +54345,7 @@ init_tool();
|
|
|
54287
54345
|
init_create_tool();
|
|
54288
54346
|
import { spawnSync } from "child_process";
|
|
54289
54347
|
import * as fs25 from "fs";
|
|
54290
|
-
import * as
|
|
54348
|
+
import * as path39 from "path";
|
|
54291
54349
|
var CHECKPOINT_LOG_PATH = ".swarm/checkpoints.json";
|
|
54292
54350
|
var MAX_LABEL_LENGTH = 100;
|
|
54293
54351
|
var GIT_TIMEOUT_MS = 30000;
|
|
@@ -54338,7 +54396,7 @@ function validateLabel(label) {
|
|
|
54338
54396
|
return null;
|
|
54339
54397
|
}
|
|
54340
54398
|
function getCheckpointLogPath(directory) {
|
|
54341
|
-
return
|
|
54399
|
+
return path39.join(directory, CHECKPOINT_LOG_PATH);
|
|
54342
54400
|
}
|
|
54343
54401
|
function readCheckpointLog(directory) {
|
|
54344
54402
|
const logPath = getCheckpointLogPath(directory);
|
|
@@ -54356,7 +54414,7 @@ function readCheckpointLog(directory) {
|
|
|
54356
54414
|
}
|
|
54357
54415
|
function writeCheckpointLog(log2, directory) {
|
|
54358
54416
|
const logPath = getCheckpointLogPath(directory);
|
|
54359
|
-
const dir =
|
|
54417
|
+
const dir = path39.dirname(logPath);
|
|
54360
54418
|
if (!fs25.existsSync(dir)) {
|
|
54361
54419
|
fs25.mkdirSync(dir, { recursive: true });
|
|
54362
54420
|
}
|
|
@@ -54564,7 +54622,7 @@ var checkpoint = createSwarmTool({
|
|
|
54564
54622
|
init_dist();
|
|
54565
54623
|
init_create_tool();
|
|
54566
54624
|
import * as fs26 from "fs";
|
|
54567
|
-
import * as
|
|
54625
|
+
import * as path40 from "path";
|
|
54568
54626
|
var MAX_FILE_SIZE_BYTES2 = 256 * 1024;
|
|
54569
54627
|
var DEFAULT_DAYS = 90;
|
|
54570
54628
|
var DEFAULT_TOP_N = 20;
|
|
@@ -54708,7 +54766,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
54708
54766
|
const extSet = new Set(extensions.map((e) => e.startsWith(".") ? e : `.${e}`));
|
|
54709
54767
|
const filteredChurn = new Map;
|
|
54710
54768
|
for (const [file3, count] of churnMap) {
|
|
54711
|
-
const ext =
|
|
54769
|
+
const ext = path40.extname(file3).toLowerCase();
|
|
54712
54770
|
if (extSet.has(ext)) {
|
|
54713
54771
|
filteredChurn.set(file3, count);
|
|
54714
54772
|
}
|
|
@@ -54719,7 +54777,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
|
|
|
54719
54777
|
for (const [file3, churnCount] of filteredChurn) {
|
|
54720
54778
|
let fullPath = file3;
|
|
54721
54779
|
if (!fs26.existsSync(fullPath)) {
|
|
54722
|
-
fullPath =
|
|
54780
|
+
fullPath = path40.join(cwd, file3);
|
|
54723
54781
|
}
|
|
54724
54782
|
const complexity = getComplexityForFile(fullPath);
|
|
54725
54783
|
if (complexity !== null) {
|
|
@@ -54867,7 +54925,7 @@ var complexity_hotspots = createSwarmTool({
|
|
|
54867
54925
|
// src/tools/declare-scope.ts
|
|
54868
54926
|
init_tool();
|
|
54869
54927
|
import * as fs27 from "fs";
|
|
54870
|
-
import * as
|
|
54928
|
+
import * as path41 from "path";
|
|
54871
54929
|
init_create_tool();
|
|
54872
54930
|
function validateTaskIdFormat(taskId) {
|
|
54873
54931
|
const taskIdPattern = /^\d+\.\d+(\.\d+)*$/;
|
|
@@ -54946,8 +55004,8 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
54946
55004
|
};
|
|
54947
55005
|
}
|
|
54948
55006
|
}
|
|
54949
|
-
normalizedDir =
|
|
54950
|
-
const pathParts = normalizedDir.split(
|
|
55007
|
+
normalizedDir = path41.normalize(args2.working_directory);
|
|
55008
|
+
const pathParts = normalizedDir.split(path41.sep);
|
|
54951
55009
|
if (pathParts.includes("..")) {
|
|
54952
55010
|
return {
|
|
54953
55011
|
success: false,
|
|
@@ -54957,10 +55015,10 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
54957
55015
|
]
|
|
54958
55016
|
};
|
|
54959
55017
|
}
|
|
54960
|
-
const resolvedDir =
|
|
55018
|
+
const resolvedDir = path41.resolve(normalizedDir);
|
|
54961
55019
|
try {
|
|
54962
55020
|
const realPath = fs27.realpathSync(resolvedDir);
|
|
54963
|
-
const planPath2 =
|
|
55021
|
+
const planPath2 = path41.join(realPath, ".swarm", "plan.json");
|
|
54964
55022
|
if (!fs27.existsSync(planPath2)) {
|
|
54965
55023
|
return {
|
|
54966
55024
|
success: false,
|
|
@@ -54981,7 +55039,7 @@ async function executeDeclareScope(args2, fallbackDir) {
|
|
|
54981
55039
|
}
|
|
54982
55040
|
}
|
|
54983
55041
|
const directory = normalizedDir ?? fallbackDir ?? process.cwd();
|
|
54984
|
-
const planPath =
|
|
55042
|
+
const planPath = path41.resolve(directory, ".swarm", "plan.json");
|
|
54985
55043
|
if (!fs27.existsSync(planPath)) {
|
|
54986
55044
|
return {
|
|
54987
55045
|
success: false,
|
|
@@ -55071,20 +55129,20 @@ function validateBase(base) {
|
|
|
55071
55129
|
function validatePaths(paths) {
|
|
55072
55130
|
if (!paths)
|
|
55073
55131
|
return null;
|
|
55074
|
-
for (const
|
|
55075
|
-
if (!
|
|
55132
|
+
for (const path42 of paths) {
|
|
55133
|
+
if (!path42 || path42.length === 0) {
|
|
55076
55134
|
return "empty path not allowed";
|
|
55077
55135
|
}
|
|
55078
|
-
if (
|
|
55136
|
+
if (path42.length > MAX_PATH_LENGTH) {
|
|
55079
55137
|
return `path exceeds maximum length of ${MAX_PATH_LENGTH}`;
|
|
55080
55138
|
}
|
|
55081
|
-
if (SHELL_METACHARACTERS2.test(
|
|
55139
|
+
if (SHELL_METACHARACTERS2.test(path42)) {
|
|
55082
55140
|
return "path contains shell metacharacters";
|
|
55083
55141
|
}
|
|
55084
|
-
if (
|
|
55142
|
+
if (path42.startsWith("-")) {
|
|
55085
55143
|
return 'path cannot start with "-" (option-like arguments not allowed)';
|
|
55086
55144
|
}
|
|
55087
|
-
if (CONTROL_CHAR_PATTERN2.test(
|
|
55145
|
+
if (CONTROL_CHAR_PATTERN2.test(path42)) {
|
|
55088
55146
|
return "path contains control characters";
|
|
55089
55147
|
}
|
|
55090
55148
|
}
|
|
@@ -55164,8 +55222,8 @@ var diff = tool({
|
|
|
55164
55222
|
if (parts2.length >= 3) {
|
|
55165
55223
|
const additions = parseInt(parts2[0], 10) || 0;
|
|
55166
55224
|
const deletions = parseInt(parts2[1], 10) || 0;
|
|
55167
|
-
const
|
|
55168
|
-
files.push({ path:
|
|
55225
|
+
const path42 = parts2[2];
|
|
55226
|
+
files.push({ path: path42, additions, deletions });
|
|
55169
55227
|
}
|
|
55170
55228
|
}
|
|
55171
55229
|
const contractChanges = [];
|
|
@@ -55395,7 +55453,7 @@ Use these as DOMAIN values when delegating to @sme.`;
|
|
|
55395
55453
|
init_dist();
|
|
55396
55454
|
init_create_tool();
|
|
55397
55455
|
import * as fs28 from "fs";
|
|
55398
|
-
import * as
|
|
55456
|
+
import * as path42 from "path";
|
|
55399
55457
|
var MAX_FILE_SIZE_BYTES3 = 1024 * 1024;
|
|
55400
55458
|
var MAX_EVIDENCE_FILES = 1000;
|
|
55401
55459
|
var EVIDENCE_DIR2 = ".swarm/evidence";
|
|
@@ -55425,9 +55483,9 @@ function validateRequiredTypes(input) {
|
|
|
55425
55483
|
return null;
|
|
55426
55484
|
}
|
|
55427
55485
|
function isPathWithinSwarm2(filePath, cwd) {
|
|
55428
|
-
const normalizedCwd =
|
|
55429
|
-
const swarmPath =
|
|
55430
|
-
const normalizedPath =
|
|
55486
|
+
const normalizedCwd = path42.resolve(cwd);
|
|
55487
|
+
const swarmPath = path42.join(normalizedCwd, ".swarm");
|
|
55488
|
+
const normalizedPath = path42.resolve(filePath);
|
|
55431
55489
|
return normalizedPath.startsWith(swarmPath);
|
|
55432
55490
|
}
|
|
55433
55491
|
function parseCompletedTasks(planContent) {
|
|
@@ -55457,10 +55515,10 @@ function readEvidenceFiles(evidenceDir, _cwd) {
|
|
|
55457
55515
|
if (!VALID_EVIDENCE_FILENAME_REGEX.test(filename)) {
|
|
55458
55516
|
continue;
|
|
55459
55517
|
}
|
|
55460
|
-
const filePath =
|
|
55518
|
+
const filePath = path42.join(evidenceDir, filename);
|
|
55461
55519
|
try {
|
|
55462
|
-
const resolvedPath =
|
|
55463
|
-
const evidenceDirResolved =
|
|
55520
|
+
const resolvedPath = path42.resolve(filePath);
|
|
55521
|
+
const evidenceDirResolved = path42.resolve(evidenceDir);
|
|
55464
55522
|
if (!resolvedPath.startsWith(evidenceDirResolved)) {
|
|
55465
55523
|
continue;
|
|
55466
55524
|
}
|
|
@@ -55578,7 +55636,7 @@ var evidence_check = createSwarmTool({
|
|
|
55578
55636
|
return JSON.stringify(errorResult, null, 2);
|
|
55579
55637
|
}
|
|
55580
55638
|
const requiredTypes = requiredTypesValue.split(",").map((t) => t.trim()).filter((t) => t.length > 0).map(normalizeEvidenceType);
|
|
55581
|
-
const planPath =
|
|
55639
|
+
const planPath = path42.join(cwd, PLAN_FILE);
|
|
55582
55640
|
if (!isPathWithinSwarm2(planPath, cwd)) {
|
|
55583
55641
|
const errorResult = {
|
|
55584
55642
|
error: "plan file path validation failed",
|
|
@@ -55610,7 +55668,7 @@ var evidence_check = createSwarmTool({
|
|
|
55610
55668
|
};
|
|
55611
55669
|
return JSON.stringify(result2, null, 2);
|
|
55612
55670
|
}
|
|
55613
|
-
const evidenceDir =
|
|
55671
|
+
const evidenceDir = path42.join(cwd, EVIDENCE_DIR2);
|
|
55614
55672
|
const evidence = readEvidenceFiles(evidenceDir, cwd);
|
|
55615
55673
|
const { tasksWithFullEvidence, gaps } = analyzeGaps(completedTasks, evidence, requiredTypes);
|
|
55616
55674
|
const completeness = completedTasks.length > 0 ? Math.round(tasksWithFullEvidence.length / completedTasks.length * 100) / 100 : 1;
|
|
@@ -55628,7 +55686,7 @@ var evidence_check = createSwarmTool({
|
|
|
55628
55686
|
init_tool();
|
|
55629
55687
|
init_create_tool();
|
|
55630
55688
|
import * as fs29 from "fs";
|
|
55631
|
-
import * as
|
|
55689
|
+
import * as path43 from "path";
|
|
55632
55690
|
var EXT_MAP = {
|
|
55633
55691
|
python: ".py",
|
|
55634
55692
|
py: ".py",
|
|
@@ -55709,12 +55767,12 @@ var extract_code_blocks = createSwarmTool({
|
|
|
55709
55767
|
if (prefix) {
|
|
55710
55768
|
filename = `${prefix}_${filename}`;
|
|
55711
55769
|
}
|
|
55712
|
-
let filepath =
|
|
55713
|
-
const base =
|
|
55714
|
-
const ext =
|
|
55770
|
+
let filepath = path43.join(targetDir, filename);
|
|
55771
|
+
const base = path43.basename(filepath, path43.extname(filepath));
|
|
55772
|
+
const ext = path43.extname(filepath);
|
|
55715
55773
|
let counter = 1;
|
|
55716
55774
|
while (fs29.existsSync(filepath)) {
|
|
55717
|
-
filepath =
|
|
55775
|
+
filepath = path43.join(targetDir, `${base}_${counter}${ext}`);
|
|
55718
55776
|
counter++;
|
|
55719
55777
|
}
|
|
55720
55778
|
try {
|
|
@@ -55832,7 +55890,7 @@ var gitingest = tool({
|
|
|
55832
55890
|
// src/tools/imports.ts
|
|
55833
55891
|
init_dist();
|
|
55834
55892
|
import * as fs30 from "fs";
|
|
55835
|
-
import * as
|
|
55893
|
+
import * as path44 from "path";
|
|
55836
55894
|
var MAX_FILE_PATH_LENGTH2 = 500;
|
|
55837
55895
|
var MAX_SYMBOL_LENGTH = 256;
|
|
55838
55896
|
var MAX_FILE_SIZE_BYTES4 = 1024 * 1024;
|
|
@@ -55886,7 +55944,7 @@ function validateSymbolInput(symbol3) {
|
|
|
55886
55944
|
return null;
|
|
55887
55945
|
}
|
|
55888
55946
|
function isBinaryFile2(filePath, buffer) {
|
|
55889
|
-
const ext =
|
|
55947
|
+
const ext = path44.extname(filePath).toLowerCase();
|
|
55890
55948
|
if (ext === ".json" || ext === ".md" || ext === ".txt") {
|
|
55891
55949
|
return false;
|
|
55892
55950
|
}
|
|
@@ -55910,15 +55968,15 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
55910
55968
|
const imports = [];
|
|
55911
55969
|
let _resolvedTarget;
|
|
55912
55970
|
try {
|
|
55913
|
-
_resolvedTarget =
|
|
55971
|
+
_resolvedTarget = path44.resolve(targetFile);
|
|
55914
55972
|
} catch {
|
|
55915
55973
|
_resolvedTarget = targetFile;
|
|
55916
55974
|
}
|
|
55917
|
-
const targetBasename =
|
|
55975
|
+
const targetBasename = path44.basename(targetFile, path44.extname(targetFile));
|
|
55918
55976
|
const targetWithExt = targetFile;
|
|
55919
55977
|
const targetWithoutExt = targetFile.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
55920
|
-
const normalizedTargetWithExt =
|
|
55921
|
-
const normalizedTargetWithoutExt =
|
|
55978
|
+
const normalizedTargetWithExt = path44.normalize(targetWithExt).replace(/\\/g, "/");
|
|
55979
|
+
const normalizedTargetWithoutExt = path44.normalize(targetWithoutExt).replace(/\\/g, "/");
|
|
55922
55980
|
const importRegex = /import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
|
|
55923
55981
|
for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
|
|
55924
55982
|
const modulePath = match[1] || match[2] || match[3];
|
|
@@ -55941,9 +55999,9 @@ function parseImports(content, targetFile, targetSymbol) {
|
|
|
55941
55999
|
}
|
|
55942
56000
|
const _normalizedModule = modulePath.replace(/^\.\//, "").replace(/^\.\.\\/, "../");
|
|
55943
56001
|
let isMatch = false;
|
|
55944
|
-
const _targetDir =
|
|
55945
|
-
const targetExt =
|
|
55946
|
-
const targetBasenameNoExt =
|
|
56002
|
+
const _targetDir = path44.dirname(targetFile);
|
|
56003
|
+
const targetExt = path44.extname(targetFile);
|
|
56004
|
+
const targetBasenameNoExt = path44.basename(targetFile, targetExt);
|
|
55947
56005
|
const moduleNormalized = modulePath.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
55948
56006
|
const moduleName = modulePath.split(/[/\\]/).pop() || "";
|
|
55949
56007
|
const moduleNameNoExt = moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
|
|
@@ -56011,10 +56069,10 @@ function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFile
|
|
|
56011
56069
|
entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
|
|
56012
56070
|
for (const entry of entries) {
|
|
56013
56071
|
if (SKIP_DIRECTORIES2.has(entry)) {
|
|
56014
|
-
stats.skippedDirs.push(
|
|
56072
|
+
stats.skippedDirs.push(path44.join(dir, entry));
|
|
56015
56073
|
continue;
|
|
56016
56074
|
}
|
|
56017
|
-
const fullPath =
|
|
56075
|
+
const fullPath = path44.join(dir, entry);
|
|
56018
56076
|
let stat2;
|
|
56019
56077
|
try {
|
|
56020
56078
|
stat2 = fs30.statSync(fullPath);
|
|
@@ -56028,7 +56086,7 @@ function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFile
|
|
|
56028
56086
|
if (stat2.isDirectory()) {
|
|
56029
56087
|
findSourceFiles(fullPath, files, stats);
|
|
56030
56088
|
} else if (stat2.isFile()) {
|
|
56031
|
-
const ext =
|
|
56089
|
+
const ext = path44.extname(fullPath).toLowerCase();
|
|
56032
56090
|
if (SUPPORTED_EXTENSIONS.includes(ext)) {
|
|
56033
56091
|
files.push(fullPath);
|
|
56034
56092
|
}
|
|
@@ -56084,7 +56142,7 @@ var imports = tool({
|
|
|
56084
56142
|
return JSON.stringify(errorResult, null, 2);
|
|
56085
56143
|
}
|
|
56086
56144
|
try {
|
|
56087
|
-
const targetFile =
|
|
56145
|
+
const targetFile = path44.resolve(file3);
|
|
56088
56146
|
if (!fs30.existsSync(targetFile)) {
|
|
56089
56147
|
const errorResult = {
|
|
56090
56148
|
error: `target file not found: ${file3}`,
|
|
@@ -56106,7 +56164,7 @@ var imports = tool({
|
|
|
56106
56164
|
};
|
|
56107
56165
|
return JSON.stringify(errorResult, null, 2);
|
|
56108
56166
|
}
|
|
56109
|
-
const baseDir =
|
|
56167
|
+
const baseDir = path44.dirname(targetFile);
|
|
56110
56168
|
const scanStats = {
|
|
56111
56169
|
skippedDirs: [],
|
|
56112
56170
|
skippedFiles: 0,
|
|
@@ -56428,7 +56486,7 @@ init_config();
|
|
|
56428
56486
|
init_schema();
|
|
56429
56487
|
init_manager();
|
|
56430
56488
|
import * as fs31 from "fs";
|
|
56431
|
-
import * as
|
|
56489
|
+
import * as path45 from "path";
|
|
56432
56490
|
init_utils2();
|
|
56433
56491
|
init_create_tool();
|
|
56434
56492
|
function safeWarn(message, error93) {
|
|
@@ -56623,7 +56681,7 @@ async function executePhaseComplete(args2, workingDirectory) {
|
|
|
56623
56681
|
}
|
|
56624
56682
|
if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
|
|
56625
56683
|
try {
|
|
56626
|
-
const projectName =
|
|
56684
|
+
const projectName = path45.basename(dir);
|
|
56627
56685
|
const knowledgeConfig = {
|
|
56628
56686
|
enabled: true,
|
|
56629
56687
|
swarm_max_entries: 100,
|
|
@@ -56652,12 +56710,17 @@ async function executePhaseComplete(args2, workingDirectory) {
|
|
|
56652
56710
|
safeWarn("[phase_complete] Failed to curate lessons from retrospective:", error93);
|
|
56653
56711
|
}
|
|
56654
56712
|
}
|
|
56713
|
+
let complianceWarnings = [];
|
|
56655
56714
|
try {
|
|
56656
56715
|
const curatorConfig = CuratorConfigSchema.parse(config3.curator ?? {});
|
|
56657
56716
|
if (curatorConfig.enabled && curatorConfig.phase_enabled) {
|
|
56658
56717
|
const curatorResult = await runCuratorPhase(dir, phase, agentsDispatched, curatorConfig, {});
|
|
56659
56718
|
await applyCuratorKnowledgeUpdates(dir, curatorResult.knowledge_recommendations, {});
|
|
56660
56719
|
await runCriticDriftCheck(dir, phase, curatorResult, curatorConfig);
|
|
56720
|
+
if (curatorResult.compliance.length > 0 && !curatorConfig.suppress_warnings) {
|
|
56721
|
+
const complianceLines = curatorResult.compliance.map((obs) => `[${obs.severity.toUpperCase()}] ${obs.description}`).slice(0, 5);
|
|
56722
|
+
complianceWarnings = complianceLines;
|
|
56723
|
+
}
|
|
56661
56724
|
}
|
|
56662
56725
|
} catch (curatorError) {
|
|
56663
56726
|
safeWarn("[phase_complete] Curator pipeline error (non-blocking):", curatorError);
|
|
@@ -56743,6 +56806,9 @@ async function executePhaseComplete(args2, workingDirectory) {
|
|
|
56743
56806
|
warnings.push(`Warning: failed to update plan.json phase status: ${error93 instanceof Error ? error93.message : String(error93)}`);
|
|
56744
56807
|
}
|
|
56745
56808
|
}
|
|
56809
|
+
if (complianceWarnings.length > 0) {
|
|
56810
|
+
warnings.push(`Curator compliance: ${complianceWarnings.join("; ")}`);
|
|
56811
|
+
}
|
|
56746
56812
|
const result = {
|
|
56747
56813
|
success: success3,
|
|
56748
56814
|
phase,
|
|
@@ -56787,7 +56853,7 @@ init_discovery();
|
|
|
56787
56853
|
init_utils();
|
|
56788
56854
|
init_create_tool();
|
|
56789
56855
|
import * as fs32 from "fs";
|
|
56790
|
-
import * as
|
|
56856
|
+
import * as path46 from "path";
|
|
56791
56857
|
var MAX_OUTPUT_BYTES5 = 52428800;
|
|
56792
56858
|
var AUDIT_TIMEOUT_MS = 120000;
|
|
56793
56859
|
function isValidEcosystem(value) {
|
|
@@ -56805,16 +56871,16 @@ function validateArgs3(args2) {
|
|
|
56805
56871
|
function detectEcosystems(directory) {
|
|
56806
56872
|
const ecosystems = [];
|
|
56807
56873
|
const cwd = directory;
|
|
56808
|
-
if (fs32.existsSync(
|
|
56874
|
+
if (fs32.existsSync(path46.join(cwd, "package.json"))) {
|
|
56809
56875
|
ecosystems.push("npm");
|
|
56810
56876
|
}
|
|
56811
|
-
if (fs32.existsSync(
|
|
56877
|
+
if (fs32.existsSync(path46.join(cwd, "pyproject.toml")) || fs32.existsSync(path46.join(cwd, "requirements.txt"))) {
|
|
56812
56878
|
ecosystems.push("pip");
|
|
56813
56879
|
}
|
|
56814
|
-
if (fs32.existsSync(
|
|
56880
|
+
if (fs32.existsSync(path46.join(cwd, "Cargo.toml"))) {
|
|
56815
56881
|
ecosystems.push("cargo");
|
|
56816
56882
|
}
|
|
56817
|
-
if (fs32.existsSync(
|
|
56883
|
+
if (fs32.existsSync(path46.join(cwd, "go.mod"))) {
|
|
56818
56884
|
ecosystems.push("go");
|
|
56819
56885
|
}
|
|
56820
56886
|
try {
|
|
@@ -56823,10 +56889,10 @@ function detectEcosystems(directory) {
|
|
|
56823
56889
|
ecosystems.push("dotnet");
|
|
56824
56890
|
}
|
|
56825
56891
|
} catch {}
|
|
56826
|
-
if (fs32.existsSync(
|
|
56892
|
+
if (fs32.existsSync(path46.join(cwd, "Gemfile")) || fs32.existsSync(path46.join(cwd, "Gemfile.lock"))) {
|
|
56827
56893
|
ecosystems.push("ruby");
|
|
56828
56894
|
}
|
|
56829
|
-
if (fs32.existsSync(
|
|
56895
|
+
if (fs32.existsSync(path46.join(cwd, "pubspec.yaml"))) {
|
|
56830
56896
|
ecosystems.push("dart");
|
|
56831
56897
|
}
|
|
56832
56898
|
return ecosystems;
|
|
@@ -57889,7 +57955,7 @@ var SUPPORTED_PARSER_EXTENSIONS = new Set([
|
|
|
57889
57955
|
// src/tools/pre-check-batch.ts
|
|
57890
57956
|
init_dist();
|
|
57891
57957
|
import * as fs35 from "fs";
|
|
57892
|
-
import * as
|
|
57958
|
+
import * as path49 from "path";
|
|
57893
57959
|
|
|
57894
57960
|
// node_modules/yocto-queue/index.js
|
|
57895
57961
|
class Node2 {
|
|
@@ -58057,7 +58123,7 @@ init_manager();
|
|
|
58057
58123
|
|
|
58058
58124
|
// src/quality/metrics.ts
|
|
58059
58125
|
import * as fs33 from "fs";
|
|
58060
|
-
import * as
|
|
58126
|
+
import * as path47 from "path";
|
|
58061
58127
|
var MAX_FILE_SIZE_BYTES5 = 256 * 1024;
|
|
58062
58128
|
var MIN_DUPLICATION_LINES = 10;
|
|
58063
58129
|
function estimateCyclomaticComplexity(content) {
|
|
@@ -58109,7 +58175,7 @@ async function computeComplexityDelta(files, workingDir) {
|
|
|
58109
58175
|
let totalComplexity = 0;
|
|
58110
58176
|
const analyzedFiles = [];
|
|
58111
58177
|
for (const file3 of files) {
|
|
58112
|
-
const fullPath =
|
|
58178
|
+
const fullPath = path47.isAbsolute(file3) ? file3 : path47.join(workingDir, file3);
|
|
58113
58179
|
if (!fs33.existsSync(fullPath)) {
|
|
58114
58180
|
continue;
|
|
58115
58181
|
}
|
|
@@ -58232,7 +58298,7 @@ function countGoExports(content) {
|
|
|
58232
58298
|
function getExportCountForFile(filePath) {
|
|
58233
58299
|
try {
|
|
58234
58300
|
const content = fs33.readFileSync(filePath, "utf-8");
|
|
58235
|
-
const ext =
|
|
58301
|
+
const ext = path47.extname(filePath).toLowerCase();
|
|
58236
58302
|
switch (ext) {
|
|
58237
58303
|
case ".ts":
|
|
58238
58304
|
case ".tsx":
|
|
@@ -58258,7 +58324,7 @@ async function computePublicApiDelta(files, workingDir) {
|
|
|
58258
58324
|
let totalExports = 0;
|
|
58259
58325
|
const analyzedFiles = [];
|
|
58260
58326
|
for (const file3 of files) {
|
|
58261
|
-
const fullPath =
|
|
58327
|
+
const fullPath = path47.isAbsolute(file3) ? file3 : path47.join(workingDir, file3);
|
|
58262
58328
|
if (!fs33.existsSync(fullPath)) {
|
|
58263
58329
|
continue;
|
|
58264
58330
|
}
|
|
@@ -58292,7 +58358,7 @@ async function computeDuplicationRatio(files, workingDir) {
|
|
|
58292
58358
|
let duplicateLines = 0;
|
|
58293
58359
|
const analyzedFiles = [];
|
|
58294
58360
|
for (const file3 of files) {
|
|
58295
|
-
const fullPath =
|
|
58361
|
+
const fullPath = path47.isAbsolute(file3) ? file3 : path47.join(workingDir, file3);
|
|
58296
58362
|
if (!fs33.existsSync(fullPath)) {
|
|
58297
58363
|
continue;
|
|
58298
58364
|
}
|
|
@@ -58325,8 +58391,8 @@ function countCodeLines(content) {
|
|
|
58325
58391
|
return lines.length;
|
|
58326
58392
|
}
|
|
58327
58393
|
function isTestFile(filePath) {
|
|
58328
|
-
const basename8 =
|
|
58329
|
-
const _ext =
|
|
58394
|
+
const basename8 = path47.basename(filePath);
|
|
58395
|
+
const _ext = path47.extname(filePath).toLowerCase();
|
|
58330
58396
|
const testPatterns = [
|
|
58331
58397
|
".test.",
|
|
58332
58398
|
".spec.",
|
|
@@ -58407,8 +58473,8 @@ function matchGlobSegment(globSegments, pathSegments) {
|
|
|
58407
58473
|
}
|
|
58408
58474
|
return gIndex === globSegments.length && pIndex === pathSegments.length;
|
|
58409
58475
|
}
|
|
58410
|
-
function matchesGlobSegment(
|
|
58411
|
-
const normalizedPath =
|
|
58476
|
+
function matchesGlobSegment(path48, glob) {
|
|
58477
|
+
const normalizedPath = path48.replace(/\\/g, "/");
|
|
58412
58478
|
const normalizedGlob = glob.replace(/\\/g, "/");
|
|
58413
58479
|
if (normalizedPath.includes("//")) {
|
|
58414
58480
|
return false;
|
|
@@ -58439,8 +58505,8 @@ function simpleGlobToRegex2(glob) {
|
|
|
58439
58505
|
function hasGlobstar(glob) {
|
|
58440
58506
|
return glob.includes("**");
|
|
58441
58507
|
}
|
|
58442
|
-
function globMatches(
|
|
58443
|
-
const normalizedPath =
|
|
58508
|
+
function globMatches(path48, glob) {
|
|
58509
|
+
const normalizedPath = path48.replace(/\\/g, "/");
|
|
58444
58510
|
if (!glob || glob === "") {
|
|
58445
58511
|
if (normalizedPath.includes("//")) {
|
|
58446
58512
|
return false;
|
|
@@ -58476,7 +58542,7 @@ function shouldExcludeFile(filePath, excludeGlobs) {
|
|
|
58476
58542
|
async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
58477
58543
|
let testLines = 0;
|
|
58478
58544
|
let codeLines = 0;
|
|
58479
|
-
const srcDir =
|
|
58545
|
+
const srcDir = path47.join(workingDir, "src");
|
|
58480
58546
|
if (fs33.existsSync(srcDir)) {
|
|
58481
58547
|
await scanDirectoryForLines(srcDir, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
58482
58548
|
codeLines += lines;
|
|
@@ -58484,14 +58550,14 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
58484
58550
|
}
|
|
58485
58551
|
const possibleSrcDirs = ["lib", "app", "source", "core"];
|
|
58486
58552
|
for (const dir of possibleSrcDirs) {
|
|
58487
|
-
const dirPath =
|
|
58553
|
+
const dirPath = path47.join(workingDir, dir);
|
|
58488
58554
|
if (fs33.existsSync(dirPath)) {
|
|
58489
58555
|
await scanDirectoryForLines(dirPath, enforceGlobs, excludeGlobs, false, (lines) => {
|
|
58490
58556
|
codeLines += lines;
|
|
58491
58557
|
});
|
|
58492
58558
|
}
|
|
58493
58559
|
}
|
|
58494
|
-
const testsDir =
|
|
58560
|
+
const testsDir = path47.join(workingDir, "tests");
|
|
58495
58561
|
if (fs33.existsSync(testsDir)) {
|
|
58496
58562
|
await scanDirectoryForLines(testsDir, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
58497
58563
|
testLines += lines;
|
|
@@ -58499,7 +58565,7 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
|
|
|
58499
58565
|
}
|
|
58500
58566
|
const possibleTestDirs = ["test", "__tests__", "specs"];
|
|
58501
58567
|
for (const dir of possibleTestDirs) {
|
|
58502
|
-
const dirPath =
|
|
58568
|
+
const dirPath = path47.join(workingDir, dir);
|
|
58503
58569
|
if (fs33.existsSync(dirPath) && dirPath !== testsDir) {
|
|
58504
58570
|
await scanDirectoryForLines(dirPath, ["**"], ["node_modules", "dist"], true, (lines) => {
|
|
58505
58571
|
testLines += lines;
|
|
@@ -58514,7 +58580,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
58514
58580
|
try {
|
|
58515
58581
|
const entries = fs33.readdirSync(dirPath, { withFileTypes: true });
|
|
58516
58582
|
for (const entry of entries) {
|
|
58517
|
-
const fullPath =
|
|
58583
|
+
const fullPath = path47.join(dirPath, entry.name);
|
|
58518
58584
|
if (entry.isDirectory()) {
|
|
58519
58585
|
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === ".git") {
|
|
58520
58586
|
continue;
|
|
@@ -58522,7 +58588,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
|
|
|
58522
58588
|
await scanDirectoryForLines(fullPath, includeGlobs, excludeGlobs, isTestScan, callback);
|
|
58523
58589
|
} else if (entry.isFile()) {
|
|
58524
58590
|
const relativePath = fullPath.replace(`${process.cwd()}/`, "");
|
|
58525
|
-
const ext =
|
|
58591
|
+
const ext = path47.extname(entry.name).toLowerCase();
|
|
58526
58592
|
const validExts = [
|
|
58527
58593
|
".ts",
|
|
58528
58594
|
".tsx",
|
|
@@ -58773,7 +58839,7 @@ init_dist();
|
|
|
58773
58839
|
init_manager();
|
|
58774
58840
|
init_detector();
|
|
58775
58841
|
import * as fs34 from "fs";
|
|
58776
|
-
import * as
|
|
58842
|
+
import * as path48 from "path";
|
|
58777
58843
|
import { extname as extname9 } from "path";
|
|
58778
58844
|
|
|
58779
58845
|
// src/sast/rules/c.ts
|
|
@@ -59736,7 +59802,7 @@ async function sastScan(input, directory, config3) {
|
|
|
59736
59802
|
_filesSkipped++;
|
|
59737
59803
|
continue;
|
|
59738
59804
|
}
|
|
59739
|
-
const resolvedPath =
|
|
59805
|
+
const resolvedPath = path48.isAbsolute(filePath) ? filePath : path48.resolve(directory, filePath);
|
|
59740
59806
|
if (!fs34.existsSync(resolvedPath)) {
|
|
59741
59807
|
_filesSkipped++;
|
|
59742
59808
|
continue;
|
|
@@ -59935,18 +60001,18 @@ function validatePath(inputPath, baseDir, workspaceDir) {
|
|
|
59935
60001
|
let resolved;
|
|
59936
60002
|
const isWinAbs = isWindowsAbsolutePath(inputPath);
|
|
59937
60003
|
if (isWinAbs) {
|
|
59938
|
-
resolved =
|
|
59939
|
-
} else if (
|
|
59940
|
-
resolved =
|
|
60004
|
+
resolved = path49.win32.resolve(inputPath);
|
|
60005
|
+
} else if (path49.isAbsolute(inputPath)) {
|
|
60006
|
+
resolved = path49.resolve(inputPath);
|
|
59941
60007
|
} else {
|
|
59942
|
-
resolved =
|
|
60008
|
+
resolved = path49.resolve(baseDir, inputPath);
|
|
59943
60009
|
}
|
|
59944
|
-
const workspaceResolved =
|
|
60010
|
+
const workspaceResolved = path49.resolve(workspaceDir);
|
|
59945
60011
|
let relative5;
|
|
59946
60012
|
if (isWinAbs) {
|
|
59947
|
-
relative5 =
|
|
60013
|
+
relative5 = path49.win32.relative(workspaceResolved, resolved);
|
|
59948
60014
|
} else {
|
|
59949
|
-
relative5 =
|
|
60015
|
+
relative5 = path49.relative(workspaceResolved, resolved);
|
|
59950
60016
|
}
|
|
59951
60017
|
if (relative5.startsWith("..")) {
|
|
59952
60018
|
return "path traversal detected";
|
|
@@ -60007,13 +60073,13 @@ async function runLintWrapped(files, directory, _config) {
|
|
|
60007
60073
|
}
|
|
60008
60074
|
async function runLintOnFiles(linter, files, workspaceDir) {
|
|
60009
60075
|
const isWindows = process.platform === "win32";
|
|
60010
|
-
const binDir =
|
|
60076
|
+
const binDir = path49.join(workspaceDir, "node_modules", ".bin");
|
|
60011
60077
|
const validatedFiles = [];
|
|
60012
60078
|
for (const file3 of files) {
|
|
60013
60079
|
if (typeof file3 !== "string") {
|
|
60014
60080
|
continue;
|
|
60015
60081
|
}
|
|
60016
|
-
const resolvedPath =
|
|
60082
|
+
const resolvedPath = path49.resolve(file3);
|
|
60017
60083
|
const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
|
|
60018
60084
|
if (validationError) {
|
|
60019
60085
|
continue;
|
|
@@ -60031,10 +60097,10 @@ async function runLintOnFiles(linter, files, workspaceDir) {
|
|
|
60031
60097
|
}
|
|
60032
60098
|
let command;
|
|
60033
60099
|
if (linter === "biome") {
|
|
60034
|
-
const biomeBin = isWindows ?
|
|
60100
|
+
const biomeBin = isWindows ? path49.join(binDir, "biome.EXE") : path49.join(binDir, "biome");
|
|
60035
60101
|
command = [biomeBin, "check", ...validatedFiles];
|
|
60036
60102
|
} else {
|
|
60037
|
-
const eslintBin = isWindows ?
|
|
60103
|
+
const eslintBin = isWindows ? path49.join(binDir, "eslint.cmd") : path49.join(binDir, "eslint");
|
|
60038
60104
|
command = [eslintBin, ...validatedFiles];
|
|
60039
60105
|
}
|
|
60040
60106
|
try {
|
|
@@ -60171,7 +60237,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
60171
60237
|
skippedFiles++;
|
|
60172
60238
|
continue;
|
|
60173
60239
|
}
|
|
60174
|
-
const resolvedPath =
|
|
60240
|
+
const resolvedPath = path49.resolve(file3);
|
|
60175
60241
|
const validationError = validatePath(resolvedPath, directory, directory);
|
|
60176
60242
|
if (validationError) {
|
|
60177
60243
|
skippedFiles++;
|
|
@@ -60189,7 +60255,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
60189
60255
|
};
|
|
60190
60256
|
}
|
|
60191
60257
|
for (const file3 of validatedFiles) {
|
|
60192
|
-
const ext =
|
|
60258
|
+
const ext = path49.extname(file3).toLowerCase();
|
|
60193
60259
|
if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
|
|
60194
60260
|
skippedFiles++;
|
|
60195
60261
|
continue;
|
|
@@ -60348,7 +60414,7 @@ async function runPreCheckBatch(input, workspaceDir) {
|
|
|
60348
60414
|
warn(`pre_check_batch: Invalid file path: ${file3}`);
|
|
60349
60415
|
continue;
|
|
60350
60416
|
}
|
|
60351
|
-
changedFiles.push(
|
|
60417
|
+
changedFiles.push(path49.resolve(directory, file3));
|
|
60352
60418
|
}
|
|
60353
60419
|
if (changedFiles.length === 0) {
|
|
60354
60420
|
warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
|
|
@@ -60499,7 +60565,7 @@ var pre_check_batch = createSwarmTool({
|
|
|
60499
60565
|
};
|
|
60500
60566
|
return JSON.stringify(errorResult, null, 2);
|
|
60501
60567
|
}
|
|
60502
|
-
const resolvedDirectory =
|
|
60568
|
+
const resolvedDirectory = path49.resolve(typedArgs.directory);
|
|
60503
60569
|
const workspaceAnchor = resolvedDirectory;
|
|
60504
60570
|
const dirError = validateDirectory3(resolvedDirectory, workspaceAnchor);
|
|
60505
60571
|
if (dirError) {
|
|
@@ -60607,7 +60673,7 @@ init_tool();
|
|
|
60607
60673
|
init_manager2();
|
|
60608
60674
|
init_create_tool();
|
|
60609
60675
|
import * as fs36 from "fs";
|
|
60610
|
-
import * as
|
|
60676
|
+
import * as path50 from "path";
|
|
60611
60677
|
function detectPlaceholderContent(args2) {
|
|
60612
60678
|
const issues = [];
|
|
60613
60679
|
const placeholderPattern = /^\[\w[\w\s]*\]$/;
|
|
@@ -60711,7 +60777,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
60711
60777
|
try {
|
|
60712
60778
|
await savePlan(dir, plan);
|
|
60713
60779
|
try {
|
|
60714
|
-
const markerPath =
|
|
60780
|
+
const markerPath = path50.join(dir, ".swarm", ".plan-write-marker");
|
|
60715
60781
|
const marker = JSON.stringify({
|
|
60716
60782
|
source: "save_plan",
|
|
60717
60783
|
timestamp: new Date().toISOString(),
|
|
@@ -60723,7 +60789,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
60723
60789
|
return {
|
|
60724
60790
|
success: true,
|
|
60725
60791
|
message: "Plan saved successfully",
|
|
60726
|
-
plan_path:
|
|
60792
|
+
plan_path: path50.join(dir, ".swarm", "plan.json"),
|
|
60727
60793
|
phases_count: plan.phases.length,
|
|
60728
60794
|
tasks_count: tasksCount
|
|
60729
60795
|
};
|
|
@@ -60762,7 +60828,7 @@ var save_plan = createSwarmTool({
|
|
|
60762
60828
|
init_dist();
|
|
60763
60829
|
init_manager();
|
|
60764
60830
|
import * as fs37 from "fs";
|
|
60765
|
-
import * as
|
|
60831
|
+
import * as path51 from "path";
|
|
60766
60832
|
|
|
60767
60833
|
// src/sbom/detectors/index.ts
|
|
60768
60834
|
init_utils();
|
|
@@ -61610,7 +61676,7 @@ function findManifestFiles(rootDir) {
|
|
|
61610
61676
|
try {
|
|
61611
61677
|
const entries = fs37.readdirSync(dir, { withFileTypes: true });
|
|
61612
61678
|
for (const entry of entries) {
|
|
61613
|
-
const fullPath =
|
|
61679
|
+
const fullPath = path51.join(dir, entry.name);
|
|
61614
61680
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
|
|
61615
61681
|
continue;
|
|
61616
61682
|
}
|
|
@@ -61619,7 +61685,7 @@ function findManifestFiles(rootDir) {
|
|
|
61619
61685
|
} else if (entry.isFile()) {
|
|
61620
61686
|
for (const pattern of patterns) {
|
|
61621
61687
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
61622
|
-
manifestFiles.push(
|
|
61688
|
+
manifestFiles.push(path51.relative(rootDir, fullPath));
|
|
61623
61689
|
break;
|
|
61624
61690
|
}
|
|
61625
61691
|
}
|
|
@@ -61637,11 +61703,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
61637
61703
|
try {
|
|
61638
61704
|
const entries = fs37.readdirSync(dir, { withFileTypes: true });
|
|
61639
61705
|
for (const entry of entries) {
|
|
61640
|
-
const fullPath =
|
|
61706
|
+
const fullPath = path51.join(dir, entry.name);
|
|
61641
61707
|
if (entry.isFile()) {
|
|
61642
61708
|
for (const pattern of patterns) {
|
|
61643
61709
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
61644
|
-
found.push(
|
|
61710
|
+
found.push(path51.relative(workingDir, fullPath));
|
|
61645
61711
|
break;
|
|
61646
61712
|
}
|
|
61647
61713
|
}
|
|
@@ -61654,11 +61720,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
61654
61720
|
function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
|
|
61655
61721
|
const dirs = new Set;
|
|
61656
61722
|
for (const file3 of changedFiles) {
|
|
61657
|
-
let currentDir =
|
|
61723
|
+
let currentDir = path51.dirname(file3);
|
|
61658
61724
|
while (true) {
|
|
61659
|
-
if (currentDir && currentDir !== "." && currentDir !==
|
|
61660
|
-
dirs.add(
|
|
61661
|
-
const parent =
|
|
61725
|
+
if (currentDir && currentDir !== "." && currentDir !== path51.sep) {
|
|
61726
|
+
dirs.add(path51.join(workingDir, currentDir));
|
|
61727
|
+
const parent = path51.dirname(currentDir);
|
|
61662
61728
|
if (parent === currentDir)
|
|
61663
61729
|
break;
|
|
61664
61730
|
currentDir = parent;
|
|
@@ -61742,7 +61808,7 @@ var sbom_generate = createSwarmTool({
|
|
|
61742
61808
|
const changedFiles = obj.changed_files;
|
|
61743
61809
|
const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
|
|
61744
61810
|
const workingDir = directory;
|
|
61745
|
-
const outputDir =
|
|
61811
|
+
const outputDir = path51.isAbsolute(relativeOutputDir) ? relativeOutputDir : path51.join(workingDir, relativeOutputDir);
|
|
61746
61812
|
let manifestFiles = [];
|
|
61747
61813
|
if (scope === "all") {
|
|
61748
61814
|
manifestFiles = findManifestFiles(workingDir);
|
|
@@ -61765,7 +61831,7 @@ var sbom_generate = createSwarmTool({
|
|
|
61765
61831
|
const processedFiles = [];
|
|
61766
61832
|
for (const manifestFile of manifestFiles) {
|
|
61767
61833
|
try {
|
|
61768
|
-
const fullPath =
|
|
61834
|
+
const fullPath = path51.isAbsolute(manifestFile) ? manifestFile : path51.join(workingDir, manifestFile);
|
|
61769
61835
|
if (!fs37.existsSync(fullPath)) {
|
|
61770
61836
|
continue;
|
|
61771
61837
|
}
|
|
@@ -61782,7 +61848,7 @@ var sbom_generate = createSwarmTool({
|
|
|
61782
61848
|
const bom = generateCycloneDX(allComponents);
|
|
61783
61849
|
const bomJson = serializeCycloneDX(bom);
|
|
61784
61850
|
const filename = generateSbomFilename();
|
|
61785
|
-
const outputPath =
|
|
61851
|
+
const outputPath = path51.join(outputDir, filename);
|
|
61786
61852
|
fs37.writeFileSync(outputPath, bomJson, "utf-8");
|
|
61787
61853
|
const verdict = processedFiles.length > 0 ? "pass" : "pass";
|
|
61788
61854
|
try {
|
|
@@ -61826,7 +61892,7 @@ var sbom_generate = createSwarmTool({
|
|
|
61826
61892
|
init_dist();
|
|
61827
61893
|
init_create_tool();
|
|
61828
61894
|
import * as fs38 from "fs";
|
|
61829
|
-
import * as
|
|
61895
|
+
import * as path52 from "path";
|
|
61830
61896
|
var SPEC_CANDIDATES = [
|
|
61831
61897
|
"openapi.json",
|
|
61832
61898
|
"openapi.yaml",
|
|
@@ -61858,12 +61924,12 @@ function normalizePath2(p) {
|
|
|
61858
61924
|
}
|
|
61859
61925
|
function discoverSpecFile(cwd, specFileArg) {
|
|
61860
61926
|
if (specFileArg) {
|
|
61861
|
-
const resolvedPath =
|
|
61862
|
-
const normalizedCwd = cwd.endsWith(
|
|
61927
|
+
const resolvedPath = path52.resolve(cwd, specFileArg);
|
|
61928
|
+
const normalizedCwd = cwd.endsWith(path52.sep) ? cwd : cwd + path52.sep;
|
|
61863
61929
|
if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
|
|
61864
61930
|
throw new Error("Invalid spec_file: path traversal detected");
|
|
61865
61931
|
}
|
|
61866
|
-
const ext =
|
|
61932
|
+
const ext = path52.extname(resolvedPath).toLowerCase();
|
|
61867
61933
|
if (!ALLOWED_EXTENSIONS.includes(ext)) {
|
|
61868
61934
|
throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
|
|
61869
61935
|
}
|
|
@@ -61877,7 +61943,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
61877
61943
|
return resolvedPath;
|
|
61878
61944
|
}
|
|
61879
61945
|
for (const candidate of SPEC_CANDIDATES) {
|
|
61880
|
-
const candidatePath =
|
|
61946
|
+
const candidatePath = path52.resolve(cwd, candidate);
|
|
61881
61947
|
if (fs38.existsSync(candidatePath)) {
|
|
61882
61948
|
const stats = fs38.statSync(candidatePath);
|
|
61883
61949
|
if (stats.size <= MAX_SPEC_SIZE) {
|
|
@@ -61889,7 +61955,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
61889
61955
|
}
|
|
61890
61956
|
function parseSpec(specFile) {
|
|
61891
61957
|
const content = fs38.readFileSync(specFile, "utf-8");
|
|
61892
|
-
const ext =
|
|
61958
|
+
const ext = path52.extname(specFile).toLowerCase();
|
|
61893
61959
|
if (ext === ".json") {
|
|
61894
61960
|
return parseJsonSpec(content);
|
|
61895
61961
|
}
|
|
@@ -61965,7 +62031,7 @@ function extractRoutes(cwd) {
|
|
|
61965
62031
|
return;
|
|
61966
62032
|
}
|
|
61967
62033
|
for (const entry of entries) {
|
|
61968
|
-
const fullPath =
|
|
62034
|
+
const fullPath = path52.join(dir, entry.name);
|
|
61969
62035
|
if (entry.isSymbolicLink()) {
|
|
61970
62036
|
continue;
|
|
61971
62037
|
}
|
|
@@ -61975,7 +62041,7 @@ function extractRoutes(cwd) {
|
|
|
61975
62041
|
}
|
|
61976
62042
|
walkDir(fullPath);
|
|
61977
62043
|
} else if (entry.isFile()) {
|
|
61978
|
-
const ext =
|
|
62044
|
+
const ext = path52.extname(entry.name).toLowerCase();
|
|
61979
62045
|
const baseName = entry.name.toLowerCase();
|
|
61980
62046
|
if (![".ts", ".js", ".mjs"].includes(ext)) {
|
|
61981
62047
|
continue;
|
|
@@ -62145,7 +62211,7 @@ init_secretscan();
|
|
|
62145
62211
|
init_tool();
|
|
62146
62212
|
init_create_tool();
|
|
62147
62213
|
import * as fs39 from "fs";
|
|
62148
|
-
import * as
|
|
62214
|
+
import * as path53 from "path";
|
|
62149
62215
|
var MAX_FILE_SIZE_BYTES7 = 1024 * 1024;
|
|
62150
62216
|
var WINDOWS_RESERVED_NAMES = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
|
|
62151
62217
|
function containsControlCharacters(str) {
|
|
@@ -62174,11 +62240,11 @@ function containsWindowsAttacks(str) {
|
|
|
62174
62240
|
}
|
|
62175
62241
|
function isPathInWorkspace(filePath, workspace) {
|
|
62176
62242
|
try {
|
|
62177
|
-
const resolvedPath =
|
|
62243
|
+
const resolvedPath = path53.resolve(workspace, filePath);
|
|
62178
62244
|
const realWorkspace = fs39.realpathSync(workspace);
|
|
62179
62245
|
const realResolvedPath = fs39.realpathSync(resolvedPath);
|
|
62180
|
-
const relativePath =
|
|
62181
|
-
if (relativePath.startsWith("..") ||
|
|
62246
|
+
const relativePath = path53.relative(realWorkspace, realResolvedPath);
|
|
62247
|
+
if (relativePath.startsWith("..") || path53.isAbsolute(relativePath)) {
|
|
62182
62248
|
return false;
|
|
62183
62249
|
}
|
|
62184
62250
|
return true;
|
|
@@ -62190,7 +62256,7 @@ function validatePathForRead(filePath, workspace) {
|
|
|
62190
62256
|
return isPathInWorkspace(filePath, workspace);
|
|
62191
62257
|
}
|
|
62192
62258
|
function extractTSSymbols(filePath, cwd) {
|
|
62193
|
-
const fullPath =
|
|
62259
|
+
const fullPath = path53.join(cwd, filePath);
|
|
62194
62260
|
if (!validatePathForRead(fullPath, cwd)) {
|
|
62195
62261
|
return [];
|
|
62196
62262
|
}
|
|
@@ -62342,7 +62408,7 @@ function extractTSSymbols(filePath, cwd) {
|
|
|
62342
62408
|
});
|
|
62343
62409
|
}
|
|
62344
62410
|
function extractPythonSymbols(filePath, cwd) {
|
|
62345
|
-
const fullPath =
|
|
62411
|
+
const fullPath = path53.join(cwd, filePath);
|
|
62346
62412
|
if (!validatePathForRead(fullPath, cwd)) {
|
|
62347
62413
|
return [];
|
|
62348
62414
|
}
|
|
@@ -62425,7 +62491,7 @@ var symbols = createSwarmTool({
|
|
|
62425
62491
|
}, null, 2);
|
|
62426
62492
|
}
|
|
62427
62493
|
const cwd = directory;
|
|
62428
|
-
const ext =
|
|
62494
|
+
const ext = path53.extname(file3);
|
|
62429
62495
|
if (containsControlCharacters(file3)) {
|
|
62430
62496
|
return JSON.stringify({
|
|
62431
62497
|
file: file3,
|
|
@@ -62497,7 +62563,7 @@ init_dist();
|
|
|
62497
62563
|
init_utils();
|
|
62498
62564
|
init_create_tool();
|
|
62499
62565
|
import * as fs40 from "fs";
|
|
62500
|
-
import * as
|
|
62566
|
+
import * as path54 from "path";
|
|
62501
62567
|
var MAX_TEXT_LENGTH = 200;
|
|
62502
62568
|
var MAX_FILE_SIZE_BYTES8 = 1024 * 1024;
|
|
62503
62569
|
var SUPPORTED_EXTENSIONS2 = new Set([
|
|
@@ -62568,9 +62634,9 @@ function validatePathsInput(paths, cwd) {
|
|
|
62568
62634
|
return { error: "paths contains path traversal", resolvedPath: null };
|
|
62569
62635
|
}
|
|
62570
62636
|
try {
|
|
62571
|
-
const resolvedPath =
|
|
62572
|
-
const normalizedCwd =
|
|
62573
|
-
const normalizedResolved =
|
|
62637
|
+
const resolvedPath = path54.resolve(paths);
|
|
62638
|
+
const normalizedCwd = path54.resolve(cwd);
|
|
62639
|
+
const normalizedResolved = path54.resolve(resolvedPath);
|
|
62574
62640
|
if (!normalizedResolved.startsWith(normalizedCwd)) {
|
|
62575
62641
|
return {
|
|
62576
62642
|
error: "paths must be within the current working directory",
|
|
@@ -62586,7 +62652,7 @@ function validatePathsInput(paths, cwd) {
|
|
|
62586
62652
|
}
|
|
62587
62653
|
}
|
|
62588
62654
|
function isSupportedExtension(filePath) {
|
|
62589
|
-
const ext =
|
|
62655
|
+
const ext = path54.extname(filePath).toLowerCase();
|
|
62590
62656
|
return SUPPORTED_EXTENSIONS2.has(ext);
|
|
62591
62657
|
}
|
|
62592
62658
|
function findSourceFiles2(dir, files = []) {
|
|
@@ -62601,7 +62667,7 @@ function findSourceFiles2(dir, files = []) {
|
|
|
62601
62667
|
if (SKIP_DIRECTORIES3.has(entry)) {
|
|
62602
62668
|
continue;
|
|
62603
62669
|
}
|
|
62604
|
-
const fullPath =
|
|
62670
|
+
const fullPath = path54.join(dir, entry);
|
|
62605
62671
|
let stat2;
|
|
62606
62672
|
try {
|
|
62607
62673
|
stat2 = fs40.statSync(fullPath);
|
|
@@ -62713,7 +62779,7 @@ var todo_extract = createSwarmTool({
|
|
|
62713
62779
|
filesToScan.push(scanPath);
|
|
62714
62780
|
} else {
|
|
62715
62781
|
const errorResult = {
|
|
62716
|
-
error: `unsupported file extension: ${
|
|
62782
|
+
error: `unsupported file extension: ${path54.extname(scanPath)}`,
|
|
62717
62783
|
total: 0,
|
|
62718
62784
|
byPriority: { high: 0, medium: 0, low: 0 },
|
|
62719
62785
|
entries: []
|
|
@@ -62759,14 +62825,14 @@ var todo_extract = createSwarmTool({
|
|
|
62759
62825
|
init_tool();
|
|
62760
62826
|
init_schema();
|
|
62761
62827
|
import * as fs42 from "fs";
|
|
62762
|
-
import * as
|
|
62828
|
+
import * as path56 from "path";
|
|
62763
62829
|
|
|
62764
62830
|
// src/hooks/diff-scope.ts
|
|
62765
62831
|
import * as fs41 from "fs";
|
|
62766
|
-
import * as
|
|
62832
|
+
import * as path55 from "path";
|
|
62767
62833
|
function getDeclaredScope(taskId, directory) {
|
|
62768
62834
|
try {
|
|
62769
|
-
const planPath =
|
|
62835
|
+
const planPath = path55.join(directory, ".swarm", "plan.json");
|
|
62770
62836
|
if (!fs41.existsSync(planPath))
|
|
62771
62837
|
return null;
|
|
62772
62838
|
const raw = fs41.readFileSync(planPath, "utf-8");
|
|
@@ -62881,7 +62947,7 @@ var TIER_3_PATTERNS = [
|
|
|
62881
62947
|
];
|
|
62882
62948
|
function matchesTier3Pattern(files) {
|
|
62883
62949
|
for (const file3 of files) {
|
|
62884
|
-
const fileName =
|
|
62950
|
+
const fileName = path56.basename(file3);
|
|
62885
62951
|
for (const pattern of TIER_3_PATTERNS) {
|
|
62886
62952
|
if (pattern.test(fileName)) {
|
|
62887
62953
|
return true;
|
|
@@ -62903,7 +62969,7 @@ function checkReviewerGate(taskId, workingDirectory) {
|
|
|
62903
62969
|
if (hasActiveTurboMode2()) {
|
|
62904
62970
|
const resolvedDir2 = workingDirectory ?? process.cwd();
|
|
62905
62971
|
try {
|
|
62906
|
-
const planPath =
|
|
62972
|
+
const planPath = path56.join(resolvedDir2, ".swarm", "plan.json");
|
|
62907
62973
|
const planRaw = fs42.readFileSync(planPath, "utf-8");
|
|
62908
62974
|
const plan = JSON.parse(planRaw);
|
|
62909
62975
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -62923,7 +62989,7 @@ function checkReviewerGate(taskId, workingDirectory) {
|
|
|
62923
62989
|
}
|
|
62924
62990
|
const resolvedDir = workingDirectory ?? process.cwd();
|
|
62925
62991
|
try {
|
|
62926
|
-
const evidencePath =
|
|
62992
|
+
const evidencePath = path56.join(resolvedDir, ".swarm", "evidence", `${taskId}.json`);
|
|
62927
62993
|
const raw = fs42.readFileSync(evidencePath, "utf-8");
|
|
62928
62994
|
const evidence = JSON.parse(raw);
|
|
62929
62995
|
if (evidence?.required_gates && Array.isArray(evidence.required_gates) && evidence?.gates) {
|
|
@@ -62964,7 +63030,7 @@ function checkReviewerGate(taskId, workingDirectory) {
|
|
|
62964
63030
|
}
|
|
62965
63031
|
try {
|
|
62966
63032
|
const resolvedDir2 = workingDirectory ?? process.cwd();
|
|
62967
|
-
const planPath =
|
|
63033
|
+
const planPath = path56.join(resolvedDir2, ".swarm", "plan.json");
|
|
62968
63034
|
const planRaw = fs42.readFileSync(planPath, "utf-8");
|
|
62969
63035
|
const plan = JSON.parse(planRaw);
|
|
62970
63036
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -63146,8 +63212,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
63146
63212
|
};
|
|
63147
63213
|
}
|
|
63148
63214
|
}
|
|
63149
|
-
normalizedDir =
|
|
63150
|
-
const pathParts = normalizedDir.split(
|
|
63215
|
+
normalizedDir = path56.normalize(args2.working_directory);
|
|
63216
|
+
const pathParts = normalizedDir.split(path56.sep);
|
|
63151
63217
|
if (pathParts.includes("..")) {
|
|
63152
63218
|
return {
|
|
63153
63219
|
success: false,
|
|
@@ -63157,10 +63223,10 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
|
|
|
63157
63223
|
]
|
|
63158
63224
|
};
|
|
63159
63225
|
}
|
|
63160
|
-
const resolvedDir =
|
|
63226
|
+
const resolvedDir = path56.resolve(normalizedDir);
|
|
63161
63227
|
try {
|
|
63162
63228
|
const realPath = fs42.realpathSync(resolvedDir);
|
|
63163
|
-
const planPath =
|
|
63229
|
+
const planPath = path56.join(realPath, ".swarm", "plan.json");
|
|
63164
63230
|
if (!fs42.existsSync(planPath)) {
|
|
63165
63231
|
return {
|
|
63166
63232
|
success: false,
|
|
@@ -63355,7 +63421,7 @@ var OpenCodeSwarm = async (ctx) => {
|
|
|
63355
63421
|
const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
|
|
63356
63422
|
preflightTriggerManager = new PTM(automationConfig);
|
|
63357
63423
|
const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
|
|
63358
|
-
const swarmDir =
|
|
63424
|
+
const swarmDir = path57.resolve(ctx.directory, ".swarm");
|
|
63359
63425
|
statusArtifact = new ASA(swarmDir);
|
|
63360
63426
|
statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
|
|
63361
63427
|
if (automationConfig.capabilities?.evidence_auto_summaries === true) {
|