opencode-swarm 7.121.0 → 7.121.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.opencode/skills/commit-pr/SKILL.md +4 -0
- package/.opencode/skills/issue-ingest/SKILL.md +9 -7
- package/dist/cli/{curation-policy-re2kaysb.js → curation-policy-10wnhpwn.js} +2 -2
- package/dist/cli/{curator-llm-factory-jta9tggm.js → curator-llm-factory-vcyvbny0.js} +10 -10
- package/dist/cli/{curator-8m0pf9cz.js → curator-mwvrryf3.js} +10 -10
- package/dist/cli/{evidence-summary-service-jtx5q3r6.js → evidence-summary-service-k14ykm03.js} +2 -2
- package/dist/cli/{guardrail-explain-nsfm5ksb.js → guardrail-explain-tgkk87z5.js} +11 -11
- package/dist/cli/{hive-promoter-8303gnfk.js → hive-promoter-z4tw1gfv.js} +10 -10
- package/dist/cli/{index-rywkdacj.js → index-0f800qg7.js} +3 -3
- package/dist/cli/{index-3je67dcz.js → index-1y03193n.js} +1 -1
- package/dist/cli/{index-3ygv9535.js → index-2ygp3qq4.js} +11 -11
- package/dist/cli/{index-nhgw7de8.js → index-35xyj7gn.js} +1 -1
- package/dist/cli/{index-69ms9ny1.js → index-5a3xsnzg.js} +1 -1
- package/dist/cli/{index-3366gs26.js → index-db82jxt7.js} +2 -2
- package/dist/cli/{index-j5xv8zbp.js → index-emkb0bbe.js} +1 -1
- package/dist/cli/{index-0k4r8111.js → index-ft6jw816.js} +4 -4
- package/dist/cli/{index-0e1v02hq.js → index-j8349ac0.js} +1 -1
- package/dist/cli/{index-0mbmfmt0.js → index-qt2yaghg.js} +2 -1
- package/dist/cli/{index-fndvr7fr.js → index-rbfq77sz.js} +1 -1
- package/dist/cli/{index-78b192v7.js → index-x4fwtd59.js} +3 -3
- package/dist/cli/{index-gmc34yzt.js → index-y0qa3xf0.js} +770 -669
- package/dist/cli/index.js +10 -10
- package/dist/cli/{knowledge-escalator-0ejqs8c9.js → knowledge-escalator-8ajq1fhb.js} +3 -3
- package/dist/cli/{knowledge-events-wx9e37ba.js → knowledge-events-2sjy3aa7.js} +1 -1
- package/dist/cli/{knowledge-store-rnajx33a.js → knowledge-store-27cesthc.js} +1 -1
- package/dist/cli/{knowledge-validator-1f4mkzmc.js → knowledge-validator-9keh3p8j.js} +4 -4
- package/dist/cli/{scan-cursor-qapm0sxj.js → scan-cursor-qmsmmg1b.js} +2 -2
- package/dist/cli/{skill-generator-tkv7s12g.js → skill-generator-hkyxdc3j.js} +5 -5
- package/dist/commands/issue.d.ts +12 -0
- package/dist/config/plan-schema.d.ts +3 -0
- package/dist/hooks/delegation-gate.d.ts +120 -0
- package/dist/hooks/issue-trace-reducer.d.ts +66 -0
- package/dist/hooks/issue-trace-state.d.ts +64 -0
- package/dist/hooks/issue-trace.d.ts +31 -0
- package/dist/index.js +258 -232
- package/dist/tools/save-plan.d.ts +2 -0
- package/package.json +1 -1
|
@@ -65,7 +65,7 @@ import {
|
|
|
65
65
|
saveTaskSetSnapshot,
|
|
66
66
|
transientBackoff,
|
|
67
67
|
validateProjectRoot
|
|
68
|
-
} from "./index-
|
|
68
|
+
} from "./index-emkb0bbe.js";
|
|
69
69
|
import {
|
|
70
70
|
withTimeout
|
|
71
71
|
} from "./index-4905hd2m.js";
|
|
@@ -95,15 +95,15 @@ import {
|
|
|
95
95
|
retireSkill,
|
|
96
96
|
selectCandidateEntries,
|
|
97
97
|
syncBundledProjectSkillsIfMissingAsync
|
|
98
|
-
} from "./index-
|
|
98
|
+
} from "./index-x4fwtd59.js";
|
|
99
99
|
import {
|
|
100
100
|
readRecentEscalations
|
|
101
|
-
} from "./index-
|
|
101
|
+
} from "./index-ft6jw816.js";
|
|
102
102
|
import {
|
|
103
103
|
alreadyCuratedThisGeneration,
|
|
104
104
|
claimNextScanBatch,
|
|
105
105
|
resolveCohortId
|
|
106
|
-
} from "./index-
|
|
106
|
+
} from "./index-j8349ac0.js";
|
|
107
107
|
import {
|
|
108
108
|
CURATOR_INIT_PROMPT,
|
|
109
109
|
CURATOR_PHASE_PROMPT,
|
|
@@ -136,11 +136,11 @@ import {
|
|
|
136
136
|
validateActionability,
|
|
137
137
|
validateActionableFields,
|
|
138
138
|
validateLesson
|
|
139
|
-
} from "./index-
|
|
139
|
+
} from "./index-db82jxt7.js";
|
|
140
140
|
import {
|
|
141
141
|
authorizeCuration,
|
|
142
142
|
buildConfigFingerprintInput
|
|
143
|
-
} from "./index-
|
|
143
|
+
} from "./index-5a3xsnzg.js";
|
|
144
144
|
import {
|
|
145
145
|
cohortConfigFingerprint
|
|
146
146
|
} from "./index-rtry5xyf.js";
|
|
@@ -170,7 +170,7 @@ import {
|
|
|
170
170
|
transactFile,
|
|
171
171
|
transactKnowledge,
|
|
172
172
|
wordBigrams
|
|
173
|
-
} from "./index-
|
|
173
|
+
} from "./index-0f800qg7.js";
|
|
174
174
|
import {
|
|
175
175
|
MAX_EVENT_LOG_ENTRIES,
|
|
176
176
|
_internals,
|
|
@@ -180,7 +180,7 @@ import {
|
|
|
180
180
|
recordHiveKnowledgeEvent,
|
|
181
181
|
recordKnowledgeEvent,
|
|
182
182
|
resolveKnowledgeEventsPath
|
|
183
|
-
} from "./index-
|
|
183
|
+
} from "./index-35xyj7gn.js";
|
|
184
184
|
import {
|
|
185
185
|
resolveHiveDataDir,
|
|
186
186
|
resolveHiveEventsPath,
|
|
@@ -204,7 +204,7 @@ import {
|
|
|
204
204
|
import {
|
|
205
205
|
PlanSchema,
|
|
206
206
|
RetrospectiveEvidenceSchema
|
|
207
|
-
} from "./index-
|
|
207
|
+
} from "./index-qt2yaghg.js";
|
|
208
208
|
import {
|
|
209
209
|
AGENT_TOOL_MAP,
|
|
210
210
|
ALL_SUBAGENT_NAMES,
|
|
@@ -271,8 +271,8 @@ import {
|
|
|
271
271
|
} from "./index-a76rekgs.js";
|
|
272
272
|
|
|
273
273
|
// src/state.ts
|
|
274
|
-
import * as
|
|
275
|
-
import * as
|
|
274
|
+
import * as fs41 from "fs/promises";
|
|
275
|
+
import * as path80 from "path";
|
|
276
276
|
|
|
277
277
|
// src/db/qa-gate-profile.ts
|
|
278
278
|
import { createHash } from "crypto";
|
|
@@ -9759,7 +9759,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
|
|
|
9759
9759
|
}
|
|
9760
9760
|
if (config.skill_generation_enabled === true && skillCandidates.length > 0) {
|
|
9761
9761
|
try {
|
|
9762
|
-
const skillModule = await import("./skill-generator-
|
|
9762
|
+
const skillModule = await import("./skill-generator-hkyxdc3j.js");
|
|
9763
9763
|
for (const cand of skillCandidates) {
|
|
9764
9764
|
if (cand.confidence < (config.min_skill_confidence ?? DEFAULT_SKILL_MIN_CONFIDENCE)) {
|
|
9765
9765
|
continue;
|
|
@@ -10096,7 +10096,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
|
|
|
10096
10096
|
} catch {}
|
|
10097
10097
|
}
|
|
10098
10098
|
if (contradictedEntries.length > 0 && knowledgeConfig.contradiction_threshold_action === "quarantine") {
|
|
10099
|
-
const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-
|
|
10099
|
+
const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-8ajq1fhb.js");
|
|
10100
10100
|
for (const { id } of contradictedEntries) {
|
|
10101
10101
|
try {
|
|
10102
10102
|
await maybeQuarantineOnContradiction(directory, id, knowledgeConfig.contradiction_quarantine_threshold, knowledgeConfig.contradiction_quarantine_window_days);
|
|
@@ -10894,7 +10894,7 @@ async function runCuratorPostMortem(directory, options = {}) {
|
|
|
10894
10894
|
warnings.push("Failed to collect knowledge summary.");
|
|
10895
10895
|
}
|
|
10896
10896
|
try {
|
|
10897
|
-
const { getScanStatus } = await import("./scan-cursor-
|
|
10897
|
+
const { getScanStatus } = await import("./scan-cursor-qmsmmg1b.js");
|
|
10898
10898
|
const scanStatus = await getScanStatus(directory);
|
|
10899
10899
|
if (scanStatus.remaining_estimate > 0) {
|
|
10900
10900
|
warnings.push(`Fair scan: reviewed ${knowledgeSummary.length} entries this sweep (generation ${scanStatus.generation}); ${scanStatus.remaining_estimate} more eligible entries will be visited in future curation sweeps.`);
|
|
@@ -11068,7 +11068,7 @@ var _internals15 = {
|
|
|
11068
11068
|
loadDefaultKnowledgeConfig: async (directory) => {
|
|
11069
11069
|
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-vwxpsk6j.js");
|
|
11070
11070
|
try {
|
|
11071
|
-
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-
|
|
11071
|
+
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-rbfq77sz.js");
|
|
11072
11072
|
const loaded = loadPluginConfigWithMeta2(directory);
|
|
11073
11073
|
return KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
|
|
11074
11074
|
} catch {
|
|
@@ -11076,11 +11076,11 @@ var _internals15 = {
|
|
|
11076
11076
|
}
|
|
11077
11077
|
},
|
|
11078
11078
|
applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig, generation) => {
|
|
11079
|
-
const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-
|
|
11079
|
+
const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-mwvrryf3.js");
|
|
11080
11080
|
return applyCuratorKnowledgeUpdates2(directory, recommendations, knowledgeConfig, generation);
|
|
11081
11081
|
},
|
|
11082
11082
|
checkHivePromotions: async (entries, knowledgeConfig, directory) => {
|
|
11083
|
-
const { checkHivePromotions } = await import("./hive-promoter-
|
|
11083
|
+
const { checkHivePromotions } = await import("./hive-promoter-z4tw1gfv.js");
|
|
11084
11084
|
return checkHivePromotions(entries, knowledgeConfig, directory);
|
|
11085
11085
|
},
|
|
11086
11086
|
applyProposalTriage: async (directory, triage) => {
|
|
@@ -11089,7 +11089,7 @@ var _internals15 = {
|
|
|
11089
11089
|
activateProposal,
|
|
11090
11090
|
listSkills: listSkills2,
|
|
11091
11091
|
sanitizeSlug
|
|
11092
|
-
} = await import("./skill-generator-
|
|
11092
|
+
} = await import("./skill-generator-hkyxdc3j.js");
|
|
11093
11093
|
const result = {
|
|
11094
11094
|
approved: [],
|
|
11095
11095
|
rejected: [],
|
|
@@ -11278,14 +11278,14 @@ async function transactHiveStore(mutate) {
|
|
|
11278
11278
|
` : "");
|
|
11279
11279
|
await _internals16.atomicWriteFile(hivePath, content);
|
|
11280
11280
|
if (outcome.rejects && outcome.rejects.length > 0) {
|
|
11281
|
-
const rejectBlock = outcome.rejects.map((r) => JSON.stringify(r)).join(`
|
|
11282
|
-
`)
|
|
11281
|
+
const rejectBlock = `${outcome.rejects.map((r) => JSON.stringify(r)).join(`
|
|
11282
|
+
`)}
|
|
11283
11283
|
`;
|
|
11284
11284
|
await appendFile2(rejectedPath, rejectBlock, "utf-8");
|
|
11285
11285
|
}
|
|
11286
11286
|
if (outcome.audit && outcome.audit.length > 0) {
|
|
11287
|
-
const auditBlock = outcome.audit.map((a) => a.line).join(`
|
|
11288
|
-
`)
|
|
11287
|
+
const auditBlock = `${outcome.audit.map((a) => a.line).join(`
|
|
11288
|
+
`)}
|
|
11289
11289
|
`;
|
|
11290
11290
|
await appendFile2(eventsPath, auditBlock, "utf-8");
|
|
11291
11291
|
try {
|
|
@@ -13557,7 +13557,7 @@ function hashContent(content) {
|
|
|
13557
13557
|
async function loadConfigForPolicyCurator(directory) {
|
|
13558
13558
|
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-vwxpsk6j.js");
|
|
13559
13559
|
try {
|
|
13560
|
-
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-
|
|
13560
|
+
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-rbfq77sz.js");
|
|
13561
13561
|
const { config: loadedConfig } = loadPluginConfigWithMeta2(directory);
|
|
13562
13562
|
return KnowledgeConfigSchema2.parse(loadedConfig.knowledge ?? {});
|
|
13563
13563
|
} catch {
|
|
@@ -18867,8 +18867,8 @@ var _internals28 = {
|
|
|
18867
18867
|
loadCuratorDeps: async () => {
|
|
18868
18868
|
const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate: createCuratorLLMDelegate2 }] = await Promise.all([
|
|
18869
18869
|
import("./schema-vwxpsk6j.js"),
|
|
18870
|
-
import("./curator-
|
|
18871
|
-
import("./curator-llm-factory-
|
|
18870
|
+
import("./curator-mwvrryf3.js"),
|
|
18871
|
+
import("./curator-llm-factory-vcyvbny0.js")
|
|
18872
18872
|
]);
|
|
18873
18873
|
return { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 };
|
|
18874
18874
|
}
|
|
@@ -19366,7 +19366,7 @@ import { fileURLToPath } from "url";
|
|
|
19366
19366
|
// package.json
|
|
19367
19367
|
var package_default = {
|
|
19368
19368
|
name: "opencode-swarm",
|
|
19369
|
-
version: "7.121.
|
|
19369
|
+
version: "7.121.2",
|
|
19370
19370
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
19371
19371
|
main: "dist/index.js",
|
|
19372
19372
|
types: "dist/index.d.ts",
|
|
@@ -19806,7 +19806,7 @@ async function computeCurationDiagnostics(directory, entries) {
|
|
|
19806
19806
|
let scanCompleted = false;
|
|
19807
19807
|
let scanRemaining = 0;
|
|
19808
19808
|
try {
|
|
19809
|
-
const { getScanStatus } = await import("./scan-cursor-
|
|
19809
|
+
const { getScanStatus } = await import("./scan-cursor-qmsmmg1b.js");
|
|
19810
19810
|
const status = await getScanStatus(directory);
|
|
19811
19811
|
scanGeneration = status.generation;
|
|
19812
19812
|
scanCompleted = status.completed;
|
|
@@ -19819,14 +19819,14 @@ async function computeCurationDiagnostics(directory, entries) {
|
|
|
19819
19819
|
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-vwxpsk6j.js");
|
|
19820
19820
|
let config;
|
|
19821
19821
|
try {
|
|
19822
|
-
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-
|
|
19822
|
+
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-rbfq77sz.js");
|
|
19823
19823
|
const loaded = loadPluginConfigWithMeta2(directory);
|
|
19824
19824
|
config = KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
|
|
19825
19825
|
} catch {
|
|
19826
19826
|
config = KnowledgeConfigSchema2.parse({});
|
|
19827
19827
|
}
|
|
19828
19828
|
const { cohortConfigFingerprint: cohortConfigFingerprint2 } = await import("./config-fingerprint-v22xh5a2.js");
|
|
19829
|
-
const { buildConfigFingerprintInput: buildConfigFingerprintInput2, readCohortConfigFingerprint } = await import("./curation-policy-
|
|
19829
|
+
const { buildConfigFingerprintInput: buildConfigFingerprintInput2, readCohortConfigFingerprint } = await import("./curation-policy-10wnhpwn.js");
|
|
19830
19830
|
const currentFp = cohortConfigFingerprint2(buildConfigFingerprintInput2(config));
|
|
19831
19831
|
const cohortFp = await readCohortConfigFingerprint(directory);
|
|
19832
19832
|
configMatch = cohortFp === null ? null : currentFp === cohortFp;
|
|
@@ -21817,7 +21817,7 @@ async function handleEvidenceCommand(directory, args) {
|
|
|
21817
21817
|
return formatTaskEvidenceMarkdown(evidenceData);
|
|
21818
21818
|
}
|
|
21819
21819
|
async function handleEvidenceSummaryCommand(directory) {
|
|
21820
|
-
const { buildEvidenceSummary } = await import("./evidence-summary-service-
|
|
21820
|
+
const { buildEvidenceSummary } = await import("./evidence-summary-service-k14ykm03.js");
|
|
21821
21821
|
const artifact = await buildEvidenceSummary(directory);
|
|
21822
21822
|
if (!artifact) {
|
|
21823
21823
|
return "No plan found. Run `/swarm plan` to check plan status.";
|
|
@@ -27578,6 +27578,8 @@ async function handleHistoryCommand(directory, _args) {
|
|
|
27578
27578
|
return formatHistoryMarkdown(historyData);
|
|
27579
27579
|
}
|
|
27580
27580
|
// src/commands/issue.ts
|
|
27581
|
+
import * as fs24 from "fs";
|
|
27582
|
+
import * as path53 from "path";
|
|
27581
27583
|
var USAGE7 = [
|
|
27582
27584
|
"Usage: /swarm issue <url|owner/repo#N|N> [--plan] [--trace] [--no-repro]",
|
|
27583
27585
|
"",
|
|
@@ -27663,6 +27665,34 @@ function parseIssueRef(input, directory) {
|
|
|
27663
27665
|
}
|
|
27664
27666
|
return null;
|
|
27665
27667
|
}
|
|
27668
|
+
var _internals41 = {
|
|
27669
|
+
writeFileSync: fs24.writeFileSync,
|
|
27670
|
+
mkdirSync: fs24.mkdirSync,
|
|
27671
|
+
renameSync: fs24.renameSync,
|
|
27672
|
+
unlinkSync: fs24.unlinkSync,
|
|
27673
|
+
readFileSync: fs24.readFileSync,
|
|
27674
|
+
existsSync: fs24.existsSync
|
|
27675
|
+
};
|
|
27676
|
+
function atomicWriteFileSync(dir, filename, content) {
|
|
27677
|
+
const tmpPath = path53.join(dir, `.tmp-${filename}-${Date.now()}-${process.pid}`);
|
|
27678
|
+
const finalPath = path53.join(dir, filename);
|
|
27679
|
+
_internals41.writeFileSync(tmpPath, content, "utf-8");
|
|
27680
|
+
try {
|
|
27681
|
+
_internals41.renameSync(tmpPath, finalPath);
|
|
27682
|
+
} catch {
|
|
27683
|
+
try {
|
|
27684
|
+
_internals41.unlinkSync(finalPath);
|
|
27685
|
+
} catch {}
|
|
27686
|
+
try {
|
|
27687
|
+
_internals41.renameSync(tmpPath, finalPath);
|
|
27688
|
+
} catch (retryErr) {
|
|
27689
|
+
try {
|
|
27690
|
+
_internals41.unlinkSync(tmpPath);
|
|
27691
|
+
} catch {}
|
|
27692
|
+
throw retryErr;
|
|
27693
|
+
}
|
|
27694
|
+
}
|
|
27695
|
+
}
|
|
27666
27696
|
function handleIssueCommand(directory, args) {
|
|
27667
27697
|
const parsed = parseArgs8(args);
|
|
27668
27698
|
const rawInput = parsed.rest.join(" ").trim();
|
|
@@ -27681,6 +27711,57 @@ ${USAGE7}`;
|
|
|
27681
27711
|
if ("error" in result) {
|
|
27682
27712
|
return `Error: ${result.error}
|
|
27683
27713
|
|
|
27714
|
+
${USAGE7}`;
|
|
27715
|
+
}
|
|
27716
|
+
const swarmDir = path53.join(directory, ".swarm");
|
|
27717
|
+
const issueReference = {
|
|
27718
|
+
url: result.sanitized,
|
|
27719
|
+
owner: issueInfo.owner,
|
|
27720
|
+
repo: issueInfo.repo,
|
|
27721
|
+
number: issueInfo.number,
|
|
27722
|
+
timestamp: new Date().toISOString(),
|
|
27723
|
+
flags: {
|
|
27724
|
+
...parsed.plan && { plan: true },
|
|
27725
|
+
...parsed.trace && { trace: true },
|
|
27726
|
+
...parsed.noRepro && { noRepro: true }
|
|
27727
|
+
}
|
|
27728
|
+
};
|
|
27729
|
+
if (parsed.noRepro) {
|
|
27730
|
+
issueReference.noReproWaiver = {
|
|
27731
|
+
waived: true,
|
|
27732
|
+
reason: "--no-repro flag",
|
|
27733
|
+
timestamp: new Date().toISOString()
|
|
27734
|
+
};
|
|
27735
|
+
}
|
|
27736
|
+
const traceState = {
|
|
27737
|
+
issueNumber: issueInfo.number,
|
|
27738
|
+
lastTransition: null,
|
|
27739
|
+
completed: false
|
|
27740
|
+
};
|
|
27741
|
+
let oldTraceState = null;
|
|
27742
|
+
try {
|
|
27743
|
+
oldTraceState = _internals41.readFileSync(path53.join(swarmDir, "issue-trace-state.json"), "utf-8");
|
|
27744
|
+
} catch {}
|
|
27745
|
+
try {
|
|
27746
|
+
_internals41.mkdirSync(swarmDir, { recursive: true });
|
|
27747
|
+
atomicWriteFileSync(swarmDir, "issue-trace-state.json", JSON.stringify(traceState, null, 2));
|
|
27748
|
+
atomicWriteFileSync(swarmDir, "issue-reference.json", JSON.stringify(issueReference, null, 2));
|
|
27749
|
+
} catch (e) {
|
|
27750
|
+
if (oldTraceState !== null) {
|
|
27751
|
+
try {
|
|
27752
|
+
atomicWriteFileSync(swarmDir, "issue-trace-state.json", oldTraceState);
|
|
27753
|
+
} catch {}
|
|
27754
|
+
} else {
|
|
27755
|
+
try {
|
|
27756
|
+
_internals41.unlinkSync(path53.join(swarmDir, "issue-trace-state.json"));
|
|
27757
|
+
} catch {}
|
|
27758
|
+
}
|
|
27759
|
+
try {
|
|
27760
|
+
_internals41.unlinkSync(path53.join(swarmDir, "issue-reference.json"));
|
|
27761
|
+
} catch {}
|
|
27762
|
+
const errMsg = e instanceof Error ? e.message : String(e);
|
|
27763
|
+
return `Error: Failed to persist issue reference durably: ${errMsg}
|
|
27764
|
+
|
|
27684
27765
|
${USAGE7}`;
|
|
27685
27766
|
}
|
|
27686
27767
|
const flags = [];
|
|
@@ -27695,19 +27776,19 @@ ${USAGE7}`;
|
|
|
27695
27776
|
}
|
|
27696
27777
|
|
|
27697
27778
|
// src/commands/knowledge.ts
|
|
27698
|
-
import { join as
|
|
27779
|
+
import { join as join45 } from "path";
|
|
27699
27780
|
|
|
27700
27781
|
// src/hooks/knowledge-migrator.ts
|
|
27701
27782
|
init_logger();
|
|
27702
27783
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
27703
|
-
import { existsSync as
|
|
27784
|
+
import { existsSync as existsSync32, readFileSync as readFileSync21 } from "fs";
|
|
27704
27785
|
import { mkdir as mkdir12, readFile as readFile13, writeFile as writeFile11 } from "fs/promises";
|
|
27705
27786
|
import * as os9 from "os";
|
|
27706
|
-
import * as
|
|
27787
|
+
import * as path54 from "path";
|
|
27707
27788
|
async function migrateKnowledgeToExternal(_directory, _config) {
|
|
27708
|
-
const externalSentinelPath =
|
|
27709
|
-
const contextPath =
|
|
27710
|
-
if (
|
|
27789
|
+
const externalSentinelPath = path54.join(_directory, ".swarm", ".knowledge-external-migrated");
|
|
27790
|
+
const contextPath = path54.join(_directory, ".swarm", "context.md");
|
|
27791
|
+
if (_internals42.existsSync(externalSentinelPath)) {
|
|
27711
27792
|
return {
|
|
27712
27793
|
migrated: false,
|
|
27713
27794
|
entriesMigrated: 0,
|
|
@@ -27716,7 +27797,7 @@ async function migrateKnowledgeToExternal(_directory, _config) {
|
|
|
27716
27797
|
skippedReason: "external-sentinel-exists"
|
|
27717
27798
|
};
|
|
27718
27799
|
}
|
|
27719
|
-
if (!
|
|
27800
|
+
if (!_internals42.existsSync(contextPath)) {
|
|
27720
27801
|
return {
|
|
27721
27802
|
migrated: false,
|
|
27722
27803
|
entriesMigrated: 0,
|
|
@@ -27725,7 +27806,7 @@ async function migrateKnowledgeToExternal(_directory, _config) {
|
|
|
27725
27806
|
skippedReason: "no-context-file"
|
|
27726
27807
|
};
|
|
27727
27808
|
}
|
|
27728
|
-
const contextContent = await
|
|
27809
|
+
const contextContent = await _internals42.readFile(contextPath, "utf-8");
|
|
27729
27810
|
if (contextContent.trim().length === 0) {
|
|
27730
27811
|
return {
|
|
27731
27812
|
migrated: false,
|
|
@@ -27743,7 +27824,7 @@ async function migrateKnowledgeToExternal(_directory, _config) {
|
|
|
27743
27824
|
entriesCount++;
|
|
27744
27825
|
}
|
|
27745
27826
|
}
|
|
27746
|
-
await
|
|
27827
|
+
await _internals42.writeSentinel(externalSentinelPath, entriesCount, entriesCount);
|
|
27747
27828
|
return {
|
|
27748
27829
|
migrated: true,
|
|
27749
27830
|
entriesMigrated: entriesCount,
|
|
@@ -27751,7 +27832,7 @@ async function migrateKnowledgeToExternal(_directory, _config) {
|
|
|
27751
27832
|
entriesTotal: entriesCount
|
|
27752
27833
|
};
|
|
27753
27834
|
}
|
|
27754
|
-
var
|
|
27835
|
+
var _internals42 = {
|
|
27755
27836
|
appendKnowledge,
|
|
27756
27837
|
migrateContextToKnowledge,
|
|
27757
27838
|
migrateKnowledgeToExternal,
|
|
@@ -27764,17 +27845,17 @@ var _internals41 = {
|
|
|
27764
27845
|
inferProjectName,
|
|
27765
27846
|
writeSentinel,
|
|
27766
27847
|
resolveLegacyHiveKnowledgePath,
|
|
27767
|
-
existsSync:
|
|
27768
|
-
readFileSync:
|
|
27848
|
+
existsSync: existsSync32,
|
|
27849
|
+
readFileSync: readFileSync21,
|
|
27769
27850
|
readFile: readFile13,
|
|
27770
27851
|
mkdir: mkdir12,
|
|
27771
27852
|
writeFile: writeFile11
|
|
27772
27853
|
};
|
|
27773
27854
|
async function migrateContextToKnowledge(directory, config) {
|
|
27774
|
-
const sentinelPath =
|
|
27775
|
-
const contextPath =
|
|
27855
|
+
const sentinelPath = path54.join(directory, ".swarm", ".knowledge-migrated");
|
|
27856
|
+
const contextPath = path54.join(directory, ".swarm", "context.md");
|
|
27776
27857
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
27777
|
-
if (
|
|
27858
|
+
if (existsSync32(sentinelPath)) {
|
|
27778
27859
|
return {
|
|
27779
27860
|
migrated: false,
|
|
27780
27861
|
entriesMigrated: 0,
|
|
@@ -27783,7 +27864,7 @@ async function migrateContextToKnowledge(directory, config) {
|
|
|
27783
27864
|
skippedReason: "sentinel-exists"
|
|
27784
27865
|
};
|
|
27785
27866
|
}
|
|
27786
|
-
if (!
|
|
27867
|
+
if (!existsSync32(contextPath)) {
|
|
27787
27868
|
return {
|
|
27788
27869
|
migrated: false,
|
|
27789
27870
|
entriesMigrated: 0,
|
|
@@ -27802,9 +27883,9 @@ async function migrateContextToKnowledge(directory, config) {
|
|
|
27802
27883
|
skippedReason: "empty-context"
|
|
27803
27884
|
};
|
|
27804
27885
|
}
|
|
27805
|
-
const rawEntries =
|
|
27886
|
+
const rawEntries = _internals42.parseContextMd(contextContent);
|
|
27806
27887
|
if (rawEntries.length === 0) {
|
|
27807
|
-
await
|
|
27888
|
+
await _internals42.writeSentinel(sentinelPath, 0, 0);
|
|
27808
27889
|
return {
|
|
27809
27890
|
migrated: true,
|
|
27810
27891
|
entriesMigrated: 0,
|
|
@@ -27815,10 +27896,10 @@ async function migrateContextToKnowledge(directory, config) {
|
|
|
27815
27896
|
const existing = await readKnowledge(knowledgePath);
|
|
27816
27897
|
let migrated = 0;
|
|
27817
27898
|
let dropped = 0;
|
|
27818
|
-
const projectName =
|
|
27899
|
+
const projectName = _internals42.inferProjectName(directory);
|
|
27819
27900
|
for (const raw of rawEntries) {
|
|
27820
27901
|
if (config.validation_enabled !== false) {
|
|
27821
|
-
const category = raw.categoryHint ??
|
|
27902
|
+
const category = raw.categoryHint ?? _internals42.inferCategoryFromText(raw.text);
|
|
27822
27903
|
const result = validateLesson(raw.text, existing.map((e) => e.lesson), {
|
|
27823
27904
|
category,
|
|
27824
27905
|
scope: "global",
|
|
@@ -27838,8 +27919,8 @@ async function migrateContextToKnowledge(directory, config) {
|
|
|
27838
27919
|
const entry = {
|
|
27839
27920
|
id: randomUUID7(),
|
|
27840
27921
|
tier: "swarm",
|
|
27841
|
-
lesson:
|
|
27842
|
-
category: raw.categoryHint ??
|
|
27922
|
+
lesson: _internals42.truncateLesson(raw.text),
|
|
27923
|
+
category: raw.categoryHint ?? _internals42.inferCategoryFromText(raw.text),
|
|
27843
27924
|
tags: [...inferredTags, `migration:${raw.sourceSection}`],
|
|
27844
27925
|
scope: "global",
|
|
27845
27926
|
confidence: 0.3,
|
|
@@ -27862,7 +27943,7 @@ async function migrateContextToKnowledge(directory, config) {
|
|
|
27862
27943
|
if (migrated > 0) {
|
|
27863
27944
|
await rewriteKnowledge(knowledgePath, existing);
|
|
27864
27945
|
}
|
|
27865
|
-
await
|
|
27946
|
+
await _internals42.writeSentinel(sentinelPath, migrated, dropped);
|
|
27866
27947
|
log(`[knowledge-migrator] Migrated ${migrated} entries, dropped ${dropped}`);
|
|
27867
27948
|
return {
|
|
27868
27949
|
migrated: true,
|
|
@@ -27872,10 +27953,10 @@ async function migrateContextToKnowledge(directory, config) {
|
|
|
27872
27953
|
};
|
|
27873
27954
|
}
|
|
27874
27955
|
async function migrateHiveKnowledgeLegacy(config) {
|
|
27875
|
-
const legacyHivePath =
|
|
27956
|
+
const legacyHivePath = _internals42.resolveLegacyHiveKnowledgePath();
|
|
27876
27957
|
const canonicalHivePath = resolveHiveKnowledgePath2();
|
|
27877
|
-
const sentinelPath =
|
|
27878
|
-
if (
|
|
27958
|
+
const sentinelPath = path54.join(path54.dirname(canonicalHivePath), ".hive-knowledge-migrated");
|
|
27959
|
+
if (existsSync32(sentinelPath)) {
|
|
27879
27960
|
return {
|
|
27880
27961
|
migrated: false,
|
|
27881
27962
|
entriesMigrated: 0,
|
|
@@ -27884,7 +27965,7 @@ async function migrateHiveKnowledgeLegacy(config) {
|
|
|
27884
27965
|
skippedReason: "sentinel-exists"
|
|
27885
27966
|
};
|
|
27886
27967
|
}
|
|
27887
|
-
if (!
|
|
27968
|
+
if (!existsSync32(legacyHivePath)) {
|
|
27888
27969
|
return {
|
|
27889
27970
|
migrated: false,
|
|
27890
27971
|
entriesMigrated: 0,
|
|
@@ -27895,7 +27976,7 @@ async function migrateHiveKnowledgeLegacy(config) {
|
|
|
27895
27976
|
}
|
|
27896
27977
|
const legacyEntries = await readKnowledge(legacyHivePath);
|
|
27897
27978
|
if (legacyEntries.length === 0) {
|
|
27898
|
-
await
|
|
27979
|
+
await _internals42.writeSentinel(sentinelPath, 0, 0);
|
|
27899
27980
|
return {
|
|
27900
27981
|
migrated: true,
|
|
27901
27982
|
entriesMigrated: 0,
|
|
@@ -27943,7 +28024,7 @@ async function migrateHiveKnowledgeLegacy(config) {
|
|
|
27943
28024
|
const newHiveEntry = {
|
|
27944
28025
|
id: resolvedId,
|
|
27945
28026
|
tier: "hive",
|
|
27946
|
-
lesson:
|
|
28027
|
+
lesson: _internals42.truncateLesson(lesson),
|
|
27947
28028
|
category,
|
|
27948
28029
|
tags: ["migration:legacy-hive"],
|
|
27949
28030
|
scope: scopeTag,
|
|
@@ -27962,7 +28043,7 @@ async function migrateHiveKnowledgeLegacy(config) {
|
|
|
27962
28043
|
encounter_score: 1
|
|
27963
28044
|
};
|
|
27964
28045
|
try {
|
|
27965
|
-
await
|
|
28046
|
+
await _internals42.appendKnowledge(canonicalHivePath, newHiveEntry);
|
|
27966
28047
|
existingHiveEntries.push(newHiveEntry);
|
|
27967
28048
|
migrated++;
|
|
27968
28049
|
} catch (appendError) {
|
|
@@ -27978,7 +28059,7 @@ async function migrateHiveKnowledgeLegacy(config) {
|
|
|
27978
28059
|
dropped++;
|
|
27979
28060
|
}
|
|
27980
28061
|
}
|
|
27981
|
-
await
|
|
28062
|
+
await _internals42.writeSentinel(sentinelPath, migrated, dropped);
|
|
27982
28063
|
log(`[knowledge-migrator] Migrated ${migrated} legacy hive entries, dropped ${dropped}`);
|
|
27983
28064
|
return {
|
|
27984
28065
|
migrated: true,
|
|
@@ -27989,7 +28070,7 @@ async function migrateHiveKnowledgeLegacy(config) {
|
|
|
27989
28070
|
};
|
|
27990
28071
|
}
|
|
27991
28072
|
function parseContextMd(content) {
|
|
27992
|
-
const sections =
|
|
28073
|
+
const sections = _internals42.splitIntoSections(content);
|
|
27993
28074
|
const entries = [];
|
|
27994
28075
|
const seen = new Set;
|
|
27995
28076
|
const sectionPatterns = [
|
|
@@ -28005,7 +28086,7 @@ function parseContextMd(content) {
|
|
|
28005
28086
|
const match = sectionPatterns.find((sp) => sp.pattern.test(section.heading));
|
|
28006
28087
|
if (!match)
|
|
28007
28088
|
continue;
|
|
28008
|
-
const bullets =
|
|
28089
|
+
const bullets = _internals42.extractBullets(section.body);
|
|
28009
28090
|
for (const bullet of bullets) {
|
|
28010
28091
|
if (bullet.length < 15)
|
|
28011
28092
|
continue;
|
|
@@ -28014,9 +28095,9 @@ function parseContextMd(content) {
|
|
|
28014
28095
|
continue;
|
|
28015
28096
|
seen.add(normalized);
|
|
28016
28097
|
entries.push({
|
|
28017
|
-
text:
|
|
28098
|
+
text: _internals42.truncateLesson(bullet),
|
|
28018
28099
|
sourceSection: match.sourceSection,
|
|
28019
|
-
categoryHint:
|
|
28100
|
+
categoryHint: _internals42.inferCategoryFromText(bullet)
|
|
28020
28101
|
});
|
|
28021
28102
|
}
|
|
28022
28103
|
}
|
|
@@ -28085,16 +28166,16 @@ function truncateLesson2(text) {
|
|
|
28085
28166
|
return `${text.slice(0, 277)}...`;
|
|
28086
28167
|
}
|
|
28087
28168
|
function inferProjectName(directory) {
|
|
28088
|
-
const packageJsonPath =
|
|
28089
|
-
if (
|
|
28169
|
+
const packageJsonPath = path54.join(directory, "package.json");
|
|
28170
|
+
if (existsSync32(packageJsonPath)) {
|
|
28090
28171
|
try {
|
|
28091
|
-
const pkg = JSON.parse(
|
|
28172
|
+
const pkg = JSON.parse(readFileSync21(packageJsonPath, "utf-8"));
|
|
28092
28173
|
if (pkg.name && typeof pkg.name === "string") {
|
|
28093
28174
|
return pkg.name;
|
|
28094
28175
|
}
|
|
28095
28176
|
} catch {}
|
|
28096
28177
|
}
|
|
28097
|
-
return
|
|
28178
|
+
return path54.basename(directory);
|
|
28098
28179
|
}
|
|
28099
28180
|
async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
28100
28181
|
const sentinel = {
|
|
@@ -28106,21 +28187,21 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
|
28106
28187
|
schema_version: 1,
|
|
28107
28188
|
migration_tool: "knowledge-migrator.ts"
|
|
28108
28189
|
};
|
|
28109
|
-
await
|
|
28110
|
-
await
|
|
28190
|
+
await _internals42.mkdir(path54.dirname(sentinelPath), { recursive: true });
|
|
28191
|
+
await _internals42.writeFile(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
|
|
28111
28192
|
}
|
|
28112
28193
|
function resolveLegacyHiveKnowledgePath() {
|
|
28113
28194
|
const platform = process.platform;
|
|
28114
28195
|
const home = process.env.HOME || os9.homedir();
|
|
28115
28196
|
let dataDir;
|
|
28116
28197
|
if (platform === "win32") {
|
|
28117
|
-
dataDir =
|
|
28198
|
+
dataDir = path54.join(process.env.LOCALAPPDATA || path54.join(home, "AppData", "Local"), "opencode-swarm", "Data");
|
|
28118
28199
|
} else if (platform === "darwin") {
|
|
28119
|
-
dataDir =
|
|
28200
|
+
dataDir = path54.join(home, "Library", "Application Support", "opencode-swarm");
|
|
28120
28201
|
} else {
|
|
28121
|
-
dataDir =
|
|
28202
|
+
dataDir = path54.join(process.env.XDG_DATA_HOME || path54.join(home, ".local", "share"), "opencode-swarm");
|
|
28122
28203
|
}
|
|
28123
|
-
return
|
|
28204
|
+
return path54.join(dataDir, "hive-knowledge.jsonl");
|
|
28124
28205
|
}
|
|
28125
28206
|
|
|
28126
28207
|
// src/commands/knowledge.ts
|
|
@@ -28211,7 +28292,7 @@ async function handleKnowledgeRestoreCommand(directory, args) {
|
|
|
28211
28292
|
}
|
|
28212
28293
|
return `\u274C Entry ${fullId2} could not be unarchived${result.reason ? ` (${result.reason})` : ""}.`;
|
|
28213
28294
|
}
|
|
28214
|
-
const quarantinePath =
|
|
28295
|
+
const quarantinePath = join45(resolveKnowledgeStoreDir(directory), "knowledge-quarantined.jsonl");
|
|
28215
28296
|
const entries = await readKnowledge(quarantinePath);
|
|
28216
28297
|
const resolved = resolveEntryByPrefix(entries, inputId);
|
|
28217
28298
|
if ("error" in resolved) {
|
|
@@ -28519,7 +28600,7 @@ function timeoutMessage(timeoutMs) {
|
|
|
28519
28600
|
async function computeWithTimeout(directory, currentPhase, timeoutMs) {
|
|
28520
28601
|
const controller = new AbortController;
|
|
28521
28602
|
let timeout;
|
|
28522
|
-
const metricsPromise =
|
|
28603
|
+
const metricsPromise = _internals43.computeLearningMetrics(directory, {
|
|
28523
28604
|
currentPhase,
|
|
28524
28605
|
signal: controller.signal
|
|
28525
28606
|
});
|
|
@@ -28576,19 +28657,19 @@ ${JSON.stringify({
|
|
|
28576
28657
|
return `Error computing learning metrics: ${message}. Run /swarm diagnose to check .swarm/ health.`;
|
|
28577
28658
|
}
|
|
28578
28659
|
}
|
|
28579
|
-
var
|
|
28660
|
+
var _internals43 = {
|
|
28580
28661
|
computeLearningMetrics
|
|
28581
28662
|
};
|
|
28582
28663
|
|
|
28583
28664
|
// src/commands/link.ts
|
|
28584
28665
|
import { mkdir as mkdir14, writeFile as writeFile12 } from "fs/promises";
|
|
28585
|
-
import * as
|
|
28666
|
+
import * as path56 from "path";
|
|
28586
28667
|
|
|
28587
28668
|
// src/knowledge/family-migration.ts
|
|
28588
28669
|
var import_proper_lockfile5 = __toESM(require_proper_lockfile(), 1);
|
|
28589
|
-
import { existsSync as
|
|
28670
|
+
import { existsSync as existsSync33, readFileSync as readFileSync22 } from "fs";
|
|
28590
28671
|
import { mkdir as mkdir13 } from "fs/promises";
|
|
28591
|
-
import * as
|
|
28672
|
+
import * as path55 from "path";
|
|
28592
28673
|
|
|
28593
28674
|
// src/knowledge/family-manifest.ts
|
|
28594
28675
|
function reqStr(o, field) {
|
|
@@ -28693,10 +28774,10 @@ var MIGRATION_LOCK_RETRIES = {
|
|
|
28693
28774
|
retries: { retries: 10, minTimeout: 100, maxTimeout: 500 }
|
|
28694
28775
|
};
|
|
28695
28776
|
function readJsonl2(filePath) {
|
|
28696
|
-
if (!
|
|
28777
|
+
if (!existsSync33(filePath))
|
|
28697
28778
|
return [];
|
|
28698
28779
|
try {
|
|
28699
|
-
const content =
|
|
28780
|
+
const content = readFileSync22(filePath, "utf-8");
|
|
28700
28781
|
const out = [];
|
|
28701
28782
|
for (const line of content.split(`
|
|
28702
28783
|
`)) {
|
|
@@ -28713,10 +28794,10 @@ function readJsonl2(filePath) {
|
|
|
28713
28794
|
}
|
|
28714
28795
|
}
|
|
28715
28796
|
function readJson(filePath) {
|
|
28716
|
-
if (!
|
|
28797
|
+
if (!existsSync33(filePath))
|
|
28717
28798
|
return null;
|
|
28718
28799
|
try {
|
|
28719
|
-
return JSON.parse(
|
|
28800
|
+
return JSON.parse(readFileSync22(filePath, "utf-8"));
|
|
28720
28801
|
} catch {
|
|
28721
28802
|
return null;
|
|
28722
28803
|
}
|
|
@@ -28943,7 +29024,7 @@ function validateSerialized(member, serialized) {
|
|
|
28943
29024
|
return true;
|
|
28944
29025
|
}
|
|
28945
29026
|
function readSourceMember(member, sourceDir) {
|
|
28946
|
-
const filePath =
|
|
29027
|
+
const filePath = path55.join(sourceDir, member.filename);
|
|
28947
29028
|
if (member.mergeStrategy === "sum-counters") {
|
|
28948
29029
|
return readJson(filePath) ?? {};
|
|
28949
29030
|
}
|
|
@@ -29022,7 +29103,7 @@ async function migrateKnowledgeFamily(destinationDir, sourceDir) {
|
|
|
29022
29103
|
}
|
|
29023
29104
|
}
|
|
29024
29105
|
for (const { member, serialized } of staged) {
|
|
29025
|
-
const destPath =
|
|
29106
|
+
const destPath = path55.join(destinationDir, member.filename);
|
|
29026
29107
|
await atomicWriteFile(destPath, serialized);
|
|
29027
29108
|
}
|
|
29028
29109
|
} finally {
|
|
@@ -29111,7 +29192,7 @@ ${formatStatus(directory)}`;
|
|
|
29111
29192
|
let totalSkipped = 0;
|
|
29112
29193
|
let familySummary = "";
|
|
29113
29194
|
try {
|
|
29114
|
-
const result = await migrateKnowledgeFamily(linkDir,
|
|
29195
|
+
const result = await migrateKnowledgeFamily(linkDir, path56.join(directory, ".swarm"));
|
|
29115
29196
|
for (const m of result.perMember) {
|
|
29116
29197
|
totalMerged += m.merged;
|
|
29117
29198
|
totalSkipped += m.skipped;
|
|
@@ -29142,7 +29223,7 @@ ${formatStatus(directory)}`;
|
|
|
29142
29223
|
const config = KnowledgeConfigSchema.parse(loadedConfig.knowledge ?? {});
|
|
29143
29224
|
const fingerprint = cohortConfigFingerprint(buildConfigFingerprintInput(config));
|
|
29144
29225
|
await mkdir14(linkDir, { recursive: true });
|
|
29145
|
-
await writeFile12(
|
|
29226
|
+
await writeFile12(path56.join(linkDir, "cohort-config.json"), JSON.stringify({ fingerprint, updated_at: new Date().toISOString() }, null, 2), "utf-8");
|
|
29146
29227
|
} catch {}
|
|
29147
29228
|
const relinkNote = existing ? `
|
|
29148
29229
|
(Re-linked from previous link "${existing.linkId}".)` : "";
|
|
@@ -29168,7 +29249,7 @@ var MIN_MAX_CYCLES = 1;
|
|
|
29168
29249
|
var MAX_MAX_CYCLES = 5;
|
|
29169
29250
|
async function readLatestLoopState(directory) {
|
|
29170
29251
|
try {
|
|
29171
|
-
const { readdirSync: readdirSync7, statSync: statSync11, readFileSync:
|
|
29252
|
+
const { readdirSync: readdirSync7, statSync: statSync11, readFileSync: readFileSync23 } = await import("fs");
|
|
29172
29253
|
const loopDir = `${directory}/.swarm/loop`;
|
|
29173
29254
|
let latestMtime = 0;
|
|
29174
29255
|
let latestPath = null;
|
|
@@ -29191,14 +29272,14 @@ async function readLatestLoopState(directory) {
|
|
|
29191
29272
|
}
|
|
29192
29273
|
if (!latestPath)
|
|
29193
29274
|
return null;
|
|
29194
|
-
const raw =
|
|
29275
|
+
const raw = readFileSync23(latestPath, "utf-8");
|
|
29195
29276
|
const state = JSON.parse(raw);
|
|
29196
29277
|
return { autonomy: state.params?.autonomy };
|
|
29197
29278
|
} catch {
|
|
29198
29279
|
return null;
|
|
29199
29280
|
}
|
|
29200
29281
|
}
|
|
29201
|
-
var
|
|
29282
|
+
var _internals44 = {
|
|
29202
29283
|
readLatestLoopState
|
|
29203
29284
|
};
|
|
29204
29285
|
var USAGE8 = `Usage: /swarm loop <objective> [--max-cycles 1..5] [--autonomy checkpoint|auto] [--depth standard|exhaustive] [--resume]
|
|
@@ -29311,7 +29392,7 @@ ${USAGE8}`;
|
|
|
29311
29392
|
}
|
|
29312
29393
|
let autonomy = parsed.autonomy;
|
|
29313
29394
|
if (parsed.resume && !parsed.autonomyExplicit) {
|
|
29314
|
-
const state = await
|
|
29395
|
+
const state = await _internals44.readLatestLoopState(_directory);
|
|
29315
29396
|
if (state?.autonomy && AUTONOMY_LEVELS.has(state.autonomy)) {
|
|
29316
29397
|
autonomy = state.autonomy;
|
|
29317
29398
|
}
|
|
@@ -29324,13 +29405,13 @@ ${USAGE8}`;
|
|
|
29324
29405
|
}
|
|
29325
29406
|
|
|
29326
29407
|
// src/commands/memory.ts
|
|
29327
|
-
import { existsSync as
|
|
29328
|
-
import * as
|
|
29408
|
+
import { existsSync as existsSync34 } from "fs";
|
|
29409
|
+
import * as path59 from "path";
|
|
29329
29410
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
29330
29411
|
// src/memory/evaluation.ts
|
|
29331
|
-
import * as
|
|
29412
|
+
import * as fs25 from "fs/promises";
|
|
29332
29413
|
import * as os10 from "os";
|
|
29333
|
-
import * as
|
|
29414
|
+
import * as path57 from "path";
|
|
29334
29415
|
var DEFAULT_PROVIDERS = [
|
|
29335
29416
|
"local-jsonl",
|
|
29336
29417
|
"sqlite"
|
|
@@ -29342,7 +29423,7 @@ var DEFAULT_MODES = [
|
|
|
29342
29423
|
];
|
|
29343
29424
|
var DEFAULT_TIMESTAMP = "2026-05-26T12:00:00.000Z";
|
|
29344
29425
|
async function evaluateMemoryRecallFixtures(options) {
|
|
29345
|
-
const fixtureDirectory =
|
|
29426
|
+
const fixtureDirectory = path57.resolve(options.fixtureDirectory);
|
|
29346
29427
|
const providers = options.providers ?? DEFAULT_PROVIDERS;
|
|
29347
29428
|
const modes = options.modes ?? DEFAULT_MODES;
|
|
29348
29429
|
const generatedAt = new Date().toISOString();
|
|
@@ -29351,7 +29432,7 @@ async function evaluateMemoryRecallFixtures(options) {
|
|
|
29351
29432
|
for (const fixture of fixtures) {
|
|
29352
29433
|
const materialized = materializeFixture(fixture);
|
|
29353
29434
|
for (const providerName of providers) {
|
|
29354
|
-
const tempRoot = await
|
|
29435
|
+
const tempRoot = await fs25.realpath(await fs25.mkdtemp(path57.join(os10.tmpdir(), "swarm-memory-eval-")));
|
|
29355
29436
|
const provider = createEvaluationProvider(providerName, tempRoot);
|
|
29356
29437
|
try {
|
|
29357
29438
|
await provider.initialize?.();
|
|
@@ -29394,7 +29475,7 @@ async function evaluateMemoryRecallFixtures(options) {
|
|
|
29394
29475
|
async function rmTempRoot(tempRoot) {
|
|
29395
29476
|
for (let attempt = 0;attempt < 10; attempt++) {
|
|
29396
29477
|
try {
|
|
29397
|
-
await
|
|
29478
|
+
await fs25.rm(tempRoot, { recursive: true, force: true });
|
|
29398
29479
|
return;
|
|
29399
29480
|
} catch (err) {
|
|
29400
29481
|
if (attempt === 9)
|
|
@@ -29404,11 +29485,11 @@ async function rmTempRoot(tempRoot) {
|
|
|
29404
29485
|
}
|
|
29405
29486
|
}
|
|
29406
29487
|
async function loadRecallEvaluationFixtures(fixtureDirectory) {
|
|
29407
|
-
const entries = await
|
|
29488
|
+
const entries = await fs25.readdir(fixtureDirectory, { withFileTypes: true });
|
|
29408
29489
|
const files = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort((a, b) => a.localeCompare(b));
|
|
29409
29490
|
const fixtures = [];
|
|
29410
29491
|
for (const file of files) {
|
|
29411
|
-
const raw = await
|
|
29492
|
+
const raw = await fs25.readFile(path57.join(fixtureDirectory, file), "utf-8");
|
|
29412
29493
|
fixtures.push(validateFixture(JSON.parse(raw), file));
|
|
29413
29494
|
}
|
|
29414
29495
|
return fixtures;
|
|
@@ -29685,8 +29766,8 @@ var CuratorOutputMemoryDecisionSchema = exports_external.object({
|
|
|
29685
29766
|
}).passthrough();
|
|
29686
29767
|
// src/memory/consolidation-log.ts
|
|
29687
29768
|
import { appendFile as appendFile4, mkdir as mkdir15, readFile as readFile15 } from "fs/promises";
|
|
29688
|
-
import * as
|
|
29689
|
-
var LOG_RELATIVE_PATH =
|
|
29769
|
+
import * as path58 from "path";
|
|
29770
|
+
var LOG_RELATIVE_PATH = path58.join("memory", "consolidation-log.jsonl");
|
|
29690
29771
|
async function readConsolidationLog(directory) {
|
|
29691
29772
|
const filePath = validateSwarmPath(directory, LOG_RELATIVE_PATH);
|
|
29692
29773
|
let raw;
|
|
@@ -29709,7 +29790,7 @@ async function readConsolidationLog(directory) {
|
|
|
29709
29790
|
}
|
|
29710
29791
|
|
|
29711
29792
|
// src/commands/memory.ts
|
|
29712
|
-
var PACKAGE_ROOT =
|
|
29793
|
+
var PACKAGE_ROOT = path59.resolve(resolvePackageRootFromModule(fileURLToPath3(import.meta.url)));
|
|
29713
29794
|
async function handleMemoryCommand(_directory, _args) {
|
|
29714
29795
|
return [
|
|
29715
29796
|
"## Swarm Memory",
|
|
@@ -29768,7 +29849,7 @@ async function handleMemoryStatusCommand(directory, _args) {
|
|
|
29768
29849
|
`- Provider: \`${config.provider}\``,
|
|
29769
29850
|
`- Storage: \`${storageDir}\``,
|
|
29770
29851
|
`- SQLite path: \`${sqlitePath}\``,
|
|
29771
|
-
`- SQLite database exists: \`${
|
|
29852
|
+
`- SQLite database exists: \`${existsSync34(sqlitePath)}\``,
|
|
29772
29853
|
`- Automatic destructive cleanup: \`disabled\``,
|
|
29773
29854
|
"",
|
|
29774
29855
|
"### Legacy JSONL"
|
|
@@ -30066,7 +30147,7 @@ function resolveCommandMemoryConfig(directory) {
|
|
|
30066
30147
|
}
|
|
30067
30148
|
function parseEvaluateArgs(directory, args) {
|
|
30068
30149
|
let json = false;
|
|
30069
|
-
let fixtureDirectory =
|
|
30150
|
+
let fixtureDirectory = path59.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall");
|
|
30070
30151
|
for (let i = 0;i < args.length; i++) {
|
|
30071
30152
|
const arg = args[i];
|
|
30072
30153
|
if (arg === "--json") {
|
|
@@ -30080,10 +30161,10 @@ function parseEvaluateArgs(directory, args) {
|
|
|
30080
30161
|
error: "Usage: /swarm memory evaluate [--json] [--fixtures <directory>]"
|
|
30081
30162
|
};
|
|
30082
30163
|
}
|
|
30083
|
-
const resolvedFixtures =
|
|
30084
|
-
const canonical =
|
|
30085
|
-
const allowedRootA =
|
|
30086
|
-
const allowedRootB =
|
|
30164
|
+
const resolvedFixtures = path59.resolve(directory, next);
|
|
30165
|
+
const canonical = path59.normalize(resolvedFixtures) + path59.sep;
|
|
30166
|
+
const allowedRootA = path59.normalize(directory) + path59.sep;
|
|
30167
|
+
const allowedRootB = path59.normalize(path59.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall")) + path59.sep;
|
|
30087
30168
|
if (!canonical.startsWith(allowedRootA) && !canonical.startsWith(allowedRootB)) {
|
|
30088
30169
|
return {
|
|
30089
30170
|
error: "--fixtures <directory> must resolve under the project directory or the bundled tests/fixtures/memory-recall directory"
|
|
@@ -30122,15 +30203,15 @@ function parseMaintenanceArgs(args, options) {
|
|
|
30122
30203
|
return { limit, confirm };
|
|
30123
30204
|
}
|
|
30124
30205
|
function resolvePackageRootFromModule(modulePath) {
|
|
30125
|
-
const moduleDir =
|
|
30126
|
-
const leaf =
|
|
30206
|
+
const moduleDir = path59.dirname(modulePath);
|
|
30207
|
+
const leaf = path59.basename(moduleDir);
|
|
30127
30208
|
if (leaf === "commands" || leaf === "cli") {
|
|
30128
|
-
return
|
|
30209
|
+
return path59.resolve(moduleDir, "..", "..");
|
|
30129
30210
|
}
|
|
30130
30211
|
if (leaf === "dist") {
|
|
30131
|
-
return
|
|
30212
|
+
return path59.resolve(moduleDir, "..");
|
|
30132
30213
|
}
|
|
30133
|
-
return
|
|
30214
|
+
return path59.resolve(moduleDir, "..");
|
|
30134
30215
|
}
|
|
30135
30216
|
function formatMigrationResult(label, report) {
|
|
30136
30217
|
if (!report) {
|
|
@@ -30247,15 +30328,15 @@ function truncate(value, maxLength) {
|
|
|
30247
30328
|
}
|
|
30248
30329
|
|
|
30249
30330
|
// src/services/plan-service.ts
|
|
30250
|
-
var
|
|
30331
|
+
var _internals45 = {
|
|
30251
30332
|
loadPlanJsonOnly,
|
|
30252
30333
|
derivePlanMarkdown,
|
|
30253
30334
|
readSwarmFileAsync
|
|
30254
30335
|
};
|
|
30255
30336
|
async function getPlanData(directory, phaseArg) {
|
|
30256
|
-
const plan = await
|
|
30337
|
+
const plan = await _internals45.loadPlanJsonOnly(directory);
|
|
30257
30338
|
if (plan) {
|
|
30258
|
-
const fullMarkdown =
|
|
30339
|
+
const fullMarkdown = _internals45.derivePlanMarkdown(plan);
|
|
30259
30340
|
if (phaseArg === undefined || phaseArg === null || phaseArg === "") {
|
|
30260
30341
|
return {
|
|
30261
30342
|
hasPlan: true,
|
|
@@ -30298,7 +30379,7 @@ async function getPlanData(directory, phaseArg) {
|
|
|
30298
30379
|
isLegacy: false
|
|
30299
30380
|
};
|
|
30300
30381
|
}
|
|
30301
|
-
const planContent = await
|
|
30382
|
+
const planContent = await _internals45.readSwarmFileAsync(directory, "plan.md");
|
|
30302
30383
|
if (!planContent) {
|
|
30303
30384
|
return {
|
|
30304
30385
|
hasPlan: false,
|
|
@@ -30395,7 +30476,7 @@ async function handlePlanCommand(directory, args) {
|
|
|
30395
30476
|
return formatPlanMarkdown(planData);
|
|
30396
30477
|
}
|
|
30397
30478
|
// src/commands/post-mortem.ts
|
|
30398
|
-
var
|
|
30479
|
+
var _internals46 = {
|
|
30399
30480
|
createCuratorLLMDelegate,
|
|
30400
30481
|
runCuratorPostMortem
|
|
30401
30482
|
};
|
|
@@ -30443,10 +30524,10 @@ async function handlePostMortemCommand(directory, args, options) {
|
|
|
30443
30524
|
};
|
|
30444
30525
|
if (options?.sessionID) {
|
|
30445
30526
|
try {
|
|
30446
|
-
pmOptions.llmDelegate =
|
|
30527
|
+
pmOptions.llmDelegate = _internals46.createCuratorLLMDelegate(directory, "postmortem", options.sessionID);
|
|
30447
30528
|
} catch {}
|
|
30448
30529
|
}
|
|
30449
|
-
const result = await
|
|
30530
|
+
const result = await _internals46.runCuratorPostMortem(directory, pmOptions);
|
|
30450
30531
|
const lines = [];
|
|
30451
30532
|
if (result.success) {
|
|
30452
30533
|
lines.push("## Post-Mortem Report Generated");
|
|
@@ -30603,7 +30684,7 @@ function formatMergeGroupStatus(status, conclusion, htmlUrl) {
|
|
|
30603
30684
|
}
|
|
30604
30685
|
return parts.join(" ");
|
|
30605
30686
|
}
|
|
30606
|
-
var
|
|
30687
|
+
var _internals47 = {
|
|
30607
30688
|
formatRelativeTime,
|
|
30608
30689
|
formatMergeGroupStatus,
|
|
30609
30690
|
listActive,
|
|
@@ -30611,7 +30692,7 @@ var _internals46 = {
|
|
|
30611
30692
|
parseMergeGroupRuns
|
|
30612
30693
|
};
|
|
30613
30694
|
async function handlePrMonitorStatusCommand(directory, _args, sessionID, source) {
|
|
30614
|
-
const allActive = await
|
|
30695
|
+
const allActive = await _internals47.listActive(directory);
|
|
30615
30696
|
const allSessions = source === "cli";
|
|
30616
30697
|
const subs = allSessions ? allActive : allActive.filter((record) => record.sessionID === sessionID);
|
|
30617
30698
|
if (subs.length === 0) {
|
|
@@ -30627,7 +30708,7 @@ async function handlePrMonitorStatusCommand(directory, _args, sessionID, source)
|
|
|
30627
30708
|
const index = i + 1;
|
|
30628
30709
|
lines.push(` ${index}. ${sub.repoFullName}#${sub.prNumber}`);
|
|
30629
30710
|
lines.push(` URL: ${sub.prUrl}`);
|
|
30630
|
-
const mergeGroupRuns = await
|
|
30711
|
+
const mergeGroupRuns = await _internals47.listMergeGroupRuns(directory, sub.repoFullName, sub.prNumber);
|
|
30631
30712
|
if (mergeGroupRuns.runs.length > 0) {
|
|
30632
30713
|
lines.push(" Merge-group runs:");
|
|
30633
30714
|
for (const run of mergeGroupRuns.runs) {
|
|
@@ -30767,7 +30848,7 @@ async function handlePrSubscribeCommand(directory, args, sessionID) {
|
|
|
30767
30848
|
const repoFullName = `${prInfo.owner}/${prInfo.repo}`;
|
|
30768
30849
|
const prUrl = `https://github.com/${prInfo.owner}/${prInfo.repo}/pull/${prInfo.number}`;
|
|
30769
30850
|
try {
|
|
30770
|
-
const config =
|
|
30851
|
+
const config = _internals48.loadPluginConfig(directory);
|
|
30771
30852
|
const prMonitorConfig = config.pr_monitor;
|
|
30772
30853
|
if (!prMonitorConfig?.enabled) {
|
|
30773
30854
|
return [
|
|
@@ -30777,7 +30858,7 @@ async function handlePrSubscribeCommand(directory, args, sessionID) {
|
|
|
30777
30858
|
].join(`
|
|
30778
30859
|
`);
|
|
30779
30860
|
}
|
|
30780
|
-
await
|
|
30861
|
+
await _internals48.subscribe(directory, {
|
|
30781
30862
|
sessionID,
|
|
30782
30863
|
prNumber: prInfo.number,
|
|
30783
30864
|
repoFullName,
|
|
@@ -30805,7 +30886,7 @@ async function handlePrSubscribeCommand(directory, args, sessionID) {
|
|
|
30805
30886
|
`);
|
|
30806
30887
|
}
|
|
30807
30888
|
}
|
|
30808
|
-
var
|
|
30889
|
+
var _internals48 = {
|
|
30809
30890
|
loadPluginConfig,
|
|
30810
30891
|
subscribe
|
|
30811
30892
|
};
|
|
@@ -30828,9 +30909,9 @@ async function handlePrUnsubscribeCommand(directory, args, sessionID) {
|
|
|
30828
30909
|
`);
|
|
30829
30910
|
}
|
|
30830
30911
|
const refToken = rest[0];
|
|
30831
|
-
const prInfo =
|
|
30912
|
+
const prInfo = _internals49.parsePrRef(refToken, directory);
|
|
30832
30913
|
if (!prInfo) {
|
|
30833
|
-
if (
|
|
30914
|
+
if (_internals49.looksLikePrRef(refToken)) {
|
|
30834
30915
|
return [
|
|
30835
30916
|
`Error: Could not resolve PR reference from "${refToken}".`,
|
|
30836
30917
|
"",
|
|
@@ -30851,8 +30932,8 @@ async function handlePrUnsubscribeCommand(directory, args, sessionID) {
|
|
|
30851
30932
|
const repoFullName = `${prInfo.owner}/${prInfo.repo}`;
|
|
30852
30933
|
const prUrl = `https://github.com/${prInfo.owner}/${prInfo.repo}/pull/${prInfo.number}`;
|
|
30853
30934
|
try {
|
|
30854
|
-
const correlationId =
|
|
30855
|
-
const result = await
|
|
30935
|
+
const correlationId = _internals49.buildCorrelationId(sessionID, repoFullName, prInfo.number);
|
|
30936
|
+
const result = await _internals49.unsubscribe(directory, correlationId);
|
|
30856
30937
|
if (!result) {
|
|
30857
30938
|
return [
|
|
30858
30939
|
`Not subscribed to ${prUrl}`,
|
|
@@ -30879,7 +30960,7 @@ async function handlePrUnsubscribeCommand(directory, args, sessionID) {
|
|
|
30879
30960
|
`);
|
|
30880
30961
|
}
|
|
30881
30962
|
}
|
|
30882
|
-
var
|
|
30963
|
+
var _internals49 = {
|
|
30883
30964
|
unsubscribe,
|
|
30884
30965
|
buildCorrelationId,
|
|
30885
30966
|
parsePrRef,
|
|
@@ -30887,12 +30968,12 @@ var _internals48 = {
|
|
|
30887
30968
|
};
|
|
30888
30969
|
|
|
30889
30970
|
// src/services/preflight-service.ts
|
|
30890
|
-
import * as
|
|
30891
|
-
import * as
|
|
30971
|
+
import * as fs32 from "fs";
|
|
30972
|
+
import * as path66 from "path";
|
|
30892
30973
|
|
|
30893
30974
|
// src/tools/lint.ts
|
|
30894
|
-
import * as
|
|
30895
|
-
import * as
|
|
30975
|
+
import * as fs26 from "fs";
|
|
30976
|
+
import * as path60 from "path";
|
|
30896
30977
|
|
|
30897
30978
|
// src/utils/path-security.ts
|
|
30898
30979
|
function containsPathTraversal(str) {
|
|
@@ -30948,9 +31029,9 @@ function validateArgs(args) {
|
|
|
30948
31029
|
}
|
|
30949
31030
|
function getLinterCommand(linter, mode, projectDir) {
|
|
30950
31031
|
const isWindows = process.platform === "win32";
|
|
30951
|
-
const binDir =
|
|
30952
|
-
const biomeBin = isWindows ?
|
|
30953
|
-
const eslintBin = isWindows ?
|
|
31032
|
+
const binDir = path60.join(projectDir, "node_modules", ".bin");
|
|
31033
|
+
const biomeBin = isWindows ? path60.join(binDir, "biome.EXE") : path60.join(binDir, "biome");
|
|
31034
|
+
const eslintBin = isWindows ? path60.join(binDir, "eslint.cmd") : path60.join(binDir, "eslint");
|
|
30954
31035
|
switch (linter) {
|
|
30955
31036
|
case "biome":
|
|
30956
31037
|
if (mode === "fix") {
|
|
@@ -30966,7 +31047,7 @@ function getLinterCommand(linter, mode, projectDir) {
|
|
|
30966
31047
|
}
|
|
30967
31048
|
function getAdditionalLinterCommand(linter, mode, cwd) {
|
|
30968
31049
|
const gradlewName = process.platform === "win32" ? "gradlew.bat" : "gradlew";
|
|
30969
|
-
const gradlew =
|
|
31050
|
+
const gradlew = fs26.existsSync(path60.join(cwd, gradlewName)) ? path60.join(cwd, gradlewName) : null;
|
|
30970
31051
|
switch (linter) {
|
|
30971
31052
|
case "ruff":
|
|
30972
31053
|
return mode === "fix" ? ["ruff", "check", "--fix", "."] : ["ruff", "check", "."];
|
|
@@ -31008,12 +31089,12 @@ function getAdditionalLinterCommand(linter, mode, cwd) {
|
|
|
31008
31089
|
}
|
|
31009
31090
|
}
|
|
31010
31091
|
function detectRuff(cwd) {
|
|
31011
|
-
if (
|
|
31092
|
+
if (fs26.existsSync(path60.join(cwd, "ruff.toml")))
|
|
31012
31093
|
return isCommandAvailable("ruff");
|
|
31013
31094
|
try {
|
|
31014
|
-
const pyproject =
|
|
31015
|
-
if (
|
|
31016
|
-
const content =
|
|
31095
|
+
const pyproject = path60.join(cwd, "pyproject.toml");
|
|
31096
|
+
if (fs26.existsSync(pyproject)) {
|
|
31097
|
+
const content = fs26.readFileSync(pyproject, "utf-8");
|
|
31017
31098
|
if (content.includes("[tool.ruff]"))
|
|
31018
31099
|
return isCommandAvailable("ruff");
|
|
31019
31100
|
}
|
|
@@ -31021,67 +31102,67 @@ function detectRuff(cwd) {
|
|
|
31021
31102
|
return false;
|
|
31022
31103
|
}
|
|
31023
31104
|
function detectClippy(cwd) {
|
|
31024
|
-
return
|
|
31105
|
+
return fs26.existsSync(path60.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
|
|
31025
31106
|
}
|
|
31026
31107
|
function detectGolangciLint(cwd) {
|
|
31027
|
-
return
|
|
31108
|
+
return fs26.existsSync(path60.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
|
|
31028
31109
|
}
|
|
31029
31110
|
function readTextFileSafe(filePath) {
|
|
31030
31111
|
try {
|
|
31031
|
-
return
|
|
31112
|
+
return fs26.readFileSync(filePath, "utf-8");
|
|
31032
31113
|
} catch {
|
|
31033
31114
|
return "";
|
|
31034
31115
|
}
|
|
31035
31116
|
}
|
|
31036
31117
|
function phpVendorBin(_cwd, name) {
|
|
31037
31118
|
const fileName = process.platform === "win32" ? `${name}.bat` : name;
|
|
31038
|
-
return
|
|
31119
|
+
return path60.join("vendor", "bin", fileName);
|
|
31039
31120
|
}
|
|
31040
31121
|
function phpVendorBinExists(cwd, name) {
|
|
31041
|
-
const local =
|
|
31042
|
-
const localWin =
|
|
31043
|
-
return
|
|
31122
|
+
const local = path60.join(cwd, "vendor", "bin", name);
|
|
31123
|
+
const localWin = path60.join(cwd, "vendor", "bin", `${name}.bat`);
|
|
31124
|
+
return fs26.existsSync(local) || fs26.existsSync(localWin);
|
|
31044
31125
|
}
|
|
31045
31126
|
function detectCheckstyle(cwd) {
|
|
31046
|
-
const hasMaven =
|
|
31047
|
-
const gradleFiles = ["build.gradle", "build.gradle.kts"].map((file) =>
|
|
31048
|
-
const hasGradleCheckstyleSignal =
|
|
31049
|
-
const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradleCheckstyleSignal && (
|
|
31127
|
+
const hasMaven = fs26.existsSync(path60.join(cwd, "pom.xml"));
|
|
31128
|
+
const gradleFiles = ["build.gradle", "build.gradle.kts"].map((file) => path60.join(cwd, file)).filter((file) => fs26.existsSync(file));
|
|
31129
|
+
const hasGradleCheckstyleSignal = fs26.existsSync(path60.join(cwd, "checkstyle.xml")) || fs26.existsSync(path60.join(cwd, "config", "checkstyle", "checkstyle.xml")) || gradleFiles.some((file) => /\bcheckstyle\b/i.test(readTextFileSafe(file)));
|
|
31130
|
+
const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradleCheckstyleSignal && (fs26.existsSync(path60.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
|
|
31050
31131
|
return (hasMaven || hasGradleCheckstyleSignal) && hasBinary;
|
|
31051
31132
|
}
|
|
31052
31133
|
function hasRootKotlinFile(cwd) {
|
|
31053
31134
|
try {
|
|
31054
|
-
return
|
|
31135
|
+
return fs26.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
|
|
31055
31136
|
} catch {
|
|
31056
31137
|
return false;
|
|
31057
31138
|
}
|
|
31058
31139
|
}
|
|
31059
31140
|
function buildGradleHasKotlinSignal(cwd) {
|
|
31060
|
-
const content = readTextFileSafe(
|
|
31141
|
+
const content = readTextFileSafe(path60.join(cwd, "build.gradle"));
|
|
31061
31142
|
return /\b(kotlin|org\.jetbrains\.kotlin|ktlint)\b/i.test(content);
|
|
31062
31143
|
}
|
|
31063
31144
|
function detectKtlint(cwd) {
|
|
31064
|
-
const hasKotlin =
|
|
31145
|
+
const hasKotlin = fs26.existsSync(path60.join(cwd, "build.gradle.kts")) || fs26.existsSync(path60.join(cwd, "build.gradle")) && buildGradleHasKotlinSignal(cwd) || hasRootKotlinFile(cwd);
|
|
31065
31146
|
return hasKotlin && isCommandAvailable("ktlint");
|
|
31066
31147
|
}
|
|
31067
31148
|
function detectPhpLinter(cwd) {
|
|
31068
|
-
if ((
|
|
31149
|
+
if ((fs26.existsSync(path60.join(cwd, "phpstan.neon")) || fs26.existsSync(path60.join(cwd, "phpstan.neon.dist"))) && phpVendorBinExists(cwd, "phpstan")) {
|
|
31069
31150
|
return "phpstan";
|
|
31070
31151
|
}
|
|
31071
|
-
if (
|
|
31152
|
+
if (fs26.existsSync(path60.join(cwd, "pint.json")) && phpVendorBinExists(cwd, "pint")) {
|
|
31072
31153
|
return "pint";
|
|
31073
31154
|
}
|
|
31074
|
-
if (
|
|
31155
|
+
if (fs26.existsSync(path60.join(cwd, ".php-cs-fixer.php")) && phpVendorBinExists(cwd, "php-cs-fixer")) {
|
|
31075
31156
|
return "php-cs-fixer";
|
|
31076
31157
|
}
|
|
31077
|
-
if (
|
|
31158
|
+
if (fs26.existsSync(path60.join(cwd, "phpcs.xml")) && phpVendorBinExists(cwd, "phpcs")) {
|
|
31078
31159
|
return "phpcs";
|
|
31079
31160
|
}
|
|
31080
31161
|
return null;
|
|
31081
31162
|
}
|
|
31082
31163
|
function detectDotnetFormat(cwd) {
|
|
31083
31164
|
try {
|
|
31084
|
-
const files =
|
|
31165
|
+
const files = fs26.readdirSync(cwd);
|
|
31085
31166
|
const hasCsproj = files.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"));
|
|
31086
31167
|
return hasCsproj && isCommandAvailable("dotnet");
|
|
31087
31168
|
} catch {
|
|
@@ -31089,14 +31170,14 @@ function detectDotnetFormat(cwd) {
|
|
|
31089
31170
|
}
|
|
31090
31171
|
}
|
|
31091
31172
|
function detectCppcheck(cwd) {
|
|
31092
|
-
if (
|
|
31173
|
+
if (fs26.existsSync(path60.join(cwd, "CMakeLists.txt"))) {
|
|
31093
31174
|
return isCommandAvailable("cppcheck");
|
|
31094
31175
|
}
|
|
31095
31176
|
try {
|
|
31096
|
-
const dirsToCheck = [cwd,
|
|
31177
|
+
const dirsToCheck = [cwd, path60.join(cwd, "src")];
|
|
31097
31178
|
const hasCpp = dirsToCheck.some((dir) => {
|
|
31098
31179
|
try {
|
|
31099
|
-
return
|
|
31180
|
+
return fs26.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
|
|
31100
31181
|
} catch {
|
|
31101
31182
|
return false;
|
|
31102
31183
|
}
|
|
@@ -31107,13 +31188,13 @@ function detectCppcheck(cwd) {
|
|
|
31107
31188
|
}
|
|
31108
31189
|
}
|
|
31109
31190
|
function detectSwiftlint(cwd) {
|
|
31110
|
-
return
|
|
31191
|
+
return fs26.existsSync(path60.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
|
|
31111
31192
|
}
|
|
31112
31193
|
function detectDartAnalyze(cwd) {
|
|
31113
|
-
return
|
|
31194
|
+
return fs26.existsSync(path60.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
|
|
31114
31195
|
}
|
|
31115
31196
|
function detectRubocop(cwd) {
|
|
31116
|
-
return (
|
|
31197
|
+
return (fs26.existsSync(path60.join(cwd, "Gemfile")) || fs26.existsSync(path60.join(cwd, "gems.rb")) || fs26.existsSync(path60.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
|
|
31117
31198
|
}
|
|
31118
31199
|
function detectAdditionalLinter(cwd) {
|
|
31119
31200
|
if (detectRuff(cwd))
|
|
@@ -31144,10 +31225,10 @@ function detectAdditionalLinter(cwd) {
|
|
|
31144
31225
|
function findBinInAncestors(startDir, binName) {
|
|
31145
31226
|
let dir = startDir;
|
|
31146
31227
|
while (true) {
|
|
31147
|
-
const candidate =
|
|
31148
|
-
if (
|
|
31228
|
+
const candidate = path60.join(dir, "node_modules", ".bin", binName);
|
|
31229
|
+
if (fs26.existsSync(candidate))
|
|
31149
31230
|
return candidate;
|
|
31150
|
-
const parent =
|
|
31231
|
+
const parent = path60.dirname(dir);
|
|
31151
31232
|
if (parent === dir)
|
|
31152
31233
|
break;
|
|
31153
31234
|
dir = parent;
|
|
@@ -31156,11 +31237,11 @@ function findBinInAncestors(startDir, binName) {
|
|
|
31156
31237
|
}
|
|
31157
31238
|
function findBinInEnvPath(binName) {
|
|
31158
31239
|
const searchPath = process.env.PATH ?? "";
|
|
31159
|
-
for (const dir of searchPath.split(
|
|
31240
|
+
for (const dir of searchPath.split(path60.delimiter)) {
|
|
31160
31241
|
if (!dir)
|
|
31161
31242
|
continue;
|
|
31162
|
-
const candidate =
|
|
31163
|
-
if (
|
|
31243
|
+
const candidate = path60.join(dir, binName);
|
|
31244
|
+
if (fs26.existsSync(candidate))
|
|
31164
31245
|
return candidate;
|
|
31165
31246
|
}
|
|
31166
31247
|
return null;
|
|
@@ -31168,17 +31249,17 @@ function findBinInEnvPath(binName) {
|
|
|
31168
31249
|
async function detectAvailableLinter(directory) {
|
|
31169
31250
|
if (!directory)
|
|
31170
31251
|
return null;
|
|
31171
|
-
if (!
|
|
31252
|
+
if (!fs26.existsSync(directory))
|
|
31172
31253
|
return null;
|
|
31173
31254
|
const projectDir = directory;
|
|
31174
31255
|
const isWindows = process.platform === "win32";
|
|
31175
|
-
const biomeBin = isWindows ?
|
|
31176
|
-
const eslintBin = isWindows ?
|
|
31256
|
+
const biomeBin = isWindows ? path60.join(projectDir, "node_modules", ".bin", "biome.EXE") : path60.join(projectDir, "node_modules", ".bin", "biome");
|
|
31257
|
+
const eslintBin = isWindows ? path60.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path60.join(projectDir, "node_modules", ".bin", "eslint");
|
|
31177
31258
|
const localResult = await _detectAvailableLinter(projectDir, biomeBin, eslintBin);
|
|
31178
31259
|
if (localResult)
|
|
31179
31260
|
return localResult;
|
|
31180
|
-
const biomeAncestor = findBinInAncestors(
|
|
31181
|
-
const eslintAncestor = findBinInAncestors(
|
|
31261
|
+
const biomeAncestor = findBinInAncestors(path60.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
|
|
31262
|
+
const eslintAncestor = findBinInAncestors(path60.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
|
|
31182
31263
|
if (biomeAncestor || eslintAncestor) {
|
|
31183
31264
|
return _detectAvailableLinter(projectDir, biomeAncestor ?? biomeBin, eslintAncestor ?? eslintBin);
|
|
31184
31265
|
}
|
|
@@ -31201,7 +31282,7 @@ async function _detectAvailableLinter(_projectDir, biomeBin, eslintBin) {
|
|
|
31201
31282
|
const result = await Promise.race([biomeExit, timeout]);
|
|
31202
31283
|
if (result === "timeout") {
|
|
31203
31284
|
biomeProc.kill();
|
|
31204
|
-
} else if (biomeProc.exitCode === 0 &&
|
|
31285
|
+
} else if (biomeProc.exitCode === 0 && fs26.existsSync(biomeBin)) {
|
|
31205
31286
|
return "biome";
|
|
31206
31287
|
}
|
|
31207
31288
|
} catch {}
|
|
@@ -31215,7 +31296,7 @@ async function _detectAvailableLinter(_projectDir, biomeBin, eslintBin) {
|
|
|
31215
31296
|
const result = await Promise.race([eslintExit, timeout]);
|
|
31216
31297
|
if (result === "timeout") {
|
|
31217
31298
|
eslintProc.kill();
|
|
31218
|
-
} else if (eslintProc.exitCode === 0 &&
|
|
31299
|
+
} else if (eslintProc.exitCode === 0 && fs26.existsSync(eslintBin)) {
|
|
31219
31300
|
return "eslint";
|
|
31220
31301
|
}
|
|
31221
31302
|
} catch {}
|
|
@@ -31361,15 +31442,15 @@ var lint = createSwarmTool({
|
|
|
31361
31442
|
}
|
|
31362
31443
|
const { mode } = args;
|
|
31363
31444
|
const cwd = directory;
|
|
31364
|
-
const linter = await
|
|
31445
|
+
const linter = await _internals50.detectAvailableLinter(directory);
|
|
31365
31446
|
if (linter) {
|
|
31366
|
-
const result = await
|
|
31447
|
+
const result = await _internals50.runLint(linter, mode, directory);
|
|
31367
31448
|
return JSON.stringify(result, null, 2);
|
|
31368
31449
|
}
|
|
31369
|
-
const additionalLinter =
|
|
31450
|
+
const additionalLinter = _internals50.detectAdditionalLinter(cwd);
|
|
31370
31451
|
if (additionalLinter) {
|
|
31371
31452
|
warn(`[lint] Using ${additionalLinter} linter for this project`);
|
|
31372
|
-
const result = await
|
|
31453
|
+
const result = await _internals50.runAdditionalLint(additionalLinter, mode, cwd);
|
|
31373
31454
|
return JSON.stringify(result, null, 2);
|
|
31374
31455
|
}
|
|
31375
31456
|
const errorResult = {
|
|
@@ -31383,7 +31464,7 @@ For Rust: rustup component add clippy`
|
|
|
31383
31464
|
return JSON.stringify(errorResult, null, 2);
|
|
31384
31465
|
}
|
|
31385
31466
|
});
|
|
31386
|
-
var
|
|
31467
|
+
var _internals50 = {
|
|
31387
31468
|
detectAvailableLinter,
|
|
31388
31469
|
runLint,
|
|
31389
31470
|
detectAdditionalLinter,
|
|
@@ -31391,8 +31472,8 @@ var _internals49 = {
|
|
|
31391
31472
|
};
|
|
31392
31473
|
|
|
31393
31474
|
// src/tools/secretscan.ts
|
|
31394
|
-
import * as
|
|
31395
|
-
import * as
|
|
31475
|
+
import * as fs27 from "fs";
|
|
31476
|
+
import * as path61 from "path";
|
|
31396
31477
|
var MAX_FILE_PATH_LENGTH = 500;
|
|
31397
31478
|
var MAX_FILE_SIZE_BYTES3 = 512 * 1024;
|
|
31398
31479
|
var MAX_FILES_SCANNED2 = 1000;
|
|
@@ -31619,11 +31700,11 @@ function isGlobOrPathPattern(pattern) {
|
|
|
31619
31700
|
return pattern.includes("/") || pattern.includes("\\") || /[*?[\]{}]/.test(pattern);
|
|
31620
31701
|
}
|
|
31621
31702
|
function loadSecretScanIgnore(scanDir) {
|
|
31622
|
-
const ignorePath =
|
|
31703
|
+
const ignorePath = path61.join(scanDir, ".secretscanignore");
|
|
31623
31704
|
try {
|
|
31624
|
-
if (!
|
|
31705
|
+
if (!fs27.existsSync(ignorePath))
|
|
31625
31706
|
return [];
|
|
31626
|
-
const content =
|
|
31707
|
+
const content = fs27.readFileSync(ignorePath, "utf8");
|
|
31627
31708
|
const patterns = [];
|
|
31628
31709
|
for (const rawLine of content.split(/\r?\n/)) {
|
|
31629
31710
|
const line = rawLine.trim();
|
|
@@ -31642,7 +31723,7 @@ function isExcluded(entry, relPath, exactNames, globPatterns) {
|
|
|
31642
31723
|
if (exactNames.has(entry))
|
|
31643
31724
|
return true;
|
|
31644
31725
|
for (const pattern of globPatterns) {
|
|
31645
|
-
if (
|
|
31726
|
+
if (path61.matchesGlob(relPath, pattern))
|
|
31646
31727
|
return true;
|
|
31647
31728
|
}
|
|
31648
31729
|
return false;
|
|
@@ -31663,7 +31744,7 @@ function validateDirectoryInput(dir) {
|
|
|
31663
31744
|
return null;
|
|
31664
31745
|
}
|
|
31665
31746
|
function isBinaryFile(filePath, buffer) {
|
|
31666
|
-
const ext =
|
|
31747
|
+
const ext = path61.extname(filePath).toLowerCase();
|
|
31667
31748
|
if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
|
|
31668
31749
|
return true;
|
|
31669
31750
|
}
|
|
@@ -31738,11 +31819,11 @@ function createRedactedContext(line, findings) {
|
|
|
31738
31819
|
result += line.slice(lastEnd);
|
|
31739
31820
|
return result;
|
|
31740
31821
|
}
|
|
31741
|
-
var O_NOFOLLOW = process.platform !== "win32" ?
|
|
31822
|
+
var O_NOFOLLOW = process.platform !== "win32" ? fs27.constants.O_NOFOLLOW : undefined;
|
|
31742
31823
|
function scanFileForSecrets(filePath) {
|
|
31743
31824
|
const findings = [];
|
|
31744
31825
|
try {
|
|
31745
|
-
const lstat =
|
|
31826
|
+
const lstat = fs27.lstatSync(filePath);
|
|
31746
31827
|
if (lstat.isSymbolicLink()) {
|
|
31747
31828
|
return findings;
|
|
31748
31829
|
}
|
|
@@ -31751,14 +31832,14 @@ function scanFileForSecrets(filePath) {
|
|
|
31751
31832
|
}
|
|
31752
31833
|
let buffer;
|
|
31753
31834
|
if (O_NOFOLLOW !== undefined) {
|
|
31754
|
-
const fd =
|
|
31835
|
+
const fd = fs27.openSync(filePath, "r", O_NOFOLLOW);
|
|
31755
31836
|
try {
|
|
31756
|
-
buffer =
|
|
31837
|
+
buffer = fs27.readFileSync(fd);
|
|
31757
31838
|
} finally {
|
|
31758
|
-
|
|
31839
|
+
fs27.closeSync(fd);
|
|
31759
31840
|
}
|
|
31760
31841
|
} else {
|
|
31761
|
-
buffer =
|
|
31842
|
+
buffer = fs27.readFileSync(filePath);
|
|
31762
31843
|
}
|
|
31763
31844
|
if (isBinaryFile(filePath, buffer)) {
|
|
31764
31845
|
return findings;
|
|
@@ -31800,9 +31881,9 @@ function isSymlinkLoop(realPath, visited) {
|
|
|
31800
31881
|
return false;
|
|
31801
31882
|
}
|
|
31802
31883
|
function isPathWithinScope(realPath, scanDir) {
|
|
31803
|
-
const resolvedScanDir =
|
|
31804
|
-
const resolvedRealPath =
|
|
31805
|
-
return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir +
|
|
31884
|
+
const resolvedScanDir = path61.resolve(scanDir);
|
|
31885
|
+
const resolvedRealPath = path61.resolve(realPath);
|
|
31886
|
+
return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path61.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
|
|
31806
31887
|
}
|
|
31807
31888
|
function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, stats = {
|
|
31808
31889
|
skippedDirs: 0,
|
|
@@ -31813,7 +31894,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
31813
31894
|
const files = [];
|
|
31814
31895
|
let entries;
|
|
31815
31896
|
try {
|
|
31816
|
-
entries =
|
|
31897
|
+
entries = fs27.readdirSync(dir);
|
|
31817
31898
|
} catch {
|
|
31818
31899
|
stats.fileErrors++;
|
|
31819
31900
|
return files;
|
|
@@ -31828,15 +31909,15 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
31828
31909
|
return a.localeCompare(b);
|
|
31829
31910
|
});
|
|
31830
31911
|
for (const entry of entries) {
|
|
31831
|
-
const fullPath =
|
|
31832
|
-
const relPath =
|
|
31912
|
+
const fullPath = path61.join(dir, entry);
|
|
31913
|
+
const relPath = path61.relative(scanDir, fullPath).replace(/\\/g, "/");
|
|
31833
31914
|
if (isExcluded(entry, relPath, excludeExact, excludeGlobs)) {
|
|
31834
31915
|
stats.skippedDirs++;
|
|
31835
31916
|
continue;
|
|
31836
31917
|
}
|
|
31837
31918
|
let lstat;
|
|
31838
31919
|
try {
|
|
31839
|
-
lstat =
|
|
31920
|
+
lstat = fs27.lstatSync(fullPath);
|
|
31840
31921
|
} catch {
|
|
31841
31922
|
stats.fileErrors++;
|
|
31842
31923
|
continue;
|
|
@@ -31848,7 +31929,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
31848
31929
|
if (lstat.isDirectory()) {
|
|
31849
31930
|
let realPath;
|
|
31850
31931
|
try {
|
|
31851
|
-
realPath =
|
|
31932
|
+
realPath = fs27.realpathSync(fullPath);
|
|
31852
31933
|
} catch {
|
|
31853
31934
|
stats.fileErrors++;
|
|
31854
31935
|
continue;
|
|
@@ -31864,7 +31945,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
31864
31945
|
const subFiles = findScannableFiles(fullPath, excludeExact, excludeGlobs, scanDir, visited, stats);
|
|
31865
31946
|
files.push(...subFiles);
|
|
31866
31947
|
} else if (lstat.isFile()) {
|
|
31867
|
-
const ext =
|
|
31948
|
+
const ext = path61.extname(fullPath).toLowerCase();
|
|
31868
31949
|
if (!DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
|
|
31869
31950
|
files.push(fullPath);
|
|
31870
31951
|
} else {
|
|
@@ -31930,15 +32011,15 @@ var secretscan = createSwarmTool({
|
|
|
31930
32011
|
}
|
|
31931
32012
|
}
|
|
31932
32013
|
try {
|
|
31933
|
-
const _scanDirRaw =
|
|
32014
|
+
const _scanDirRaw = path61.resolve(directory);
|
|
31934
32015
|
const scanDir = (() => {
|
|
31935
32016
|
try {
|
|
31936
|
-
return
|
|
32017
|
+
return fs27.realpathSync(_scanDirRaw);
|
|
31937
32018
|
} catch {
|
|
31938
32019
|
return _scanDirRaw;
|
|
31939
32020
|
}
|
|
31940
32021
|
})();
|
|
31941
|
-
if (!
|
|
32022
|
+
if (!fs27.existsSync(scanDir)) {
|
|
31942
32023
|
const errorResult = {
|
|
31943
32024
|
error: "directory not found",
|
|
31944
32025
|
scan_dir: directory,
|
|
@@ -31949,7 +32030,7 @@ var secretscan = createSwarmTool({
|
|
|
31949
32030
|
};
|
|
31950
32031
|
return JSON.stringify(errorResult, null, 2);
|
|
31951
32032
|
}
|
|
31952
|
-
const dirStat =
|
|
32033
|
+
const dirStat = fs27.statSync(scanDir);
|
|
31953
32034
|
if (!dirStat.isDirectory()) {
|
|
31954
32035
|
const errorResult = {
|
|
31955
32036
|
error: "target must be a directory, not a file",
|
|
@@ -32000,7 +32081,7 @@ var secretscan = createSwarmTool({
|
|
|
32000
32081
|
break;
|
|
32001
32082
|
const fileFindings = scanFileForSecrets(filePath);
|
|
32002
32083
|
try {
|
|
32003
|
-
const stat4 =
|
|
32084
|
+
const stat4 = fs27.statSync(filePath);
|
|
32004
32085
|
if (stat4.size > MAX_FILE_SIZE_BYTES3) {
|
|
32005
32086
|
skippedFiles++;
|
|
32006
32087
|
continue;
|
|
@@ -32071,7 +32152,7 @@ var secretscan = createSwarmTool({
|
|
|
32071
32152
|
});
|
|
32072
32153
|
async function runSecretscan(directory) {
|
|
32073
32154
|
try {
|
|
32074
|
-
const result = await
|
|
32155
|
+
const result = await _internals51.secretscan.execute({ directory }, {});
|
|
32075
32156
|
const jsonStr = typeof result === "string" ? result : result.output;
|
|
32076
32157
|
return JSON.parse(jsonStr);
|
|
32077
32158
|
} catch (e) {
|
|
@@ -32096,17 +32177,17 @@ async function runSecretscanOnFiles(files, directory) {
|
|
|
32096
32177
|
skippedFiles++;
|
|
32097
32178
|
continue;
|
|
32098
32179
|
}
|
|
32099
|
-
const resolvedPath =
|
|
32180
|
+
const resolvedPath = path61.isAbsolute(file) ? path61.resolve(file) : path61.resolve(directory, file);
|
|
32100
32181
|
if (!isPathWithinScope(resolvedPath, directory)) {
|
|
32101
32182
|
skippedFiles++;
|
|
32102
32183
|
continue;
|
|
32103
32184
|
}
|
|
32104
|
-
const ext =
|
|
32185
|
+
const ext = path61.extname(resolvedPath).toLowerCase();
|
|
32105
32186
|
if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
|
|
32106
32187
|
skippedFiles++;
|
|
32107
32188
|
continue;
|
|
32108
32189
|
}
|
|
32109
|
-
if (!
|
|
32190
|
+
if (!fs27.existsSync(resolvedPath)) {
|
|
32110
32191
|
skippedFiles++;
|
|
32111
32192
|
continue;
|
|
32112
32193
|
}
|
|
@@ -32143,7 +32224,7 @@ async function runSecretscanOnFiles(files, directory) {
|
|
|
32143
32224
|
};
|
|
32144
32225
|
}
|
|
32145
32226
|
}
|
|
32146
|
-
var
|
|
32227
|
+
var _internals51 = {
|
|
32147
32228
|
secretscan,
|
|
32148
32229
|
runSecretscan,
|
|
32149
32230
|
runSecretscanOnFiles,
|
|
@@ -32151,12 +32232,12 @@ var _internals50 = {
|
|
|
32151
32232
|
};
|
|
32152
32233
|
|
|
32153
32234
|
// src/tools/test-runner.ts
|
|
32154
|
-
import * as
|
|
32155
|
-
import * as
|
|
32235
|
+
import * as fs31 from "fs";
|
|
32236
|
+
import * as path65 from "path";
|
|
32156
32237
|
|
|
32157
32238
|
// src/test-impact/analyzer.ts
|
|
32158
|
-
import
|
|
32159
|
-
import
|
|
32239
|
+
import fs28 from "fs";
|
|
32240
|
+
import path62 from "path";
|
|
32160
32241
|
var IMPORT_REGEX_ES = /import\s+[\s\S]*?\s+from\s+['"]([^'"]+)['"]/g;
|
|
32161
32242
|
var IMPORT_REGEX_REQUIRE = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
32162
32243
|
var IMPORT_REGEX_REEXPORT = /export\s+(?:\{[^}]*\}|\*)\s+from\s+['"]([^'"]+)['"]/g;
|
|
@@ -32183,7 +32264,7 @@ function sharedTrailingSegments(a, b) {
|
|
|
32183
32264
|
function isCacheStale(impactMap, generatedAtMs) {
|
|
32184
32265
|
for (const sourcePath of Object.keys(impactMap)) {
|
|
32185
32266
|
try {
|
|
32186
|
-
const stat4 =
|
|
32267
|
+
const stat4 = fs28.statSync(sourcePath);
|
|
32187
32268
|
if (stat4.mtimeMs > generatedAtMs) {
|
|
32188
32269
|
return true;
|
|
32189
32270
|
}
|
|
@@ -32197,15 +32278,15 @@ function resolveRelativeImport(fromDir, importPath) {
|
|
|
32197
32278
|
if (!importPath.startsWith(".")) {
|
|
32198
32279
|
return null;
|
|
32199
32280
|
}
|
|
32200
|
-
const resolved =
|
|
32201
|
-
if (
|
|
32202
|
-
if (
|
|
32281
|
+
const resolved = path62.resolve(fromDir, importPath);
|
|
32282
|
+
if (path62.extname(resolved)) {
|
|
32283
|
+
if (fs28.existsSync(resolved) && fs28.statSync(resolved).isFile()) {
|
|
32203
32284
|
return normalizePath2(resolved);
|
|
32204
32285
|
}
|
|
32205
32286
|
} else {
|
|
32206
32287
|
for (const ext of EXTENSIONS_TO_TRY) {
|
|
32207
32288
|
const withExt = resolved + ext;
|
|
32208
|
-
if (
|
|
32289
|
+
if (fs28.existsSync(withExt) && fs28.statSync(withExt).isFile()) {
|
|
32209
32290
|
return normalizePath2(withExt);
|
|
32210
32291
|
}
|
|
32211
32292
|
}
|
|
@@ -32218,30 +32299,30 @@ function resolvePythonImport(fromDir, module) {
|
|
|
32218
32299
|
const leadingDots = module.match(/^\.+/)?.[0].length ?? 0;
|
|
32219
32300
|
let baseDir = fromDir;
|
|
32220
32301
|
for (let i = 1;i < leadingDots; i++) {
|
|
32221
|
-
baseDir =
|
|
32302
|
+
baseDir = path62.dirname(baseDir);
|
|
32222
32303
|
}
|
|
32223
32304
|
const rest = module.slice(leadingDots);
|
|
32224
32305
|
if (rest.length === 0) {
|
|
32225
|
-
const initPath =
|
|
32226
|
-
if (
|
|
32306
|
+
const initPath = path62.join(baseDir, "__init__.py");
|
|
32307
|
+
if (fs28.existsSync(initPath) && fs28.statSync(initPath).isFile()) {
|
|
32227
32308
|
return normalizePath2(initPath);
|
|
32228
32309
|
}
|
|
32229
32310
|
return null;
|
|
32230
32311
|
}
|
|
32231
|
-
const subpath = rest.replace(/\./g,
|
|
32312
|
+
const subpath = rest.replace(/\./g, path62.sep);
|
|
32232
32313
|
const candidates = [
|
|
32233
|
-
`${
|
|
32234
|
-
|
|
32314
|
+
`${path62.join(baseDir, subpath)}.py`,
|
|
32315
|
+
path62.join(baseDir, subpath, "__init__.py")
|
|
32235
32316
|
];
|
|
32236
32317
|
for (const c of candidates) {
|
|
32237
|
-
if (
|
|
32318
|
+
if (fs28.existsSync(c) && fs28.statSync(c).isFile())
|
|
32238
32319
|
return normalizePath2(c);
|
|
32239
32320
|
}
|
|
32240
32321
|
return null;
|
|
32241
32322
|
}
|
|
32242
32323
|
var goModuleCache = new Map;
|
|
32243
32324
|
function findGoModule(fromDir) {
|
|
32244
|
-
const resolved =
|
|
32325
|
+
const resolved = path62.resolve(fromDir);
|
|
32245
32326
|
let cur = resolved;
|
|
32246
32327
|
const walked = [];
|
|
32247
32328
|
for (let i = 0;i < 16; i++) {
|
|
@@ -32253,8 +32334,8 @@ function findGoModule(fromDir) {
|
|
|
32253
32334
|
}
|
|
32254
32335
|
walked.push(cur);
|
|
32255
32336
|
try {
|
|
32256
|
-
const goMod =
|
|
32257
|
-
const content =
|
|
32337
|
+
const goMod = path62.join(cur, "go.mod");
|
|
32338
|
+
const content = fs28.readFileSync(goMod, "utf-8");
|
|
32258
32339
|
const moduleMatch = content.match(/^\s*module\s+"?([^"\s/]+(?:\/[^"\s]+)*)"?/m);
|
|
32259
32340
|
if (moduleMatch) {
|
|
32260
32341
|
const result = { moduleRoot: cur, modulePath: moduleMatch[1] };
|
|
@@ -32264,10 +32345,10 @@ function findGoModule(fromDir) {
|
|
|
32264
32345
|
}
|
|
32265
32346
|
} catch {}
|
|
32266
32347
|
try {
|
|
32267
|
-
|
|
32348
|
+
fs28.accessSync(path62.join(cur, ".git"));
|
|
32268
32349
|
break;
|
|
32269
32350
|
} catch {}
|
|
32270
|
-
const parent =
|
|
32351
|
+
const parent = path62.dirname(cur);
|
|
32271
32352
|
if (parent === cur)
|
|
32272
32353
|
break;
|
|
32273
32354
|
cur = parent;
|
|
@@ -32279,20 +32360,20 @@ function findGoModule(fromDir) {
|
|
|
32279
32360
|
function resolveGoImport(fromDir, importPath) {
|
|
32280
32361
|
let dir = null;
|
|
32281
32362
|
if (importPath.startsWith(".")) {
|
|
32282
|
-
dir =
|
|
32363
|
+
dir = path62.resolve(fromDir, importPath);
|
|
32283
32364
|
} else {
|
|
32284
32365
|
const mod = findGoModule(fromDir);
|
|
32285
32366
|
if (mod && (importPath === mod.modulePath || importPath.startsWith(`${mod.modulePath}/`))) {
|
|
32286
32367
|
const subpath = importPath.slice(mod.modulePath.length);
|
|
32287
|
-
dir =
|
|
32368
|
+
dir = path62.join(mod.moduleRoot, subpath);
|
|
32288
32369
|
}
|
|
32289
32370
|
}
|
|
32290
32371
|
if (dir === null)
|
|
32291
32372
|
return [];
|
|
32292
|
-
if (!
|
|
32373
|
+
if (!fs28.existsSync(dir) || !fs28.statSync(dir).isDirectory())
|
|
32293
32374
|
return [];
|
|
32294
32375
|
try {
|
|
32295
|
-
return
|
|
32376
|
+
return fs28.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath2(path62.join(dir, f)));
|
|
32296
32377
|
} catch {
|
|
32297
32378
|
return [];
|
|
32298
32379
|
}
|
|
@@ -32312,13 +32393,13 @@ function findTestFilesSync(cwd) {
|
|
|
32312
32393
|
function walk(dir, visitedInodes) {
|
|
32313
32394
|
let entries;
|
|
32314
32395
|
try {
|
|
32315
|
-
entries =
|
|
32396
|
+
entries = fs28.readdirSync(dir, { withFileTypes: true });
|
|
32316
32397
|
} catch {
|
|
32317
32398
|
return;
|
|
32318
32399
|
}
|
|
32319
32400
|
let dirInode;
|
|
32320
32401
|
try {
|
|
32321
|
-
dirInode =
|
|
32402
|
+
dirInode = fs28.statSync(dir).ino;
|
|
32322
32403
|
} catch {
|
|
32323
32404
|
return;
|
|
32324
32405
|
}
|
|
@@ -32331,15 +32412,15 @@ function findTestFilesSync(cwd) {
|
|
|
32331
32412
|
for (const entry of entries) {
|
|
32332
32413
|
if (entry.isDirectory()) {
|
|
32333
32414
|
if (!skipDirs.has(entry.name)) {
|
|
32334
|
-
walk(
|
|
32415
|
+
walk(path62.join(dir, entry.name), visitedInodes);
|
|
32335
32416
|
}
|
|
32336
32417
|
} else if (entry.isFile()) {
|
|
32337
32418
|
const name = entry.name;
|
|
32338
32419
|
const isTsTest = /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(name) || dir.includes("__tests__") && /\.(ts|tsx|js|jsx)$/.test(name);
|
|
32339
|
-
const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${
|
|
32420
|
+
const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${path62.sep}tests${path62.sep}`) && name.endsWith(".py");
|
|
32340
32421
|
const isGoTest = /.+_test\.go$/.test(name);
|
|
32341
32422
|
if (isTsTest || isPyTest || isGoTest) {
|
|
32342
|
-
testFiles.push(normalizePath2(
|
|
32423
|
+
testFiles.push(normalizePath2(path62.join(dir, entry.name)));
|
|
32343
32424
|
}
|
|
32344
32425
|
}
|
|
32345
32426
|
}
|
|
@@ -32364,8 +32445,8 @@ function extractImports(content) {
|
|
|
32364
32445
|
];
|
|
32365
32446
|
}
|
|
32366
32447
|
function addImpactEdgesForTestFile(testFile, content, impactMap) {
|
|
32367
|
-
const ext =
|
|
32368
|
-
const testDir =
|
|
32448
|
+
const ext = path62.extname(testFile).toLowerCase();
|
|
32449
|
+
const testDir = path62.dirname(testFile);
|
|
32369
32450
|
function addEdge(source) {
|
|
32370
32451
|
if (!impactMap[source])
|
|
32371
32452
|
impactMap[source] = [];
|
|
@@ -32408,7 +32489,7 @@ async function buildImpactMapInternal(cwd) {
|
|
|
32408
32489
|
for (const testFile of testFiles) {
|
|
32409
32490
|
let content;
|
|
32410
32491
|
try {
|
|
32411
|
-
content =
|
|
32492
|
+
content = fs28.readFileSync(testFile, "utf-8");
|
|
32412
32493
|
} catch {
|
|
32413
32494
|
continue;
|
|
32414
32495
|
}
|
|
@@ -32419,7 +32500,7 @@ async function buildImpactMapInternal(cwd) {
|
|
|
32419
32500
|
}
|
|
32420
32501
|
return impactMap;
|
|
32421
32502
|
}
|
|
32422
|
-
var
|
|
32503
|
+
var _internals52 = {
|
|
32423
32504
|
validateProjectRoot,
|
|
32424
32505
|
normalizePath: normalizePath2,
|
|
32425
32506
|
isCacheStale,
|
|
@@ -32434,22 +32515,22 @@ var _internals51 = {
|
|
|
32434
32515
|
_clearGoModuleCache
|
|
32435
32516
|
};
|
|
32436
32517
|
async function buildImpactMap(cwd) {
|
|
32437
|
-
const impactMap = await
|
|
32438
|
-
await
|
|
32518
|
+
const impactMap = await _internals52.buildImpactMapInternal(cwd);
|
|
32519
|
+
await _internals52.saveImpactMap(cwd, impactMap);
|
|
32439
32520
|
return impactMap;
|
|
32440
32521
|
}
|
|
32441
32522
|
async function loadImpactMap(cwd, options) {
|
|
32442
|
-
const cachePath =
|
|
32443
|
-
if (
|
|
32523
|
+
const cachePath = path62.join(cwd, ".swarm", "cache", "impact-map.json");
|
|
32524
|
+
if (fs28.existsSync(cachePath)) {
|
|
32444
32525
|
try {
|
|
32445
|
-
const content =
|
|
32526
|
+
const content = fs28.readFileSync(cachePath, "utf-8");
|
|
32446
32527
|
const data = JSON.parse(content);
|
|
32447
32528
|
if (data.map !== null && typeof data.map === "object" && !Array.isArray(data.map)) {
|
|
32448
32529
|
const map = data.map;
|
|
32449
32530
|
const hasValidValues = Object.values(map).every((v) => Array.isArray(v) && v.every((item) => typeof item === "string"));
|
|
32450
32531
|
if (hasValidValues) {
|
|
32451
32532
|
const generatedAt = new Date(data.generatedAt).getTime();
|
|
32452
|
-
if (!
|
|
32533
|
+
if (!_internals52.isCacheStale(map, generatedAt)) {
|
|
32453
32534
|
return map;
|
|
32454
32535
|
}
|
|
32455
32536
|
if (options?.skipRebuild) {
|
|
@@ -32469,24 +32550,24 @@ async function loadImpactMap(cwd, options) {
|
|
|
32469
32550
|
if (options?.skipRebuild) {
|
|
32470
32551
|
return {};
|
|
32471
32552
|
}
|
|
32472
|
-
return
|
|
32553
|
+
return _internals52.buildImpactMap(cwd);
|
|
32473
32554
|
}
|
|
32474
32555
|
async function saveImpactMap(cwd, impactMap) {
|
|
32475
|
-
if (!
|
|
32556
|
+
if (!path62.isAbsolute(cwd)) {
|
|
32476
32557
|
throw new Error(`saveImpactMap requires an absolute project root path, got: "${cwd}"`);
|
|
32477
32558
|
}
|
|
32478
|
-
|
|
32479
|
-
const cacheDir2 =
|
|
32480
|
-
const cachePath =
|
|
32481
|
-
if (!
|
|
32482
|
-
|
|
32559
|
+
_internals52.validateProjectRoot(cwd);
|
|
32560
|
+
const cacheDir2 = path62.join(cwd, ".swarm", "cache");
|
|
32561
|
+
const cachePath = path62.join(cacheDir2, "impact-map.json");
|
|
32562
|
+
if (!fs28.existsSync(cacheDir2)) {
|
|
32563
|
+
fs28.mkdirSync(cacheDir2, { recursive: true });
|
|
32483
32564
|
}
|
|
32484
32565
|
const data = {
|
|
32485
32566
|
generatedAt: new Date().toISOString(),
|
|
32486
32567
|
fileCount: Object.keys(impactMap).length,
|
|
32487
32568
|
map: impactMap
|
|
32488
32569
|
};
|
|
32489
|
-
|
|
32570
|
+
fs28.writeFileSync(cachePath, JSON.stringify(data, null, 2), "utf-8");
|
|
32490
32571
|
}
|
|
32491
32572
|
async function analyzeImpact(changedFiles, cwd, budget) {
|
|
32492
32573
|
if (!Array.isArray(changedFiles)) {
|
|
@@ -32499,7 +32580,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
|
|
|
32499
32580
|
};
|
|
32500
32581
|
}
|
|
32501
32582
|
const validFiles = changedFiles.filter((f) => typeof f === "string" && f.length > 0 && !f.includes("\x00"));
|
|
32502
|
-
const impactMap = await
|
|
32583
|
+
const impactMap = await _internals52.loadImpactMap(cwd);
|
|
32503
32584
|
const impactedTestsSet = new Set;
|
|
32504
32585
|
const untestedFiles = [];
|
|
32505
32586
|
let visitedCount = 0;
|
|
@@ -32509,7 +32590,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
|
|
|
32509
32590
|
budgetExceeded = true;
|
|
32510
32591
|
break;
|
|
32511
32592
|
}
|
|
32512
|
-
const normalizedChanged = normalizePath2(
|
|
32593
|
+
const normalizedChanged = normalizePath2(path62.resolve(changedFile));
|
|
32513
32594
|
const tests = impactMap[normalizedChanged];
|
|
32514
32595
|
if (tests && tests.length > 0) {
|
|
32515
32596
|
for (const test of tests) {
|
|
@@ -32523,13 +32604,13 @@ async function analyzeImpact(changedFiles, cwd, budget) {
|
|
|
32523
32604
|
if (budgetExceeded)
|
|
32524
32605
|
break;
|
|
32525
32606
|
} else {
|
|
32526
|
-
const changedDir = normalizePath2(
|
|
32527
|
-
const changedInputDir = normalizePath2(
|
|
32607
|
+
const changedDir = normalizePath2(path62.dirname(normalizedChanged));
|
|
32608
|
+
const changedInputDir = normalizePath2(path62.dirname(changedFile));
|
|
32528
32609
|
const suffixMatches = Object.entries(impactMap).filter(([sourcePath]) => {
|
|
32529
32610
|
return sourcePath.endsWith(changedFile) || changedFile.endsWith(sourcePath) || sourcePath.endsWith(normalizedChanged) || normalizedChanged.endsWith(sourcePath);
|
|
32530
32611
|
}).sort(([sourceA], [sourceB]) => {
|
|
32531
|
-
const sourceDirA = normalizePath2(
|
|
32532
|
-
const sourceDirB = normalizePath2(
|
|
32612
|
+
const sourceDirA = normalizePath2(path62.dirname(sourceA));
|
|
32613
|
+
const sourceDirB = normalizePath2(path62.dirname(sourceB));
|
|
32533
32614
|
const exactA = sourceDirA === changedDir || changedInputDir !== "." && (sourceDirA === changedInputDir || sourceDirA.endsWith(`/${changedInputDir}`));
|
|
32534
32615
|
const exactB = sourceDirB === changedDir || changedInputDir !== "." && (sourceDirB === changedInputDir || sourceDirB.endsWith(`/${changedInputDir}`));
|
|
32535
32616
|
if (exactA !== exactB)
|
|
@@ -32667,8 +32748,8 @@ function detectFlakyTests(allHistory) {
|
|
|
32667
32748
|
}
|
|
32668
32749
|
|
|
32669
32750
|
// src/test-impact/history-store.ts
|
|
32670
|
-
import
|
|
32671
|
-
import
|
|
32751
|
+
import fs29 from "fs";
|
|
32752
|
+
import path63 from "path";
|
|
32672
32753
|
var MAX_HISTORY_PER_TEST = 20;
|
|
32673
32754
|
var MAX_ERROR_LENGTH = 500;
|
|
32674
32755
|
var MAX_STACK_LENGTH = 200;
|
|
@@ -32680,10 +32761,10 @@ function getHistoryPath(workingDir) {
|
|
|
32680
32761
|
if (!workingDir) {
|
|
32681
32762
|
throw new Error("getHistoryPath requires a working directory \u2014 project root must be provided by the caller");
|
|
32682
32763
|
}
|
|
32683
|
-
if (!
|
|
32764
|
+
if (!path63.isAbsolute(workingDir)) {
|
|
32684
32765
|
throw new Error(`getHistoryPath requires an absolute project root path, got: "${workingDir}"`);
|
|
32685
32766
|
}
|
|
32686
|
-
return
|
|
32767
|
+
return path63.join(workingDir, ".swarm", "cache", "test-history.jsonl");
|
|
32687
32768
|
}
|
|
32688
32769
|
function sanitizeErrorMessage(errorMessage) {
|
|
32689
32770
|
if (errorMessage === undefined) {
|
|
@@ -32775,10 +32856,10 @@ function batchAppendTestRuns(records, workingDir) {
|
|
|
32775
32856
|
}
|
|
32776
32857
|
}
|
|
32777
32858
|
const historyPath = getHistoryPath(workingDir);
|
|
32778
|
-
const historyDir =
|
|
32779
|
-
|
|
32780
|
-
if (!
|
|
32781
|
-
|
|
32859
|
+
const historyDir = path63.dirname(historyPath);
|
|
32860
|
+
_internals53.validateProjectRoot(workingDir);
|
|
32861
|
+
if (!fs29.existsSync(historyDir)) {
|
|
32862
|
+
fs29.mkdirSync(historyDir, { recursive: true });
|
|
32782
32863
|
}
|
|
32783
32864
|
withHistoryWriteLock(historyPath, () => {
|
|
32784
32865
|
const existingRecords = readAllRecords(historyPath);
|
|
@@ -32812,13 +32893,13 @@ function batchAppendTestRuns(records, workingDir) {
|
|
|
32812
32893
|
`)}
|
|
32813
32894
|
`;
|
|
32814
32895
|
const tempPath = `${historyPath}.tmp`;
|
|
32815
|
-
|
|
32816
|
-
|
|
32896
|
+
fs29.writeFileSync(tempPath, content, "utf-8");
|
|
32897
|
+
fs29.renameSync(tempPath, historyPath);
|
|
32817
32898
|
} catch (err) {
|
|
32818
32899
|
try {
|
|
32819
32900
|
const tempPath = `${historyPath}.tmp`;
|
|
32820
|
-
if (
|
|
32821
|
-
|
|
32901
|
+
if (fs29.existsSync(tempPath)) {
|
|
32902
|
+
fs29.unlinkSync(tempPath);
|
|
32822
32903
|
}
|
|
32823
32904
|
} catch {}
|
|
32824
32905
|
throw new Error(`Failed to write test history: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -32830,7 +32911,7 @@ function withHistoryWriteLock(historyPath, fn) {
|
|
|
32830
32911
|
const deadline = Date.now() + HISTORY_WRITE_LOCK_TIMEOUT_MS;
|
|
32831
32912
|
while (true) {
|
|
32832
32913
|
try {
|
|
32833
|
-
|
|
32914
|
+
fs29.mkdirSync(lockPath);
|
|
32834
32915
|
break;
|
|
32835
32916
|
} catch (error2) {
|
|
32836
32917
|
const code = error2 instanceof Error && "code" in error2 ? error2.code : undefined;
|
|
@@ -32841,9 +32922,9 @@ function withHistoryWriteLock(historyPath, fn) {
|
|
|
32841
32922
|
throw new Error(`Timed out waiting for test history lock: ${historyPath}`);
|
|
32842
32923
|
}
|
|
32843
32924
|
try {
|
|
32844
|
-
const lockStat =
|
|
32925
|
+
const lockStat = fs29.statSync(lockPath);
|
|
32845
32926
|
if (Date.now() - lockStat.mtimeMs >= HISTORY_WRITE_LOCK_STALE_MS) {
|
|
32846
|
-
|
|
32927
|
+
fs29.rmSync(lockPath, { recursive: true, force: true });
|
|
32847
32928
|
continue;
|
|
32848
32929
|
}
|
|
32849
32930
|
} catch {}
|
|
@@ -32858,7 +32939,7 @@ function withHistoryWriteLock(historyPath, fn) {
|
|
|
32858
32939
|
return fn();
|
|
32859
32940
|
} finally {
|
|
32860
32941
|
try {
|
|
32861
|
-
|
|
32942
|
+
fs29.rmSync(lockPath, { recursive: true, force: true });
|
|
32862
32943
|
} catch {}
|
|
32863
32944
|
}
|
|
32864
32945
|
function sleepSync(ms) {
|
|
@@ -32867,11 +32948,11 @@ function withHistoryWriteLock(historyPath, fn) {
|
|
|
32867
32948
|
}
|
|
32868
32949
|
}
|
|
32869
32950
|
function readAllRecords(historyPath) {
|
|
32870
|
-
if (!
|
|
32951
|
+
if (!fs29.existsSync(historyPath)) {
|
|
32871
32952
|
return [];
|
|
32872
32953
|
}
|
|
32873
32954
|
try {
|
|
32874
|
-
const content =
|
|
32955
|
+
const content = fs29.readFileSync(historyPath, "utf-8");
|
|
32875
32956
|
const lines = content.split(`
|
|
32876
32957
|
`);
|
|
32877
32958
|
const records = [];
|
|
@@ -32899,13 +32980,13 @@ function getAllHistory(workingDir) {
|
|
|
32899
32980
|
records.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
|
|
32900
32981
|
return records;
|
|
32901
32982
|
}
|
|
32902
|
-
var
|
|
32983
|
+
var _internals53 = {
|
|
32903
32984
|
validateProjectRoot
|
|
32904
32985
|
};
|
|
32905
32986
|
|
|
32906
32987
|
// src/tools/resolve-working-directory.ts
|
|
32907
|
-
import * as
|
|
32908
|
-
import * as
|
|
32988
|
+
import * as fs30 from "fs";
|
|
32989
|
+
import * as path64 from "path";
|
|
32909
32990
|
function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
32910
32991
|
if (workingDirectory == null || workingDirectory === "") {
|
|
32911
32992
|
if (typeof fallbackDirectory !== "string" || fallbackDirectory === "") {
|
|
@@ -32942,11 +33023,11 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
32942
33023
|
message: "Invalid working_directory: path traversal sequences (..) are not allowed"
|
|
32943
33024
|
};
|
|
32944
33025
|
}
|
|
32945
|
-
const normalizedDir =
|
|
32946
|
-
const resolvedDir =
|
|
33026
|
+
const normalizedDir = path64.normalize(workingDirectory);
|
|
33027
|
+
const resolvedDir = path64.resolve(normalizedDir);
|
|
32947
33028
|
let statResult;
|
|
32948
33029
|
try {
|
|
32949
|
-
statResult =
|
|
33030
|
+
statResult = fs30.statSync(resolvedDir);
|
|
32950
33031
|
} catch {
|
|
32951
33032
|
return {
|
|
32952
33033
|
success: false,
|
|
@@ -32962,16 +33043,16 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
32962
33043
|
if (typeof fallbackDirectory !== "string" || fallbackDirectory === "") {
|
|
32963
33044
|
return { success: true, directory: resolvedDir };
|
|
32964
33045
|
}
|
|
32965
|
-
const resolvedFallback =
|
|
33046
|
+
const resolvedFallback = path64.resolve(fallbackDirectory);
|
|
32966
33047
|
let fallbackExists = false;
|
|
32967
33048
|
try {
|
|
32968
|
-
|
|
33049
|
+
fs30.statSync(resolvedFallback);
|
|
32969
33050
|
fallbackExists = true;
|
|
32970
33051
|
} catch {
|
|
32971
33052
|
fallbackExists = false;
|
|
32972
33053
|
}
|
|
32973
33054
|
if (fallbackExists) {
|
|
32974
|
-
const isSubdirectory = resolvedDir.startsWith(resolvedFallback +
|
|
33055
|
+
const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path64.sep);
|
|
32975
33056
|
if (isSubdirectory) {
|
|
32976
33057
|
return {
|
|
32977
33058
|
success: false,
|
|
@@ -32994,7 +33075,7 @@ async function estimateFanOut(sourceFiles, cwd) {
|
|
|
32994
33075
|
const impactMap = await loadImpactMap(cwd, { skipRebuild: true });
|
|
32995
33076
|
const uniqueTestFiles = new Set;
|
|
32996
33077
|
for (const sourceFile of sourceFiles) {
|
|
32997
|
-
const resolvedPath =
|
|
33078
|
+
const resolvedPath = path65.resolve(cwd, sourceFile);
|
|
32998
33079
|
const normalizedPath = resolvedPath.replace(/\\/g, "/");
|
|
32999
33080
|
const testFiles = impactMap[normalizedPath];
|
|
33000
33081
|
if (testFiles) {
|
|
@@ -33079,19 +33160,19 @@ function hasDevDependency(devDeps, ...patterns) {
|
|
|
33079
33160
|
return hasPackageJsonDependency(devDeps, ...patterns);
|
|
33080
33161
|
}
|
|
33081
33162
|
function detectGoTest(cwd) {
|
|
33082
|
-
return
|
|
33163
|
+
return fs31.existsSync(path65.join(cwd, "go.mod")) && isCommandAvailable("go");
|
|
33083
33164
|
}
|
|
33084
33165
|
function detectJavaMaven(cwd) {
|
|
33085
|
-
return
|
|
33166
|
+
return fs31.existsSync(path65.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
|
|
33086
33167
|
}
|
|
33087
33168
|
function detectGradle(cwd) {
|
|
33088
|
-
const hasBuildFile =
|
|
33089
|
-
const hasGradlew =
|
|
33169
|
+
const hasBuildFile = fs31.existsSync(path65.join(cwd, "build.gradle")) || fs31.existsSync(path65.join(cwd, "build.gradle.kts"));
|
|
33170
|
+
const hasGradlew = fs31.existsSync(path65.join(cwd, "gradlew")) || fs31.existsSync(path65.join(cwd, "gradlew.bat"));
|
|
33090
33171
|
return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
|
|
33091
33172
|
}
|
|
33092
33173
|
function detectDotnetTest(cwd) {
|
|
33093
33174
|
try {
|
|
33094
|
-
const files =
|
|
33175
|
+
const files = fs31.readdirSync(cwd);
|
|
33095
33176
|
const hasCsproj = files.some((f) => f.endsWith(".csproj"));
|
|
33096
33177
|
return hasCsproj && isCommandAvailable("dotnet");
|
|
33097
33178
|
} catch {
|
|
@@ -33099,25 +33180,25 @@ function detectDotnetTest(cwd) {
|
|
|
33099
33180
|
}
|
|
33100
33181
|
}
|
|
33101
33182
|
function detectCTest(cwd) {
|
|
33102
|
-
const hasSource =
|
|
33103
|
-
const hasBuildCache =
|
|
33183
|
+
const hasSource = fs31.existsSync(path65.join(cwd, "CMakeLists.txt"));
|
|
33184
|
+
const hasBuildCache = fs31.existsSync(path65.join(cwd, "CMakeCache.txt")) || fs31.existsSync(path65.join(cwd, "build", "CMakeCache.txt"));
|
|
33104
33185
|
return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
|
|
33105
33186
|
}
|
|
33106
33187
|
function detectSwiftTest(cwd) {
|
|
33107
|
-
return
|
|
33188
|
+
return fs31.existsSync(path65.join(cwd, "Package.swift")) && isCommandAvailable("swift");
|
|
33108
33189
|
}
|
|
33109
33190
|
function detectDartTest(cwd) {
|
|
33110
|
-
return
|
|
33191
|
+
return fs31.existsSync(path65.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
|
|
33111
33192
|
}
|
|
33112
33193
|
function detectRSpec(cwd) {
|
|
33113
|
-
const hasRSpecFile =
|
|
33114
|
-
const hasGemfile =
|
|
33115
|
-
const hasSpecDir =
|
|
33194
|
+
const hasRSpecFile = fs31.existsSync(path65.join(cwd, ".rspec"));
|
|
33195
|
+
const hasGemfile = fs31.existsSync(path65.join(cwd, "Gemfile"));
|
|
33196
|
+
const hasSpecDir = fs31.existsSync(path65.join(cwd, "spec"));
|
|
33116
33197
|
const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
|
|
33117
33198
|
return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
|
|
33118
33199
|
}
|
|
33119
33200
|
function detectMinitest(cwd) {
|
|
33120
|
-
return
|
|
33201
|
+
return fs31.existsSync(path65.join(cwd, "test")) && (fs31.existsSync(path65.join(cwd, "Gemfile")) || fs31.existsSync(path65.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
|
|
33121
33202
|
}
|
|
33122
33203
|
var DISPATCH_FRAMEWORK_MAP = {
|
|
33123
33204
|
bun: "bun",
|
|
@@ -33207,9 +33288,9 @@ async function parseTestOutputViaDispatch(framework, output, baseDir) {
|
|
|
33207
33288
|
async function detectTestFramework(cwd) {
|
|
33208
33289
|
const baseDir = cwd;
|
|
33209
33290
|
try {
|
|
33210
|
-
const packageJsonPath =
|
|
33211
|
-
if (
|
|
33212
|
-
const content =
|
|
33291
|
+
const packageJsonPath = path65.join(baseDir, "package.json");
|
|
33292
|
+
if (fs31.existsSync(packageJsonPath)) {
|
|
33293
|
+
const content = fs31.readFileSync(packageJsonPath, "utf-8");
|
|
33213
33294
|
const pkg = JSON.parse(content);
|
|
33214
33295
|
const _deps = pkg.dependencies || {};
|
|
33215
33296
|
const devDeps = pkg.devDependencies || {};
|
|
@@ -33228,38 +33309,38 @@ async function detectTestFramework(cwd) {
|
|
|
33228
33309
|
return "jest";
|
|
33229
33310
|
if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
|
|
33230
33311
|
return "mocha";
|
|
33231
|
-
if (
|
|
33312
|
+
if (fs31.existsSync(path65.join(baseDir, "bun.lockb")) || fs31.existsSync(path65.join(baseDir, "bun.lock"))) {
|
|
33232
33313
|
if (scripts.test?.includes("bun"))
|
|
33233
33314
|
return "bun";
|
|
33234
33315
|
}
|
|
33235
33316
|
}
|
|
33236
33317
|
} catch {}
|
|
33237
33318
|
try {
|
|
33238
|
-
const pyprojectTomlPath =
|
|
33239
|
-
const setupCfgPath =
|
|
33240
|
-
const requirementsTxtPath =
|
|
33241
|
-
if (
|
|
33242
|
-
const content =
|
|
33319
|
+
const pyprojectTomlPath = path65.join(baseDir, "pyproject.toml");
|
|
33320
|
+
const setupCfgPath = path65.join(baseDir, "setup.cfg");
|
|
33321
|
+
const requirementsTxtPath = path65.join(baseDir, "requirements.txt");
|
|
33322
|
+
if (fs31.existsSync(pyprojectTomlPath)) {
|
|
33323
|
+
const content = fs31.readFileSync(pyprojectTomlPath, "utf-8");
|
|
33243
33324
|
if (content.includes("[tool.pytest"))
|
|
33244
33325
|
return "pytest";
|
|
33245
33326
|
if (content.includes("pytest"))
|
|
33246
33327
|
return "pytest";
|
|
33247
33328
|
}
|
|
33248
|
-
if (
|
|
33249
|
-
const content =
|
|
33329
|
+
if (fs31.existsSync(setupCfgPath)) {
|
|
33330
|
+
const content = fs31.readFileSync(setupCfgPath, "utf-8");
|
|
33250
33331
|
if (content.includes("[pytest]"))
|
|
33251
33332
|
return "pytest";
|
|
33252
33333
|
}
|
|
33253
|
-
if (
|
|
33254
|
-
const content =
|
|
33334
|
+
if (fs31.existsSync(requirementsTxtPath)) {
|
|
33335
|
+
const content = fs31.readFileSync(requirementsTxtPath, "utf-8");
|
|
33255
33336
|
if (content.includes("pytest"))
|
|
33256
33337
|
return "pytest";
|
|
33257
33338
|
}
|
|
33258
33339
|
} catch {}
|
|
33259
33340
|
try {
|
|
33260
|
-
const cargoTomlPath =
|
|
33261
|
-
if (
|
|
33262
|
-
const content =
|
|
33341
|
+
const cargoTomlPath = path65.join(baseDir, "Cargo.toml");
|
|
33342
|
+
if (fs31.existsSync(cargoTomlPath)) {
|
|
33343
|
+
const content = fs31.readFileSync(cargoTomlPath, "utf-8");
|
|
33263
33344
|
if (content.includes("[dev-dependencies]")) {
|
|
33264
33345
|
if (content.includes("tokio") || content.includes("mockall") || content.includes("pretty_assertions")) {
|
|
33265
33346
|
return "cargo";
|
|
@@ -33268,10 +33349,10 @@ async function detectTestFramework(cwd) {
|
|
|
33268
33349
|
}
|
|
33269
33350
|
} catch {}
|
|
33270
33351
|
try {
|
|
33271
|
-
const pesterConfigPath =
|
|
33272
|
-
const pesterConfigJsonPath =
|
|
33273
|
-
const pesterPs1Path =
|
|
33274
|
-
if (
|
|
33352
|
+
const pesterConfigPath = path65.join(baseDir, "pester.config.ps1");
|
|
33353
|
+
const pesterConfigJsonPath = path65.join(baseDir, "pester.config.ps1.json");
|
|
33354
|
+
const pesterPs1Path = path65.join(baseDir, "tests.ps1");
|
|
33355
|
+
if (fs31.existsSync(pesterConfigPath) || fs31.existsSync(pesterConfigJsonPath) || fs31.existsSync(pesterPs1Path)) {
|
|
33275
33356
|
return "pester";
|
|
33276
33357
|
}
|
|
33277
33358
|
} catch {}
|
|
@@ -33299,12 +33380,12 @@ async function detectTestFramework(cwd) {
|
|
|
33299
33380
|
return "none";
|
|
33300
33381
|
}
|
|
33301
33382
|
function detectPhpTest(cwd) {
|
|
33302
|
-
if (
|
|
33383
|
+
if (fs31.existsSync(path65.join(cwd, "artisan")) && fs31.existsSync(path65.join(cwd, "composer.json"))) {
|
|
33303
33384
|
return "php-artisan";
|
|
33304
33385
|
}
|
|
33305
|
-
if (
|
|
33386
|
+
if (fs31.existsSync(path65.join(cwd, "Pest.php")))
|
|
33306
33387
|
return "pest";
|
|
33307
|
-
if (
|
|
33388
|
+
if (fs31.existsSync(path65.join(cwd, "phpunit.xml")) || fs31.existsSync(path65.join(cwd, "phpunit.xml.dist"))) {
|
|
33308
33389
|
return "phpunit";
|
|
33309
33390
|
}
|
|
33310
33391
|
return null;
|
|
@@ -33327,12 +33408,12 @@ function isTestDirectoryPath(normalizedPath) {
|
|
|
33327
33408
|
return normalizedPath.split("/").some((segment) => TEST_DIRECTORY_NAMES.includes(segment));
|
|
33328
33409
|
}
|
|
33329
33410
|
function resolveWorkspacePath(file, workingDir) {
|
|
33330
|
-
return
|
|
33411
|
+
return path65.isAbsolute(file) ? path65.resolve(file) : path65.resolve(workingDir, file);
|
|
33331
33412
|
}
|
|
33332
33413
|
function toWorkspaceOutputPath(absolutePath2, workingDir, preferRelative) {
|
|
33333
33414
|
if (!preferRelative)
|
|
33334
33415
|
return absolutePath2;
|
|
33335
|
-
return
|
|
33416
|
+
return path65.relative(workingDir, absolutePath2);
|
|
33336
33417
|
}
|
|
33337
33418
|
function dedupePush(target, value) {
|
|
33338
33419
|
if (!target.includes(value)) {
|
|
@@ -33375,18 +33456,18 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
|
|
|
33375
33456
|
}
|
|
33376
33457
|
}
|
|
33377
33458
|
function getRepoLevelCandidateDirectories(workingDir, relativePath2, ext) {
|
|
33378
|
-
const relativeDir =
|
|
33459
|
+
const relativeDir = path65.dirname(relativePath2);
|
|
33379
33460
|
const nestedRelativeDir = relativeDir === "." ? "" : relativeDir;
|
|
33380
33461
|
const directories = TEST_DIRECTORY_NAMES.flatMap((dirName) => {
|
|
33381
|
-
const rootDir =
|
|
33382
|
-
return nestedRelativeDir ? [rootDir,
|
|
33462
|
+
const rootDir = path65.join(workingDir, dirName);
|
|
33463
|
+
return nestedRelativeDir ? [rootDir, path65.join(rootDir, nestedRelativeDir)] : [rootDir];
|
|
33383
33464
|
});
|
|
33384
33465
|
const normalizedRelativePath = relativePath2.replace(/\\/g, "/");
|
|
33385
33466
|
if (ext === ".java" && normalizedRelativePath.startsWith("src/main/java/")) {
|
|
33386
|
-
directories.push(
|
|
33467
|
+
directories.push(path65.join(workingDir, "src/test/java", path65.dirname(normalizedRelativePath.slice("src/main/java/".length))));
|
|
33387
33468
|
}
|
|
33388
33469
|
if ((ext === ".kt" || ext === ".java") && normalizedRelativePath.startsWith("src/main/kotlin/")) {
|
|
33389
|
-
directories.push(
|
|
33470
|
+
directories.push(path65.join(workingDir, "src/test/kotlin", path65.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
|
|
33390
33471
|
}
|
|
33391
33472
|
return [...new Set(directories)];
|
|
33392
33473
|
}
|
|
@@ -33416,23 +33497,23 @@ function isLanguageSpecificTestFile(basename14) {
|
|
|
33416
33497
|
}
|
|
33417
33498
|
function isConventionTestFilePath(filePath) {
|
|
33418
33499
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
33419
|
-
const basename14 =
|
|
33500
|
+
const basename14 = path65.basename(filePath);
|
|
33420
33501
|
return hasCompoundTestExtension(basename14) || basename14.includes(".spec.") || basename14.includes(".test.") || isLanguageSpecificTestFile(basename14) || isTestDirectoryPath(normalizedPath);
|
|
33421
33502
|
}
|
|
33422
33503
|
function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
33423
33504
|
const testFiles = [];
|
|
33424
33505
|
for (const file of sourceFiles) {
|
|
33425
33506
|
const absoluteFile = resolveWorkspacePath(file, workingDir);
|
|
33426
|
-
const relativeFile =
|
|
33427
|
-
const basename14 =
|
|
33428
|
-
const dirname26 =
|
|
33429
|
-
const preferRelativeOutput = !
|
|
33507
|
+
const relativeFile = path65.relative(workingDir, absoluteFile);
|
|
33508
|
+
const basename14 = path65.basename(absoluteFile);
|
|
33509
|
+
const dirname26 = path65.dirname(absoluteFile);
|
|
33510
|
+
const preferRelativeOutput = !path65.isAbsolute(file);
|
|
33430
33511
|
if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file)) {
|
|
33431
33512
|
dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
|
|
33432
33513
|
continue;
|
|
33433
33514
|
}
|
|
33434
33515
|
const nameWithoutExt = basename14.replace(/\.[^.]+$/, "");
|
|
33435
|
-
const ext =
|
|
33516
|
+
const ext = path65.extname(basename14);
|
|
33436
33517
|
const genericTestNames = [
|
|
33437
33518
|
`${nameWithoutExt}.spec${ext}`,
|
|
33438
33519
|
`${nameWithoutExt}.test${ext}`
|
|
@@ -33441,7 +33522,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
|
33441
33522
|
const colocatedCandidates = [
|
|
33442
33523
|
...genericTestNames,
|
|
33443
33524
|
...languageSpecificTestNames
|
|
33444
|
-
].map((candidateName) =>
|
|
33525
|
+
].map((candidateName) => path65.join(dirname26, candidateName));
|
|
33445
33526
|
const testDirectoryNames = [
|
|
33446
33527
|
basename14,
|
|
33447
33528
|
...genericTestNames,
|
|
@@ -33450,11 +33531,11 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
|
33450
33531
|
const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
|
|
33451
33532
|
const possibleTestFiles = [
|
|
33452
33533
|
...colocatedCandidates,
|
|
33453
|
-
...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) =>
|
|
33454
|
-
...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) =>
|
|
33534
|
+
...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path65.join(dirname26, dirName, candidateName))),
|
|
33535
|
+
...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path65.join(candidateDir, candidateName)))
|
|
33455
33536
|
];
|
|
33456
33537
|
for (const testFile of possibleTestFiles) {
|
|
33457
|
-
if (
|
|
33538
|
+
if (fs31.existsSync(testFile)) {
|
|
33458
33539
|
dedupePush(testFiles, toWorkspaceOutputPath(testFile, workingDir, preferRelativeOutput));
|
|
33459
33540
|
}
|
|
33460
33541
|
}
|
|
@@ -33471,8 +33552,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
33471
33552
|
for (const testFile of candidateTestFiles) {
|
|
33472
33553
|
try {
|
|
33473
33554
|
const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
|
|
33474
|
-
const content =
|
|
33475
|
-
const testDir =
|
|
33555
|
+
const content = fs31.readFileSync(absoluteTestFile, "utf-8");
|
|
33556
|
+
const testDir = path65.dirname(absoluteTestFile);
|
|
33476
33557
|
const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
|
|
33477
33558
|
let match;
|
|
33478
33559
|
match = importRegex.exec(content);
|
|
@@ -33480,8 +33561,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
33480
33561
|
const importPath = match[1];
|
|
33481
33562
|
let resolvedImport;
|
|
33482
33563
|
if (importPath.startsWith(".")) {
|
|
33483
|
-
resolvedImport =
|
|
33484
|
-
const existingExt =
|
|
33564
|
+
resolvedImport = path65.resolve(testDir, importPath);
|
|
33565
|
+
const existingExt = path65.extname(resolvedImport);
|
|
33485
33566
|
if (!existingExt) {
|
|
33486
33567
|
for (const extToTry of [
|
|
33487
33568
|
".ts",
|
|
@@ -33492,7 +33573,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
33492
33573
|
".cjs"
|
|
33493
33574
|
]) {
|
|
33494
33575
|
const withExt = resolvedImport + extToTry;
|
|
33495
|
-
if (absoluteSourceFiles.includes(withExt) ||
|
|
33576
|
+
if (absoluteSourceFiles.includes(withExt) || fs31.existsSync(withExt)) {
|
|
33496
33577
|
resolvedImport = withExt;
|
|
33497
33578
|
break;
|
|
33498
33579
|
}
|
|
@@ -33501,12 +33582,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
33501
33582
|
} else {
|
|
33502
33583
|
continue;
|
|
33503
33584
|
}
|
|
33504
|
-
const importBasename =
|
|
33505
|
-
const importDir =
|
|
33585
|
+
const importBasename = path65.basename(resolvedImport, path65.extname(resolvedImport));
|
|
33586
|
+
const importDir = path65.dirname(resolvedImport);
|
|
33506
33587
|
for (const sourceFile of absoluteSourceFiles) {
|
|
33507
|
-
const sourceDir =
|
|
33508
|
-
const sourceBasename =
|
|
33509
|
-
const isRelatedDir = importDir === sourceDir || importDir ===
|
|
33588
|
+
const sourceDir = path65.dirname(sourceFile);
|
|
33589
|
+
const sourceBasename = path65.basename(sourceFile, path65.extname(sourceFile));
|
|
33590
|
+
const isRelatedDir = importDir === sourceDir || importDir === path65.join(sourceDir, "__tests__") || importDir === path65.join(sourceDir, "tests") || importDir === path65.join(sourceDir, "test") || importDir === path65.join(sourceDir, "spec");
|
|
33510
33591
|
if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
|
|
33511
33592
|
dedupePush(testFiles, testFile);
|
|
33512
33593
|
break;
|
|
@@ -33519,8 +33600,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
33519
33600
|
while (match !== null) {
|
|
33520
33601
|
const importPath = match[1];
|
|
33521
33602
|
if (importPath.startsWith(".")) {
|
|
33522
|
-
let resolvedImport =
|
|
33523
|
-
const existingExt =
|
|
33603
|
+
let resolvedImport = path65.resolve(testDir, importPath);
|
|
33604
|
+
const existingExt = path65.extname(resolvedImport);
|
|
33524
33605
|
if (!existingExt) {
|
|
33525
33606
|
for (const extToTry of [
|
|
33526
33607
|
".ts",
|
|
@@ -33531,18 +33612,18 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
33531
33612
|
".cjs"
|
|
33532
33613
|
]) {
|
|
33533
33614
|
const withExt = resolvedImport + extToTry;
|
|
33534
|
-
if (absoluteSourceFiles.includes(withExt) ||
|
|
33615
|
+
if (absoluteSourceFiles.includes(withExt) || fs31.existsSync(withExt)) {
|
|
33535
33616
|
resolvedImport = withExt;
|
|
33536
33617
|
break;
|
|
33537
33618
|
}
|
|
33538
33619
|
}
|
|
33539
33620
|
}
|
|
33540
|
-
const importDir =
|
|
33541
|
-
const importBasename =
|
|
33621
|
+
const importDir = path65.dirname(resolvedImport);
|
|
33622
|
+
const importBasename = path65.basename(resolvedImport, path65.extname(resolvedImport));
|
|
33542
33623
|
for (const sourceFile of absoluteSourceFiles) {
|
|
33543
|
-
const sourceDir =
|
|
33544
|
-
const sourceBasename =
|
|
33545
|
-
const isRelatedDir = importDir === sourceDir || importDir ===
|
|
33624
|
+
const sourceDir = path65.dirname(sourceFile);
|
|
33625
|
+
const sourceBasename = path65.basename(sourceFile, path65.extname(sourceFile));
|
|
33626
|
+
const isRelatedDir = importDir === sourceDir || importDir === path65.join(sourceDir, "__tests__") || importDir === path65.join(sourceDir, "tests") || importDir === path65.join(sourceDir, "test") || importDir === path65.join(sourceDir, "spec");
|
|
33546
33627
|
if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
|
|
33547
33628
|
dedupePush(testFiles, testFile);
|
|
33548
33629
|
break;
|
|
@@ -33662,8 +33743,8 @@ function buildTestCommand(framework, scope, files, coverage, baseDir, bail) {
|
|
|
33662
33743
|
return ["mvn", "test"];
|
|
33663
33744
|
case "gradle": {
|
|
33664
33745
|
const isWindows = process.platform === "win32";
|
|
33665
|
-
const hasGradlewBat =
|
|
33666
|
-
const hasGradlew =
|
|
33746
|
+
const hasGradlewBat = fs31.existsSync(path65.join(baseDir, "gradlew.bat"));
|
|
33747
|
+
const hasGradlew = fs31.existsSync(path65.join(baseDir, "gradlew"));
|
|
33667
33748
|
if (hasGradlewBat && isWindows)
|
|
33668
33749
|
return ["gradlew.bat", "test"];
|
|
33669
33750
|
if (hasGradlew)
|
|
@@ -33680,7 +33761,7 @@ function buildTestCommand(framework, scope, files, coverage, baseDir, bail) {
|
|
|
33680
33761
|
"cmake-build-release",
|
|
33681
33762
|
"out"
|
|
33682
33763
|
];
|
|
33683
|
-
const actualBuildDir = buildDirCandidates.find((d) =>
|
|
33764
|
+
const actualBuildDir = buildDirCandidates.find((d) => fs31.existsSync(path65.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
|
|
33684
33765
|
return ["ctest", "--test-dir", actualBuildDir];
|
|
33685
33766
|
}
|
|
33686
33767
|
case "swift-test":
|
|
@@ -33730,7 +33811,7 @@ function buildTestCommand(framework, scope, files, coverage, baseDir, bail) {
|
|
|
33730
33811
|
}
|
|
33731
33812
|
}
|
|
33732
33813
|
function phpVendorBin2(name) {
|
|
33733
|
-
return
|
|
33814
|
+
return path65.join("vendor", "bin", process.platform === "win32" ? `${name}.bat` : name);
|
|
33734
33815
|
}
|
|
33735
33816
|
function mapFrameworkStatusToResult(status) {
|
|
33736
33817
|
if (typeof status !== "string")
|
|
@@ -34153,13 +34234,13 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail
|
|
|
34153
34234
|
};
|
|
34154
34235
|
}
|
|
34155
34236
|
const startTime = Date.now();
|
|
34156
|
-
const vitestJsonOutputPath = framework === "vitest" ?
|
|
34237
|
+
const vitestJsonOutputPath = framework === "vitest" ? path65.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
|
|
34157
34238
|
try {
|
|
34158
34239
|
if (vitestJsonOutputPath) {
|
|
34159
34240
|
try {
|
|
34160
|
-
|
|
34161
|
-
if (
|
|
34162
|
-
|
|
34241
|
+
fs31.mkdirSync(path65.dirname(vitestJsonOutputPath), { recursive: true });
|
|
34242
|
+
if (fs31.existsSync(vitestJsonOutputPath)) {
|
|
34243
|
+
fs31.unlinkSync(vitestJsonOutputPath);
|
|
34163
34244
|
}
|
|
34164
34245
|
} catch {}
|
|
34165
34246
|
}
|
|
@@ -34185,8 +34266,8 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail
|
|
|
34185
34266
|
}
|
|
34186
34267
|
if (vitestJsonOutputPath) {
|
|
34187
34268
|
try {
|
|
34188
|
-
if (
|
|
34189
|
-
const vitestJsonOutput =
|
|
34269
|
+
if (fs31.existsSync(vitestJsonOutputPath)) {
|
|
34270
|
+
const vitestJsonOutput = fs31.readFileSync(vitestJsonOutputPath, "utf-8");
|
|
34190
34271
|
if (vitestJsonOutput.trim().length > 0) {
|
|
34191
34272
|
output += (output ? `
|
|
34192
34273
|
` : "") + vitestJsonOutput;
|
|
@@ -34326,10 +34407,10 @@ var SKIP_DIRECTORIES = new Set([
|
|
|
34326
34407
|
]);
|
|
34327
34408
|
function normalizeHistoryTestFile(testFile, workingDir) {
|
|
34328
34409
|
const normalized = testFile.replace(/\\/g, "/");
|
|
34329
|
-
if (!
|
|
34410
|
+
if (!path65.isAbsolute(testFile))
|
|
34330
34411
|
return normalized;
|
|
34331
|
-
const relative9 =
|
|
34332
|
-
if (relative9.startsWith("..") ||
|
|
34412
|
+
const relative9 = path65.relative(workingDir, testFile);
|
|
34413
|
+
if (relative9.startsWith("..") || path65.isAbsolute(relative9)) {
|
|
34333
34414
|
return normalized;
|
|
34334
34415
|
}
|
|
34335
34416
|
return relative9.replace(/\\/g, "/");
|
|
@@ -34567,7 +34648,7 @@ var test_runner = createSwarmTool({
|
|
|
34567
34648
|
const sourceFiles = args.files.filter((file) => {
|
|
34568
34649
|
if (directTestFiles.includes(file))
|
|
34569
34650
|
return false;
|
|
34570
|
-
const ext =
|
|
34651
|
+
const ext = path65.extname(file).toLowerCase();
|
|
34571
34652
|
return SOURCE_EXTENSIONS.has(ext);
|
|
34572
34653
|
});
|
|
34573
34654
|
const invalidFiles = args.files.filter((file) => !directTestFiles.includes(file) && !sourceFiles.includes(file));
|
|
@@ -34613,7 +34694,7 @@ var test_runner = createSwarmTool({
|
|
|
34613
34694
|
if (isConventionTestFilePath(f)) {
|
|
34614
34695
|
return false;
|
|
34615
34696
|
}
|
|
34616
|
-
const ext =
|
|
34697
|
+
const ext = path65.extname(f).toLowerCase();
|
|
34617
34698
|
return SOURCE_EXTENSIONS.has(ext);
|
|
34618
34699
|
});
|
|
34619
34700
|
if (sourceFiles.length === 0) {
|
|
@@ -34663,7 +34744,7 @@ var test_runner = createSwarmTool({
|
|
|
34663
34744
|
if (isConventionTestFilePath(f)) {
|
|
34664
34745
|
return false;
|
|
34665
34746
|
}
|
|
34666
|
-
const ext =
|
|
34747
|
+
const ext = path65.extname(f).toLowerCase();
|
|
34667
34748
|
return SOURCE_EXTENSIONS.has(ext);
|
|
34668
34749
|
});
|
|
34669
34750
|
if (sourceFiles.length === 0) {
|
|
@@ -34715,8 +34796,8 @@ var test_runner = createSwarmTool({
|
|
|
34715
34796
|
}
|
|
34716
34797
|
if (impactResult.impactedTests.length > 0) {
|
|
34717
34798
|
testFiles = impactResult.impactedTests.map((absPath) => {
|
|
34718
|
-
const relativePath2 =
|
|
34719
|
-
return
|
|
34799
|
+
const relativePath2 = path65.relative(workingDir, absPath);
|
|
34800
|
+
return path65.isAbsolute(relativePath2) ? absPath : relativePath2;
|
|
34720
34801
|
});
|
|
34721
34802
|
} else {
|
|
34722
34803
|
graphFallbackReason = "no impacted tests found via impact analysis, falling back to graph";
|
|
@@ -34811,8 +34892,8 @@ function validateDirectoryPath(dir) {
|
|
|
34811
34892
|
if (dir.includes("..")) {
|
|
34812
34893
|
throw new Error("Directory path must not contain path traversal sequences");
|
|
34813
34894
|
}
|
|
34814
|
-
const normalized =
|
|
34815
|
-
const absolutePath2 =
|
|
34895
|
+
const normalized = path66.normalize(dir);
|
|
34896
|
+
const absolutePath2 = path66.isAbsolute(normalized) ? normalized : path66.resolve(normalized);
|
|
34816
34897
|
return absolutePath2;
|
|
34817
34898
|
}
|
|
34818
34899
|
function validateTimeout(timeoutMs, defaultValue) {
|
|
@@ -34835,9 +34916,9 @@ function validateTimeout(timeoutMs, defaultValue) {
|
|
|
34835
34916
|
}
|
|
34836
34917
|
function getPackageVersion(dir) {
|
|
34837
34918
|
try {
|
|
34838
|
-
const packagePath =
|
|
34839
|
-
if (
|
|
34840
|
-
const content =
|
|
34919
|
+
const packagePath = path66.join(dir, "package.json");
|
|
34920
|
+
if (fs32.existsSync(packagePath)) {
|
|
34921
|
+
const content = fs32.readFileSync(packagePath, "utf-8");
|
|
34841
34922
|
const pkg = JSON.parse(content);
|
|
34842
34923
|
return pkg.version ?? null;
|
|
34843
34924
|
}
|
|
@@ -34846,9 +34927,9 @@ function getPackageVersion(dir) {
|
|
|
34846
34927
|
}
|
|
34847
34928
|
function getChangelogVersion(dir) {
|
|
34848
34929
|
try {
|
|
34849
|
-
const changelogPath =
|
|
34850
|
-
if (
|
|
34851
|
-
const content =
|
|
34930
|
+
const changelogPath = path66.join(dir, "CHANGELOG.md");
|
|
34931
|
+
if (fs32.existsSync(changelogPath)) {
|
|
34932
|
+
const content = fs32.readFileSync(changelogPath, "utf-8");
|
|
34852
34933
|
const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
|
|
34853
34934
|
if (match) {
|
|
34854
34935
|
return match[1];
|
|
@@ -34860,10 +34941,10 @@ function getChangelogVersion(dir) {
|
|
|
34860
34941
|
function getVersionFileVersion(dir) {
|
|
34861
34942
|
const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
|
|
34862
34943
|
for (const file of possibleFiles) {
|
|
34863
|
-
const filePath =
|
|
34864
|
-
if (
|
|
34944
|
+
const filePath = path66.join(dir, file);
|
|
34945
|
+
if (fs32.existsSync(filePath)) {
|
|
34865
34946
|
try {
|
|
34866
|
-
const content =
|
|
34947
|
+
const content = fs32.readFileSync(filePath, "utf-8").trim();
|
|
34867
34948
|
const match = content.match(/(\d+\.\d+\.\d+)/);
|
|
34868
34949
|
if (match) {
|
|
34869
34950
|
return match[1];
|
|
@@ -34876,9 +34957,9 @@ function getVersionFileVersion(dir) {
|
|
|
34876
34957
|
async function runVersionCheck(dir, _timeoutMs) {
|
|
34877
34958
|
const startTime = Date.now();
|
|
34878
34959
|
try {
|
|
34879
|
-
const packageVersion =
|
|
34880
|
-
const changelogVersion =
|
|
34881
|
-
const versionFileVersion =
|
|
34960
|
+
const packageVersion = _internals54.getPackageVersion(dir);
|
|
34961
|
+
const changelogVersion = _internals54.getChangelogVersion(dir);
|
|
34962
|
+
const versionFileVersion = _internals54.getVersionFileVersion(dir);
|
|
34882
34963
|
const versions = [];
|
|
34883
34964
|
if (packageVersion)
|
|
34884
34965
|
versions.push(`package.json: ${packageVersion}`);
|
|
@@ -35242,7 +35323,7 @@ async function runPreflight(dir, phase, config) {
|
|
|
35242
35323
|
const reportId = `preflight-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
35243
35324
|
let validatedDir;
|
|
35244
35325
|
try {
|
|
35245
|
-
validatedDir =
|
|
35326
|
+
validatedDir = _internals54.validateDirectoryPath(dir);
|
|
35246
35327
|
} catch (error2) {
|
|
35247
35328
|
return {
|
|
35248
35329
|
id: reportId,
|
|
@@ -35262,7 +35343,7 @@ async function runPreflight(dir, phase, config) {
|
|
|
35262
35343
|
}
|
|
35263
35344
|
let validatedTimeout;
|
|
35264
35345
|
try {
|
|
35265
|
-
validatedTimeout =
|
|
35346
|
+
validatedTimeout = _internals54.validateTimeout(config?.checkTimeoutMs, DEFAULT_CONFIG.checkTimeoutMs);
|
|
35266
35347
|
} catch (error2) {
|
|
35267
35348
|
return {
|
|
35268
35349
|
id: reportId,
|
|
@@ -35303,12 +35384,12 @@ async function runPreflight(dir, phase, config) {
|
|
|
35303
35384
|
});
|
|
35304
35385
|
const checks = [];
|
|
35305
35386
|
log("[Preflight] Running lint check...");
|
|
35306
|
-
const lintResult = await
|
|
35387
|
+
const lintResult = await _internals54.runLintCheck(validatedDir, cfg.linter, cfg.checkTimeoutMs);
|
|
35307
35388
|
checks.push(lintResult);
|
|
35308
35389
|
log(`[Preflight] Lint check: ${lintResult.status} ${lintResult.message}`);
|
|
35309
35390
|
if (!cfg.skipTests) {
|
|
35310
35391
|
log("[Preflight] Running tests check...");
|
|
35311
|
-
const testsResult = await
|
|
35392
|
+
const testsResult = await _internals54.runTestsCheck(validatedDir, cfg.testScope, cfg.checkTimeoutMs);
|
|
35312
35393
|
checks.push(testsResult);
|
|
35313
35394
|
log(`[Preflight] Tests check: ${testsResult.status} ${testsResult.message}`);
|
|
35314
35395
|
} else {
|
|
@@ -35320,7 +35401,7 @@ async function runPreflight(dir, phase, config) {
|
|
|
35320
35401
|
}
|
|
35321
35402
|
if (!cfg.skipSecrets) {
|
|
35322
35403
|
log("[Preflight] Running secrets check...");
|
|
35323
|
-
const secretsResult = await
|
|
35404
|
+
const secretsResult = await _internals54.runSecretsCheck(validatedDir, cfg.checkTimeoutMs);
|
|
35324
35405
|
checks.push(secretsResult);
|
|
35325
35406
|
log(`[Preflight] Secrets check: ${secretsResult.status} ${secretsResult.message}`);
|
|
35326
35407
|
} else {
|
|
@@ -35332,7 +35413,7 @@ async function runPreflight(dir, phase, config) {
|
|
|
35332
35413
|
}
|
|
35333
35414
|
if (!cfg.skipEvidence) {
|
|
35334
35415
|
log("[Preflight] Running evidence check...");
|
|
35335
|
-
const evidenceResult = await
|
|
35416
|
+
const evidenceResult = await _internals54.runEvidenceCheck(validatedDir);
|
|
35336
35417
|
checks.push(evidenceResult);
|
|
35337
35418
|
log(`[Preflight] Evidence check: ${evidenceResult.status} ${evidenceResult.message}`);
|
|
35338
35419
|
} else {
|
|
@@ -35343,12 +35424,12 @@ async function runPreflight(dir, phase, config) {
|
|
|
35343
35424
|
});
|
|
35344
35425
|
}
|
|
35345
35426
|
log("[Preflight] Running requirement coverage check...");
|
|
35346
|
-
const reqCoverageResult = await
|
|
35427
|
+
const reqCoverageResult = await _internals54.runRequirementCoverageCheck(validatedDir, phase);
|
|
35347
35428
|
checks.push(reqCoverageResult);
|
|
35348
35429
|
log(`[Preflight] Requirement coverage check: ${reqCoverageResult.status} ${reqCoverageResult.message}`);
|
|
35349
35430
|
if (!cfg.skipVersion) {
|
|
35350
35431
|
log("[Preflight] Running version check...");
|
|
35351
|
-
const versionResult = await
|
|
35432
|
+
const versionResult = await _internals54.runVersionCheck(validatedDir, cfg.checkTimeoutMs);
|
|
35352
35433
|
checks.push(versionResult);
|
|
35353
35434
|
log(`[Preflight] Version check: ${versionResult.status} ${versionResult.message}`);
|
|
35354
35435
|
} else {
|
|
@@ -35411,10 +35492,10 @@ function formatPreflightMarkdown(report) {
|
|
|
35411
35492
|
async function handlePreflightCommand(directory, _args) {
|
|
35412
35493
|
const plan = await loadPlan(directory);
|
|
35413
35494
|
const phase = plan?.current_phase ?? 1;
|
|
35414
|
-
const report = await
|
|
35415
|
-
return
|
|
35495
|
+
const report = await _internals54.runPreflight(directory, phase);
|
|
35496
|
+
return _internals54.formatPreflightMarkdown(report);
|
|
35416
35497
|
}
|
|
35417
|
-
var
|
|
35498
|
+
var _internals54 = {
|
|
35418
35499
|
runPreflight,
|
|
35419
35500
|
formatPreflightMarkdown,
|
|
35420
35501
|
handlePreflightCommand,
|
|
@@ -35616,8 +35697,8 @@ async function handleQaGatesCommand(directory, args, sessionID) {
|
|
|
35616
35697
|
}
|
|
35617
35698
|
|
|
35618
35699
|
// src/commands/reset.ts
|
|
35619
|
-
import * as
|
|
35620
|
-
import * as
|
|
35700
|
+
import * as fs34 from "fs";
|
|
35701
|
+
import * as path68 from "path";
|
|
35621
35702
|
|
|
35622
35703
|
// src/background/circuit-breaker.ts
|
|
35623
35704
|
class CircuitBreaker {
|
|
@@ -36310,15 +36391,15 @@ function resetAutomationManager() {
|
|
|
36310
36391
|
}
|
|
36311
36392
|
|
|
36312
36393
|
// src/commands/reset-backup.ts
|
|
36313
|
-
import * as
|
|
36314
|
-
import * as
|
|
36394
|
+
import * as fs33 from "fs";
|
|
36395
|
+
import * as path67 from "path";
|
|
36315
36396
|
var RESET_BACKUP_RETENTION = 5;
|
|
36316
36397
|
function backupSwarmStateBeforeReset(directory, kind, relEntries) {
|
|
36317
36398
|
const warnings = [];
|
|
36318
36399
|
const copied = [];
|
|
36319
|
-
const swarmDir =
|
|
36400
|
+
const swarmDir = path67.join(directory, ".swarm");
|
|
36320
36401
|
try {
|
|
36321
|
-
const stat4 =
|
|
36402
|
+
const stat4 = fs33.lstatSync(swarmDir);
|
|
36322
36403
|
if (stat4.isSymbolicLink() || !stat4.isDirectory()) {
|
|
36323
36404
|
return { backupDir: null, copied, warnings };
|
|
36324
36405
|
}
|
|
@@ -36326,12 +36407,12 @@ function backupSwarmStateBeforeReset(directory, kind, relEntries) {
|
|
|
36326
36407
|
return { backupDir: null, copied, warnings };
|
|
36327
36408
|
}
|
|
36328
36409
|
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
36329
|
-
const backupsRoot =
|
|
36330
|
-
const backupDir =
|
|
36410
|
+
const backupsRoot = path67.join(swarmDir, "reset-backups");
|
|
36411
|
+
const backupDir = path67.join(backupsRoot, `${kind}-${timestamp}`);
|
|
36331
36412
|
let backupDirCreated = false;
|
|
36332
36413
|
const ensureBackupDir = () => {
|
|
36333
36414
|
if (!backupDirCreated) {
|
|
36334
|
-
|
|
36415
|
+
fs33.mkdirSync(backupDir, { recursive: true });
|
|
36335
36416
|
backupDirCreated = true;
|
|
36336
36417
|
}
|
|
36337
36418
|
};
|
|
@@ -36343,13 +36424,13 @@ function backupSwarmStateBeforeReset(directory, kind, relEntries) {
|
|
|
36343
36424
|
warnings.push(`skipped backup of ${rel} (path validation failed)`);
|
|
36344
36425
|
continue;
|
|
36345
36426
|
}
|
|
36346
|
-
if (!
|
|
36427
|
+
if (!fs33.existsSync(src))
|
|
36347
36428
|
continue;
|
|
36348
36429
|
try {
|
|
36349
36430
|
ensureBackupDir();
|
|
36350
|
-
const dest =
|
|
36351
|
-
|
|
36352
|
-
|
|
36431
|
+
const dest = path67.join(backupDir, rel);
|
|
36432
|
+
fs33.mkdirSync(path67.dirname(dest), { recursive: true });
|
|
36433
|
+
fs33.cpSync(src, dest, { recursive: true });
|
|
36353
36434
|
copied.push(rel);
|
|
36354
36435
|
} catch (err) {
|
|
36355
36436
|
warnings.push(`failed to back up ${rel}: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -36358,7 +36439,7 @@ function backupSwarmStateBeforeReset(directory, kind, relEntries) {
|
|
|
36358
36439
|
if (copied.length === 0) {
|
|
36359
36440
|
if (backupDirCreated) {
|
|
36360
36441
|
try {
|
|
36361
|
-
|
|
36442
|
+
fs33.rmSync(backupDir, { recursive: true, force: true });
|
|
36362
36443
|
} catch {}
|
|
36363
36444
|
}
|
|
36364
36445
|
return { backupDir: null, copied, warnings };
|
|
@@ -36368,10 +36449,10 @@ function backupSwarmStateBeforeReset(directory, kind, relEntries) {
|
|
|
36368
36449
|
}
|
|
36369
36450
|
function pruneOldResetBackups(backupsRoot, warnings) {
|
|
36370
36451
|
try {
|
|
36371
|
-
const entries =
|
|
36452
|
+
const entries = fs33.readdirSync(backupsRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort().reverse();
|
|
36372
36453
|
for (const stale of entries.slice(RESET_BACKUP_RETENTION)) {
|
|
36373
36454
|
try {
|
|
36374
|
-
|
|
36455
|
+
fs33.rmSync(path67.join(backupsRoot, stale), {
|
|
36375
36456
|
recursive: true,
|
|
36376
36457
|
force: true
|
|
36377
36458
|
});
|
|
@@ -36385,7 +36466,7 @@ function pruneOldResetBackups(backupsRoot, warnings) {
|
|
|
36385
36466
|
}
|
|
36386
36467
|
|
|
36387
36468
|
// src/commands/reset.ts
|
|
36388
|
-
var
|
|
36469
|
+
var _internals55 = {
|
|
36389
36470
|
backupSwarmStateBeforeReset
|
|
36390
36471
|
};
|
|
36391
36472
|
async function handleResetCommand(directory, args) {
|
|
@@ -36419,12 +36500,12 @@ async function handleResetCommand(directory, args) {
|
|
|
36419
36500
|
];
|
|
36420
36501
|
const results = [];
|
|
36421
36502
|
try {
|
|
36422
|
-
const backup =
|
|
36503
|
+
const backup = _internals55.backupSwarmStateBeforeReset(directory, "reset", [
|
|
36423
36504
|
...filesToReset,
|
|
36424
36505
|
"summaries"
|
|
36425
36506
|
]);
|
|
36426
36507
|
if (backup.backupDir && backup.copied.length > 0) {
|
|
36427
|
-
const rel =
|
|
36508
|
+
const rel = path68.relative(directory, backup.backupDir);
|
|
36428
36509
|
results.push(`- \uD83D\uDCE6 Backed up ${backup.copied.length} item(s) to ${rel}/ (restore by copying files back into .swarm/)`);
|
|
36429
36510
|
}
|
|
36430
36511
|
for (const w of backup.warnings) {
|
|
@@ -36436,8 +36517,8 @@ async function handleResetCommand(directory, args) {
|
|
|
36436
36517
|
for (const filename of filesToReset) {
|
|
36437
36518
|
try {
|
|
36438
36519
|
const resolvedPath = validateSwarmPath(directory, filename);
|
|
36439
|
-
if (
|
|
36440
|
-
|
|
36520
|
+
if (fs34.existsSync(resolvedPath)) {
|
|
36521
|
+
fs34.unlinkSync(resolvedPath);
|
|
36441
36522
|
results.push(`- \u2705 Deleted ${filename}`);
|
|
36442
36523
|
} else {
|
|
36443
36524
|
results.push(`- \u23ED\uFE0F ${filename} not found (skipped)`);
|
|
@@ -36448,9 +36529,9 @@ async function handleResetCommand(directory, args) {
|
|
|
36448
36529
|
}
|
|
36449
36530
|
for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
|
|
36450
36531
|
try {
|
|
36451
|
-
const rootPath =
|
|
36452
|
-
if (
|
|
36453
|
-
|
|
36532
|
+
const rootPath = path68.join(directory, filename);
|
|
36533
|
+
if (fs34.existsSync(rootPath)) {
|
|
36534
|
+
fs34.unlinkSync(rootPath);
|
|
36454
36535
|
results.push(`- \u2705 Deleted ${filename} (root)`);
|
|
36455
36536
|
}
|
|
36456
36537
|
} catch (err) {
|
|
@@ -36465,8 +36546,8 @@ async function handleResetCommand(directory, args) {
|
|
|
36465
36546
|
}
|
|
36466
36547
|
try {
|
|
36467
36548
|
const summariesPath = validateSwarmPath(directory, "summaries");
|
|
36468
|
-
if (
|
|
36469
|
-
|
|
36549
|
+
if (fs34.existsSync(summariesPath)) {
|
|
36550
|
+
fs34.rmSync(summariesPath, { recursive: true, force: true });
|
|
36470
36551
|
results.push("- \u2705 Deleted summaries/ directory");
|
|
36471
36552
|
} else {
|
|
36472
36553
|
results.push("- \u23ED\uFE0F summaries/ not found (skipped)");
|
|
@@ -36485,16 +36566,16 @@ async function handleResetCommand(directory, args) {
|
|
|
36485
36566
|
}
|
|
36486
36567
|
|
|
36487
36568
|
// src/commands/reset-session.ts
|
|
36488
|
-
import * as
|
|
36489
|
-
import * as
|
|
36569
|
+
import * as fs37 from "fs";
|
|
36570
|
+
import * as path71 from "path";
|
|
36490
36571
|
|
|
36491
36572
|
// src/prm/trajectory-store.ts
|
|
36492
|
-
import * as
|
|
36493
|
-
import * as
|
|
36573
|
+
import * as fs35 from "fs/promises";
|
|
36574
|
+
import * as path69 from "path";
|
|
36494
36575
|
init_logger();
|
|
36495
36576
|
var MAX_TRACKED_TRAJECTORY_SESSIONS = 500;
|
|
36496
36577
|
function getTrajectoryPath(sessionId, directory) {
|
|
36497
|
-
const relativePath2 =
|
|
36578
|
+
const relativePath2 = path69.join("trajectories", `${sessionId}.jsonl`);
|
|
36498
36579
|
return validateSwarmPath(directory, relativePath2);
|
|
36499
36580
|
}
|
|
36500
36581
|
var _inMemoryTrajectoryCache = new Map;
|
|
@@ -36524,7 +36605,7 @@ function clearTrajectoryCache(sessionId) {
|
|
|
36524
36605
|
async function readTrajectory(sessionId, directory) {
|
|
36525
36606
|
try {
|
|
36526
36607
|
const trajectoryPath = getTrajectoryPath(sessionId, directory);
|
|
36527
|
-
const content = await
|
|
36608
|
+
const content = await fs35.readFile(trajectoryPath, "utf-8");
|
|
36528
36609
|
const lines = content.split(`
|
|
36529
36610
|
`).filter((line) => line.trim().length > 0);
|
|
36530
36611
|
const entries = [];
|
|
@@ -36549,15 +36630,15 @@ async function cleanupOldTrajectoryFiles(directory, maxAgeDays = 7) {
|
|
|
36549
36630
|
for (const subdir of ["trajectories", "replays"]) {
|
|
36550
36631
|
try {
|
|
36551
36632
|
const dirPath = validateSwarmPath(directory, subdir);
|
|
36552
|
-
const entries = await
|
|
36633
|
+
const entries = await fs35.readdir(dirPath, { withFileTypes: true });
|
|
36553
36634
|
for (const entry of entries) {
|
|
36554
36635
|
if (!entry.isFile())
|
|
36555
36636
|
continue;
|
|
36556
|
-
const filePath =
|
|
36637
|
+
const filePath = path69.join(dirPath, entry.name);
|
|
36557
36638
|
try {
|
|
36558
|
-
const stat5 = await
|
|
36639
|
+
const stat5 = await fs35.stat(filePath);
|
|
36559
36640
|
if (now - stat5.mtimeMs > cutoffMs) {
|
|
36560
|
-
await
|
|
36641
|
+
await fs35.unlink(filePath);
|
|
36561
36642
|
}
|
|
36562
36643
|
} catch {}
|
|
36563
36644
|
}
|
|
@@ -36982,18 +37063,18 @@ function detectPatterns(trajectory, config, lastProcessedStep = 0) {
|
|
|
36982
37063
|
init_logger();
|
|
36983
37064
|
|
|
36984
37065
|
// src/prm/replay.ts
|
|
36985
|
-
import { promises as
|
|
36986
|
-
import
|
|
37066
|
+
import { promises as fs36 } from "fs";
|
|
37067
|
+
import path70 from "path";
|
|
36987
37068
|
init_logger();
|
|
36988
37069
|
function isPathSafe(targetPath, basePath) {
|
|
36989
|
-
const resolvedTarget =
|
|
36990
|
-
const resolvedBase =
|
|
36991
|
-
const rel =
|
|
36992
|
-
return !rel.startsWith("..") && !
|
|
37070
|
+
const resolvedTarget = path70.resolve(targetPath);
|
|
37071
|
+
const resolvedBase = path70.resolve(basePath);
|
|
37072
|
+
const rel = path70.relative(resolvedBase, resolvedTarget);
|
|
37073
|
+
return !rel.startsWith("..") && !path70.isAbsolute(rel);
|
|
36993
37074
|
}
|
|
36994
37075
|
function isWithinReplaysDir(targetPath) {
|
|
36995
|
-
const resolved =
|
|
36996
|
-
const parts = resolved.split(
|
|
37076
|
+
const resolved = path70.resolve(targetPath);
|
|
37077
|
+
const parts = resolved.split(path70.sep);
|
|
36997
37078
|
for (let i = 0;i < parts.length - 1; i++) {
|
|
36998
37079
|
if (parts[i] === ".swarm" && parts[i + 1] === "replays") {
|
|
36999
37080
|
return true;
|
|
@@ -37006,15 +37087,15 @@ function sanitizeFilename(input) {
|
|
|
37006
37087
|
}
|
|
37007
37088
|
async function startReplayRecording(sessionID, directory) {
|
|
37008
37089
|
try {
|
|
37009
|
-
const replayDir =
|
|
37090
|
+
const replayDir = path70.join(directory, ".swarm", "replays");
|
|
37010
37091
|
const safeSessionID = sanitizeFilename(sessionID);
|
|
37011
37092
|
const filename = `${safeSessionID}-${Date.now()}.jsonl`;
|
|
37012
|
-
const filepath =
|
|
37093
|
+
const filepath = path70.join(replayDir, filename);
|
|
37013
37094
|
if (!isPathSafe(filepath, replayDir)) {
|
|
37014
37095
|
advisoryWarn(`[replay] Invalid path detected - path traversal attempt blocked for session ${sessionID}`);
|
|
37015
37096
|
return null;
|
|
37016
37097
|
}
|
|
37017
|
-
await
|
|
37098
|
+
await fs36.mkdir(replayDir, { recursive: true });
|
|
37018
37099
|
return filepath;
|
|
37019
37100
|
} catch (err) {
|
|
37020
37101
|
log(`[replay] Failed to start recording for session ${sessionID}: ${err}`);
|
|
@@ -37034,14 +37115,14 @@ async function recordReplayEntry(artifactPath, sessionID, entry) {
|
|
|
37034
37115
|
};
|
|
37035
37116
|
const line = `${JSON.stringify(fullEntry)}
|
|
37036
37117
|
`;
|
|
37037
|
-
await
|
|
37118
|
+
await fs36.appendFile(artifactPath, line, "utf-8");
|
|
37038
37119
|
} catch (err) {
|
|
37039
37120
|
log(`[replay] Failed to record entry: ${err}`);
|
|
37040
37121
|
}
|
|
37041
37122
|
}
|
|
37042
37123
|
|
|
37043
37124
|
// src/prm/index.ts
|
|
37044
|
-
var
|
|
37125
|
+
var _internals56 = {
|
|
37045
37126
|
getAgentSession,
|
|
37046
37127
|
readTrajectory,
|
|
37047
37128
|
getInMemoryTrajectory,
|
|
@@ -37064,12 +37145,12 @@ function resetPrmSessionState(session, sessionId) {
|
|
|
37064
37145
|
session.prmTrajectoryStep = 0;
|
|
37065
37146
|
session.replayArtifactPath = null;
|
|
37066
37147
|
if (sessionId) {
|
|
37067
|
-
|
|
37148
|
+
_internals56.clearTrajectoryCache(sessionId);
|
|
37068
37149
|
}
|
|
37069
37150
|
}
|
|
37070
37151
|
|
|
37071
37152
|
// src/commands/reset-session.ts
|
|
37072
|
-
var
|
|
37153
|
+
var _internals57 = {
|
|
37073
37154
|
cleanupOrphanedBranches,
|
|
37074
37155
|
backupSwarmStateBeforeReset
|
|
37075
37156
|
};
|
|
@@ -37081,9 +37162,9 @@ function errorMessage(err) {
|
|
|
37081
37162
|
async function handleResetSessionCommand(directory, _args) {
|
|
37082
37163
|
const results = [];
|
|
37083
37164
|
try {
|
|
37084
|
-
const backup =
|
|
37165
|
+
const backup = _internals57.backupSwarmStateBeforeReset(directory, "reset-session", ["session"]);
|
|
37085
37166
|
if (backup.backupDir && backup.copied.length > 0) {
|
|
37086
|
-
const rel =
|
|
37167
|
+
const rel = path71.relative(directory, backup.backupDir);
|
|
37087
37168
|
results.push(`\uD83D\uDCE6 Backed up session state to ${rel}/ (restore by copying files back into .swarm/session/)`);
|
|
37088
37169
|
}
|
|
37089
37170
|
for (const w of backup.warnings) {
|
|
@@ -37095,8 +37176,8 @@ async function handleResetSessionCommand(directory, _args) {
|
|
|
37095
37176
|
let statePath;
|
|
37096
37177
|
try {
|
|
37097
37178
|
statePath = validateSwarmPath(directory, "session/state.json");
|
|
37098
|
-
if (
|
|
37099
|
-
|
|
37179
|
+
if (fs37.existsSync(statePath)) {
|
|
37180
|
+
fs37.unlinkSync(statePath);
|
|
37100
37181
|
results.push("\u2705 Deleted .swarm/session/state.json");
|
|
37101
37182
|
} else {
|
|
37102
37183
|
results.push("\u23ED\uFE0F state.json not found (already clean)");
|
|
@@ -37104,11 +37185,11 @@ async function handleResetSessionCommand(directory, _args) {
|
|
|
37104
37185
|
} catch {
|
|
37105
37186
|
results.push("\u274C Failed to delete state.json");
|
|
37106
37187
|
}
|
|
37107
|
-
const sessionDir = statePath ?
|
|
37188
|
+
const sessionDir = statePath ? path71.dirname(statePath) : undefined;
|
|
37108
37189
|
let sessionFiles = [];
|
|
37109
|
-
if (sessionDir &&
|
|
37190
|
+
if (sessionDir && fs37.existsSync(sessionDir)) {
|
|
37110
37191
|
try {
|
|
37111
|
-
sessionFiles =
|
|
37192
|
+
sessionFiles = fs37.readdirSync(sessionDir);
|
|
37112
37193
|
} catch (err) {
|
|
37113
37194
|
results.push(`\u274C Failed to read session directory: ${errorMessage(err)}`);
|
|
37114
37195
|
}
|
|
@@ -37116,13 +37197,13 @@ async function handleResetSessionCommand(directory, _args) {
|
|
|
37116
37197
|
for (const file of sessionFiles) {
|
|
37117
37198
|
if (file === "state.json")
|
|
37118
37199
|
continue;
|
|
37119
|
-
const filePath =
|
|
37200
|
+
const filePath = path71.join(sessionDir, file);
|
|
37120
37201
|
try {
|
|
37121
|
-
if (!
|
|
37202
|
+
if (!fs37.existsSync(filePath))
|
|
37122
37203
|
continue;
|
|
37123
|
-
if (!
|
|
37204
|
+
if (!fs37.lstatSync(filePath).isFile())
|
|
37124
37205
|
continue;
|
|
37125
|
-
|
|
37206
|
+
fs37.unlinkSync(filePath);
|
|
37126
37207
|
results.push(`\u2713 Deleted ${file}`);
|
|
37127
37208
|
} catch (err) {
|
|
37128
37209
|
results.push(`\u274C Failed to delete ${file}: ${errorMessage(err)}`);
|
|
@@ -37138,17 +37219,17 @@ async function handleResetSessionCommand(directory, _args) {
|
|
|
37138
37219
|
const chainCount = swarmState.delegationChains.size;
|
|
37139
37220
|
swarmState.delegationChains.clear();
|
|
37140
37221
|
results.push(`\u2705 Cleared ${chainCount} delegation chain(s)`);
|
|
37141
|
-
const worktreesDir =
|
|
37222
|
+
const worktreesDir = path71.resolve(path71.dirname(directory), ".swarm-worktrees");
|
|
37142
37223
|
try {
|
|
37143
|
-
if (
|
|
37144
|
-
|
|
37224
|
+
if (fs37.existsSync(worktreesDir)) {
|
|
37225
|
+
fs37.rmSync(worktreesDir, { recursive: true, force: true });
|
|
37145
37226
|
results.push("\u2705 Removed .swarm-worktrees/ directory");
|
|
37146
37227
|
}
|
|
37147
37228
|
} catch (err) {
|
|
37148
37229
|
results.push(`\u26A0\uFE0F Failed to remove .swarm-worktrees/: ${errorMessage(err)}`);
|
|
37149
37230
|
}
|
|
37150
37231
|
try {
|
|
37151
|
-
const branchResult = await
|
|
37232
|
+
const branchResult = await _internals57.cleanupOrphanedBranches(directory, []);
|
|
37152
37233
|
if (branchResult.removed.length > 0) {
|
|
37153
37234
|
results.push(`\u2705 Removed ${branchResult.removed.length} orphan swarm-lane branch(es)`);
|
|
37154
37235
|
}
|
|
@@ -37171,7 +37252,7 @@ async function handleResetSessionCommand(directory, _args) {
|
|
|
37171
37252
|
}
|
|
37172
37253
|
|
|
37173
37254
|
// src/summaries/manager.ts
|
|
37174
|
-
import * as
|
|
37255
|
+
import * as path72 from "path";
|
|
37175
37256
|
var SUMMARY_ID_REGEX = /^S\d+$/;
|
|
37176
37257
|
function sanitizeSummaryId(id) {
|
|
37177
37258
|
if (!id || id.length === 0) {
|
|
@@ -37195,7 +37276,7 @@ function sanitizeSummaryId(id) {
|
|
|
37195
37276
|
}
|
|
37196
37277
|
async function loadFullOutput(directory, id) {
|
|
37197
37278
|
const sanitizedId = sanitizeSummaryId(id);
|
|
37198
|
-
const relativePath2 =
|
|
37279
|
+
const relativePath2 = path72.join("summaries", `${sanitizedId}.json`);
|
|
37199
37280
|
validateSwarmPath(directory, relativePath2);
|
|
37200
37281
|
const content = await readSwarmFileAsync(directory, relativePath2);
|
|
37201
37282
|
if (content === null) {
|
|
@@ -37247,8 +37328,8 @@ ${error2 instanceof Error ? error2.message : String(error2)}`;
|
|
|
37247
37328
|
}
|
|
37248
37329
|
|
|
37249
37330
|
// src/commands/rollback.ts
|
|
37250
|
-
import * as
|
|
37251
|
-
import * as
|
|
37331
|
+
import * as fs38 from "fs";
|
|
37332
|
+
import * as path73 from "path";
|
|
37252
37333
|
init_logger();
|
|
37253
37334
|
function safeParseToolJson(result) {
|
|
37254
37335
|
try {
|
|
@@ -37312,7 +37393,7 @@ async function restoreGitCheckpoint(directory, selected) {
|
|
|
37312
37393
|
source: "checkpoints.json"
|
|
37313
37394
|
};
|
|
37314
37395
|
try {
|
|
37315
|
-
|
|
37396
|
+
fs38.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
|
|
37316
37397
|
`);
|
|
37317
37398
|
} catch (error2) {
|
|
37318
37399
|
log("Failed to write rollback event:", error2 instanceof Error ? error2.message : String(error2));
|
|
@@ -37323,7 +37404,7 @@ async function handleRollbackCommand(directory, args) {
|
|
|
37323
37404
|
const phaseArg = args[0];
|
|
37324
37405
|
if (!phaseArg) {
|
|
37325
37406
|
const manifestPath2 = validateSwarmPath(directory, "checkpoints/manifest.json");
|
|
37326
|
-
if (!
|
|
37407
|
+
if (!fs38.existsSync(manifestPath2)) {
|
|
37327
37408
|
const gitCheckpoints = await listGitCheckpoints(directory);
|
|
37328
37409
|
if (gitCheckpoints) {
|
|
37329
37410
|
return formatGitCheckpointList(gitCheckpoints);
|
|
@@ -37332,7 +37413,7 @@ async function handleRollbackCommand(directory, args) {
|
|
|
37332
37413
|
}
|
|
37333
37414
|
let manifest2;
|
|
37334
37415
|
try {
|
|
37335
|
-
manifest2 = JSON.parse(
|
|
37416
|
+
manifest2 = JSON.parse(fs38.readFileSync(manifestPath2, "utf-8"));
|
|
37336
37417
|
} catch {
|
|
37337
37418
|
return "Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.";
|
|
37338
37419
|
}
|
|
@@ -37362,7 +37443,7 @@ async function handleRollbackCommand(directory, args) {
|
|
|
37362
37443
|
return restoreGitCheckpoint(directory, selected);
|
|
37363
37444
|
}
|
|
37364
37445
|
const manifestPath = validateSwarmPath(directory, "checkpoints/manifest.json");
|
|
37365
|
-
if (!
|
|
37446
|
+
if (!fs38.existsSync(manifestPath)) {
|
|
37366
37447
|
const gitCheckpoints = await listGitCheckpoints(directory);
|
|
37367
37448
|
if (!gitCheckpoints) {
|
|
37368
37449
|
return `Error: No checkpoints found. Cannot rollback to phase ${targetPhase}.`;
|
|
@@ -37375,7 +37456,7 @@ async function handleRollbackCommand(directory, args) {
|
|
|
37375
37456
|
}
|
|
37376
37457
|
let manifest;
|
|
37377
37458
|
try {
|
|
37378
|
-
manifest = JSON.parse(
|
|
37459
|
+
manifest = JSON.parse(fs38.readFileSync(manifestPath, "utf-8"));
|
|
37379
37460
|
} catch {
|
|
37380
37461
|
return `Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.`;
|
|
37381
37462
|
}
|
|
@@ -37385,10 +37466,10 @@ async function handleRollbackCommand(directory, args) {
|
|
|
37385
37466
|
return `Error: Checkpoint for phase ${targetPhase} not found. Available phases: ${available}`;
|
|
37386
37467
|
}
|
|
37387
37468
|
const checkpointDir = validateSwarmPath(directory, `checkpoints/phase-${targetPhase}`);
|
|
37388
|
-
if (!
|
|
37469
|
+
if (!fs38.existsSync(checkpointDir)) {
|
|
37389
37470
|
return `Error: Checkpoint directory for phase ${targetPhase} does not exist.`;
|
|
37390
37471
|
}
|
|
37391
|
-
const checkpointFiles =
|
|
37472
|
+
const checkpointFiles = fs38.readdirSync(checkpointDir);
|
|
37392
37473
|
if (checkpointFiles.length === 0) {
|
|
37393
37474
|
return `Error: Checkpoint for phase ${targetPhase} is empty. Cannot rollback.`;
|
|
37394
37475
|
}
|
|
@@ -37404,10 +37485,10 @@ async function handleRollbackCommand(directory, args) {
|
|
|
37404
37485
|
if (EXCLUDE_FILES.has(file) || file.startsWith("plan-ledger.archived-")) {
|
|
37405
37486
|
continue;
|
|
37406
37487
|
}
|
|
37407
|
-
const src =
|
|
37408
|
-
const dest =
|
|
37488
|
+
const src = path73.join(checkpointDir, file);
|
|
37489
|
+
const dest = path73.join(swarmDir, file);
|
|
37409
37490
|
try {
|
|
37410
|
-
|
|
37491
|
+
fs38.cpSync(src, dest, { recursive: true, force: true });
|
|
37411
37492
|
successes.push(file);
|
|
37412
37493
|
} catch (error2) {
|
|
37413
37494
|
failures.push({ file, error: error2.message });
|
|
@@ -37424,11 +37505,11 @@ async function handleRollbackCommand(directory, args) {
|
|
|
37424
37505
|
].join(`
|
|
37425
37506
|
`);
|
|
37426
37507
|
}
|
|
37427
|
-
const existingLedgerPath =
|
|
37508
|
+
const existingLedgerPath = path73.join(swarmDir, "plan-ledger.jsonl");
|
|
37428
37509
|
let ledgerDeletionFailed = false;
|
|
37429
|
-
if (
|
|
37510
|
+
if (fs38.existsSync(existingLedgerPath)) {
|
|
37430
37511
|
try {
|
|
37431
|
-
|
|
37512
|
+
fs38.unlinkSync(existingLedgerPath);
|
|
37432
37513
|
} catch (err) {
|
|
37433
37514
|
ledgerDeletionFailed = true;
|
|
37434
37515
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
@@ -37437,9 +37518,9 @@ async function handleRollbackCommand(directory, args) {
|
|
|
37437
37518
|
}
|
|
37438
37519
|
if (!ledgerDeletionFailed) {
|
|
37439
37520
|
try {
|
|
37440
|
-
const planJsonPath =
|
|
37441
|
-
if (
|
|
37442
|
-
const planRaw =
|
|
37521
|
+
const planJsonPath = path73.join(swarmDir, "plan.json");
|
|
37522
|
+
if (fs38.existsSync(planJsonPath)) {
|
|
37523
|
+
const planRaw = fs38.readFileSync(planJsonPath, "utf-8");
|
|
37443
37524
|
const plan = PlanSchema.parse(JSON.parse(planRaw));
|
|
37444
37525
|
const planId = derivePlanId(plan);
|
|
37445
37526
|
const planHash = computePlanHash(plan);
|
|
@@ -37467,7 +37548,7 @@ async function handleRollbackCommand(directory, args) {
|
|
|
37467
37548
|
timestamp: new Date().toISOString()
|
|
37468
37549
|
};
|
|
37469
37550
|
try {
|
|
37470
|
-
|
|
37551
|
+
fs38.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
|
|
37471
37552
|
`);
|
|
37472
37553
|
} catch (error2) {
|
|
37473
37554
|
log("Failed to write rollback event:", error2 instanceof Error ? error2.message : String(error2));
|
|
@@ -37484,12 +37565,12 @@ async function handleRollbackCommand(directory, args) {
|
|
|
37484
37565
|
}
|
|
37485
37566
|
|
|
37486
37567
|
// src/commands/sdd.ts
|
|
37487
|
-
import * as
|
|
37488
|
-
import * as
|
|
37489
|
-
var
|
|
37568
|
+
import * as fs39 from "fs";
|
|
37569
|
+
import * as path74 from "path";
|
|
37570
|
+
var _internals58 = {
|
|
37490
37571
|
writeProjectedSpecSync
|
|
37491
37572
|
};
|
|
37492
|
-
var SWARM_SPEC_REL =
|
|
37573
|
+
var SWARM_SPEC_REL = path74.join(".swarm", "spec.md");
|
|
37493
37574
|
var USAGE10 = `Usage:
|
|
37494
37575
|
/swarm sdd status [--json] [--source <provider>]
|
|
37495
37576
|
/swarm sdd validate [--json] [--change <id>] [--source <provider>] [--feature <id>]
|
|
@@ -37611,7 +37692,7 @@ ${USAGE10}`;
|
|
|
37611
37692
|
}
|
|
37612
37693
|
const speckitDetection = detectSpeckit(directory);
|
|
37613
37694
|
const speckitPresent = speckitDetection.features.length > 0;
|
|
37614
|
-
const nativeSpecExists =
|
|
37695
|
+
const nativeSpecExists = fs39.existsSync(path74.join(directory, SWARM_SPEC_REL));
|
|
37615
37696
|
if (speckitPresent && !parsed.source && !nativeSpecExists) {
|
|
37616
37697
|
const openspecProjection = buildOpenSpecProjectionSync(directory);
|
|
37617
37698
|
if (openspecProjection !== null) {
|
|
@@ -37681,7 +37762,7 @@ ${USAGE10}`;
|
|
|
37681
37762
|
${USAGE10}`;
|
|
37682
37763
|
}
|
|
37683
37764
|
let useSpeckit = false;
|
|
37684
|
-
const nativeSpecExists =
|
|
37765
|
+
const nativeSpecExists = fs39.existsSync(path74.join(directory, SWARM_SPEC_REL));
|
|
37685
37766
|
if (parsed.source === "speckit") {
|
|
37686
37767
|
useSpeckit = true;
|
|
37687
37768
|
} else if (!parsed.source && !nativeSpecExists) {
|
|
@@ -37835,8 +37916,8 @@ ${USAGE10}`;
|
|
|
37835
37916
|
${USAGE10}`;
|
|
37836
37917
|
}
|
|
37837
37918
|
if (!parsed.dryRun) {
|
|
37838
|
-
const nativeSpecPath =
|
|
37839
|
-
if (
|
|
37919
|
+
const nativeSpecPath = path74.join(directory, SWARM_SPEC_REL);
|
|
37920
|
+
if (fs39.existsSync(nativeSpecPath)) {
|
|
37840
37921
|
if (!parsed.overwrite) {
|
|
37841
37922
|
return [
|
|
37842
37923
|
"Error: .swarm/spec.md already exists.",
|
|
@@ -37882,7 +37963,7 @@ ${USAGE10}`;
|
|
|
37882
37963
|
|
|
37883
37964
|
${USAGE10}`;
|
|
37884
37965
|
}
|
|
37885
|
-
const result2 =
|
|
37966
|
+
const result2 = _internals58.writeProjectedSpecSync(directory, {
|
|
37886
37967
|
source: "speckit",
|
|
37887
37968
|
feature: resolution.feature,
|
|
37888
37969
|
dryRun: parsed.dryRun,
|
|
@@ -37940,7 +38021,7 @@ ${formatList(result2.projection.warnings)}` : ""
|
|
|
37940
38021
|
].join(`
|
|
37941
38022
|
`);
|
|
37942
38023
|
}
|
|
37943
|
-
const result =
|
|
38024
|
+
const result = _internals58.writeProjectedSpecSync(directory, {
|
|
37944
38025
|
changeId: parsed.changeId,
|
|
37945
38026
|
dryRun: parsed.dryRun,
|
|
37946
38027
|
overwrite: parsed.overwrite
|
|
@@ -38002,7 +38083,7 @@ async function handleSddCommand(_directory, _args) {
|
|
|
38002
38083
|
}
|
|
38003
38084
|
|
|
38004
38085
|
// src/commands/simulate.ts
|
|
38005
|
-
import { renameSync as
|
|
38086
|
+
import { renameSync as renameSync12, unlinkSync as unlinkSync14 } from "fs";
|
|
38006
38087
|
async function handleSimulateCommand(directory, args) {
|
|
38007
38088
|
const thresholdIndex = args.indexOf("--threshold");
|
|
38008
38089
|
const minCommitsIndex = args.indexOf("--min-commits");
|
|
@@ -38050,17 +38131,17 @@ Ensure this is a git repository with commit history.`;
|
|
|
38050
38131
|
const report = reportLines.filter(Boolean).join(`
|
|
38051
38132
|
`);
|
|
38052
38133
|
try {
|
|
38053
|
-
const
|
|
38054
|
-
const
|
|
38055
|
-
const reportPath =
|
|
38056
|
-
await
|
|
38057
|
-
const reportTempPath =
|
|
38134
|
+
const fs40 = await import("fs/promises");
|
|
38135
|
+
const path75 = await import("path");
|
|
38136
|
+
const reportPath = path75.join(directory, ".swarm", "simulate-report.md");
|
|
38137
|
+
await fs40.mkdir(path75.dirname(reportPath), { recursive: true });
|
|
38138
|
+
const reportTempPath = path75.join(path75.dirname(reportPath), `${path75.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
|
|
38058
38139
|
try {
|
|
38059
|
-
await
|
|
38060
|
-
|
|
38140
|
+
await fs40.writeFile(reportTempPath, report, "utf-8");
|
|
38141
|
+
renameSync12(reportTempPath, reportPath);
|
|
38061
38142
|
} catch (err) {
|
|
38062
38143
|
try {
|
|
38063
|
-
|
|
38144
|
+
unlinkSync14(reportTempPath);
|
|
38064
38145
|
} catch {}
|
|
38065
38146
|
throw err;
|
|
38066
38147
|
}
|
|
@@ -38083,7 +38164,7 @@ async function handleSpecifyCommand(_directory, args) {
|
|
|
38083
38164
|
// src/services/status-service.ts
|
|
38084
38165
|
import * as fsSync2 from "fs";
|
|
38085
38166
|
import { readFile as readFile17 } from "fs/promises";
|
|
38086
|
-
import * as
|
|
38167
|
+
import * as path76 from "path";
|
|
38087
38168
|
|
|
38088
38169
|
// src/hooks/extractors.ts
|
|
38089
38170
|
function extractCurrentPhase(planContent) {
|
|
@@ -38127,16 +38208,16 @@ function extractCurrentPhaseFromPlan2(plan) {
|
|
|
38127
38208
|
|
|
38128
38209
|
// src/turbo/lean/state.ts
|
|
38129
38210
|
init_logger();
|
|
38130
|
-
import * as
|
|
38131
|
-
import * as
|
|
38211
|
+
import * as fs40 from "fs";
|
|
38212
|
+
import * as path75 from "path";
|
|
38132
38213
|
var STATE_FILE3 = "turbo-state.json";
|
|
38133
38214
|
function nowISO3() {
|
|
38134
38215
|
return new Date().toISOString();
|
|
38135
38216
|
}
|
|
38136
38217
|
function ensureSwarmDir2(directory) {
|
|
38137
|
-
const swarmDir =
|
|
38138
|
-
if (!
|
|
38139
|
-
|
|
38218
|
+
const swarmDir = path75.resolve(directory, ".swarm");
|
|
38219
|
+
if (!fs40.existsSync(swarmDir)) {
|
|
38220
|
+
fs40.mkdirSync(swarmDir, { recursive: true });
|
|
38140
38221
|
}
|
|
38141
38222
|
return swarmDir;
|
|
38142
38223
|
}
|
|
@@ -38179,17 +38260,17 @@ function markStateUnreadable2(directory, reason) {
|
|
|
38179
38260
|
}
|
|
38180
38261
|
function readPersisted2(directory) {
|
|
38181
38262
|
try {
|
|
38182
|
-
const filePath =
|
|
38183
|
-
if (!
|
|
38263
|
+
const filePath = path75.join(directory, ".swarm", STATE_FILE3);
|
|
38264
|
+
if (!fs40.existsSync(filePath)) {
|
|
38184
38265
|
const seed = emptyPersisted2();
|
|
38185
38266
|
try {
|
|
38186
38267
|
ensureSwarmDir2(directory);
|
|
38187
|
-
|
|
38268
|
+
fs40.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
|
|
38188
38269
|
`, "utf-8");
|
|
38189
38270
|
} catch {}
|
|
38190
38271
|
return seed;
|
|
38191
38272
|
}
|
|
38192
|
-
const raw =
|
|
38273
|
+
const raw = fs40.readFileSync(filePath, "utf-8");
|
|
38193
38274
|
const parsed = JSON.parse(raw);
|
|
38194
38275
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || parsed.version !== 1 || !parsed.sessions || typeof parsed.sessions !== "object" || Array.isArray(parsed.sessions)) {
|
|
38195
38276
|
markStateUnreadable2(directory, `malformed shape (version=${parsed?.version}, sessions type=${Array.isArray(parsed?.sessions) ? "array" : typeof parsed?.sessions})`);
|
|
@@ -38215,7 +38296,7 @@ function writePersisted2(directory, persisted) {
|
|
|
38215
38296
|
let payload;
|
|
38216
38297
|
try {
|
|
38217
38298
|
ensureSwarmDir2(directory);
|
|
38218
|
-
filePath =
|
|
38299
|
+
filePath = path75.join(directory, ".swarm", STATE_FILE3);
|
|
38219
38300
|
tmpPath = `${filePath}.tmp.${Date.now()}`;
|
|
38220
38301
|
persisted.updatedAt = nowISO3();
|
|
38221
38302
|
payload = `${JSON.stringify(persisted, null, 2)}
|
|
@@ -38226,14 +38307,14 @@ function writePersisted2(directory, persisted) {
|
|
|
38226
38307
|
throw new Error(`Lean Turbo state persistence prepare failed: ${msg}`);
|
|
38227
38308
|
}
|
|
38228
38309
|
try {
|
|
38229
|
-
|
|
38230
|
-
|
|
38310
|
+
fs40.writeFileSync(tmpPath, payload, "utf-8");
|
|
38311
|
+
fs40.renameSync(tmpPath, filePath);
|
|
38231
38312
|
} catch (error2) {
|
|
38232
38313
|
const msg = error2 instanceof Error ? error2.message : String(error2);
|
|
38233
38314
|
error(`[turbo/lean/state] Failed to persist ${STATE_FILE3} atomically: ${msg}`);
|
|
38234
38315
|
try {
|
|
38235
|
-
if (
|
|
38236
|
-
|
|
38316
|
+
if (fs40.existsSync(tmpPath)) {
|
|
38317
|
+
fs40.unlinkSync(tmpPath);
|
|
38237
38318
|
}
|
|
38238
38319
|
} catch {}
|
|
38239
38320
|
throw new Error(`Lean Turbo state persistence failed: ${msg}`);
|
|
@@ -38327,7 +38408,7 @@ var DEFAULT_CONTEXT_BUDGET_CONFIG = {
|
|
|
38327
38408
|
};
|
|
38328
38409
|
|
|
38329
38410
|
// src/services/status-service.ts
|
|
38330
|
-
var
|
|
38411
|
+
var _internals59 = {
|
|
38331
38412
|
loadLeanTurboRunState,
|
|
38332
38413
|
hasActiveLeanTurbo,
|
|
38333
38414
|
hasActiveFullAuto,
|
|
@@ -38336,7 +38417,7 @@ var _internals58 = {
|
|
|
38336
38417
|
};
|
|
38337
38418
|
function readSpecStalenessSnapshot(directory) {
|
|
38338
38419
|
try {
|
|
38339
|
-
const p =
|
|
38420
|
+
const p = path76.join(directory, ".swarm", "spec-staleness.json");
|
|
38340
38421
|
if (!fsSync2.existsSync(p))
|
|
38341
38422
|
return { stale: false };
|
|
38342
38423
|
const raw = fsSync2.readFileSync(p, "utf-8");
|
|
@@ -38448,11 +38529,11 @@ async function getStatusData(directory, agents) {
|
|
|
38448
38529
|
} catch {
|
|
38449
38530
|
status.cohort = { linked: false };
|
|
38450
38531
|
}
|
|
38451
|
-
status.fullAutoActive =
|
|
38532
|
+
status.fullAutoActive = _internals59.hasActiveFullAuto();
|
|
38452
38533
|
if (status.fullAutoActive) {
|
|
38453
|
-
const sid =
|
|
38534
|
+
const sid = _internals59.getActiveFullAutoSessionID();
|
|
38454
38535
|
if (sid) {
|
|
38455
|
-
const runState =
|
|
38536
|
+
const runState = _internals59.loadFullAutoRunState(directory, sid);
|
|
38456
38537
|
if (runState?.lastEscalation) {
|
|
38457
38538
|
status.fullAutoEscalation = {
|
|
38458
38539
|
reason: runState.lastEscalation.reason,
|
|
@@ -38467,7 +38548,7 @@ async function getStatusData(directory, agents) {
|
|
|
38467
38548
|
}
|
|
38468
38549
|
function enrichWithLeanTurbo(status, directory) {
|
|
38469
38550
|
const turboMode = hasActiveTurboMode();
|
|
38470
|
-
const leanActive =
|
|
38551
|
+
const leanActive = _internals59.hasActiveLeanTurbo();
|
|
38471
38552
|
let turboStrategy = "off";
|
|
38472
38553
|
if (leanActive) {
|
|
38473
38554
|
turboStrategy = "lean";
|
|
@@ -38486,7 +38567,7 @@ function enrichWithLeanTurbo(status, directory) {
|
|
|
38486
38567
|
}
|
|
38487
38568
|
}
|
|
38488
38569
|
if (leanSessionID) {
|
|
38489
|
-
const runState =
|
|
38570
|
+
const runState = _internals59.loadLeanTurboRunState(directory, leanSessionID);
|
|
38490
38571
|
if (runState) {
|
|
38491
38572
|
status.leanTurboPhase = runState.phase;
|
|
38492
38573
|
status.leanMaxParallelCoders = runState.maxParallelCoders;
|
|
@@ -38693,7 +38774,7 @@ No active swarm plan found. Nothing to sync.`;
|
|
|
38693
38774
|
|
|
38694
38775
|
// src/commands/turbo.ts
|
|
38695
38776
|
init_logger();
|
|
38696
|
-
var
|
|
38777
|
+
var _internals60 = {
|
|
38697
38778
|
loadPluginConfigWithMeta
|
|
38698
38779
|
};
|
|
38699
38780
|
async function handleTurboCommand(directory, args, sessionID) {
|
|
@@ -38753,7 +38834,7 @@ async function handleTurboCommand(directory, args, sessionID) {
|
|
|
38753
38834
|
if (arg0 === "on") {
|
|
38754
38835
|
let strategy = "standard";
|
|
38755
38836
|
try {
|
|
38756
|
-
const { config } =
|
|
38837
|
+
const { config } = _internals60.loadPluginConfigWithMeta(directory);
|
|
38757
38838
|
if (config.turbo?.strategy === "lean") {
|
|
38758
38839
|
strategy = "lean";
|
|
38759
38840
|
}
|
|
@@ -38850,7 +38931,7 @@ function enableLeanTurbo(session, directory, sessionID) {
|
|
|
38850
38931
|
let maxParallelCoders = 4;
|
|
38851
38932
|
let conflictPolicy = "serialize";
|
|
38852
38933
|
try {
|
|
38853
|
-
const { config } =
|
|
38934
|
+
const { config } = _internals60.loadPluginConfigWithMeta(directory);
|
|
38854
38935
|
const leanConfig = config.turbo?.lean;
|
|
38855
38936
|
if (leanConfig) {
|
|
38856
38937
|
maxParallelCoders = leanConfig.max_parallel_coders ?? 4;
|
|
@@ -38922,7 +39003,7 @@ function buildStatusMessage2(session, directory, sessionID) {
|
|
|
38922
39003
|
}
|
|
38923
39004
|
|
|
38924
39005
|
// src/commands/unlink.ts
|
|
38925
|
-
import * as
|
|
39006
|
+
import * as path77 from "path";
|
|
38926
39007
|
async function handleUnlinkCommand(directory, args) {
|
|
38927
39008
|
const pointer = readLinkPointer(directory);
|
|
38928
39009
|
if (!pointer) {
|
|
@@ -38935,7 +39016,7 @@ async function handleUnlinkCommand(directory, args) {
|
|
|
38935
39016
|
let familySummary = "";
|
|
38936
39017
|
if (copyBack) {
|
|
38937
39018
|
try {
|
|
38938
|
-
const result = await migrateKnowledgeFamily(
|
|
39019
|
+
const result = await migrateKnowledgeFamily(path77.join(directory, ".swarm"), linkDir);
|
|
38939
39020
|
for (const m of result.perMember) {
|
|
38940
39021
|
totalMerged += m.merged;
|
|
38941
39022
|
totalSkipped += m.skipped;
|
|
@@ -39055,7 +39136,7 @@ function findSimilarCommands(query) {
|
|
|
39055
39136
|
}
|
|
39056
39137
|
const scored = VALID_COMMANDS.map((cmd) => {
|
|
39057
39138
|
const cmdLower = cmd.toLowerCase();
|
|
39058
|
-
const fullScore =
|
|
39139
|
+
const fullScore = _internals61.levenshteinDistance(q, cmdLower);
|
|
39059
39140
|
let tokenScore = Infinity;
|
|
39060
39141
|
if (cmd.includes(" ") || cmd.includes("-")) {
|
|
39061
39142
|
const qTokens = q.split(/[\s-]+/);
|
|
@@ -39068,7 +39149,7 @@ function findSimilarCommands(query) {
|
|
|
39068
39149
|
for (const ct of cmdTokens) {
|
|
39069
39150
|
if (ct.length === 0)
|
|
39070
39151
|
continue;
|
|
39071
|
-
const dist =
|
|
39152
|
+
const dist = _internals61.levenshteinDistance(qt, ct);
|
|
39072
39153
|
if (dist < minDist)
|
|
39073
39154
|
minDist = dist;
|
|
39074
39155
|
}
|
|
@@ -39078,7 +39159,7 @@ function findSimilarCommands(query) {
|
|
|
39078
39159
|
}
|
|
39079
39160
|
const dashStrippedQ = q.replace(/-/g, "");
|
|
39080
39161
|
const dashStrippedCmd = cmdLower.replace(/-/g, "");
|
|
39081
|
-
const dashScore =
|
|
39162
|
+
const dashScore = _internals61.levenshteinDistance(dashStrippedQ, dashStrippedCmd);
|
|
39082
39163
|
const score = Math.min(fullScore, tokenScore, dashScore);
|
|
39083
39164
|
return { cmd, score };
|
|
39084
39165
|
});
|
|
@@ -39113,16 +39194,16 @@ function buildDetailedHelp(commandName, entry) {
|
|
|
39113
39194
|
async function handleHelpCommand(ctx) {
|
|
39114
39195
|
const targetCommand = ctx.args.join(" ");
|
|
39115
39196
|
if (!targetCommand) {
|
|
39116
|
-
const { buildHelpText } = await import("./index-
|
|
39197
|
+
const { buildHelpText } = await import("./index-2ygp3qq4.js");
|
|
39117
39198
|
return buildHelpText();
|
|
39118
39199
|
}
|
|
39119
39200
|
const tokens = targetCommand.split(/\s+/);
|
|
39120
|
-
const resolved =
|
|
39201
|
+
const resolved = _internals61.resolveCommand(tokens);
|
|
39121
39202
|
if (resolved) {
|
|
39122
|
-
return
|
|
39203
|
+
return _internals61.buildDetailedHelp(resolved.key, resolved.entry);
|
|
39123
39204
|
}
|
|
39124
|
-
const similar =
|
|
39125
|
-
const { buildHelpText: fullHelp } = await import("./index-
|
|
39205
|
+
const similar = _internals61.findSimilarCommands(targetCommand);
|
|
39206
|
+
const { buildHelpText: fullHelp } = await import("./index-2ygp3qq4.js");
|
|
39126
39207
|
if (similar.length > 0) {
|
|
39127
39208
|
return `Command '/swarm ${targetCommand}' not found.
|
|
39128
39209
|
|
|
@@ -39186,7 +39267,7 @@ var COMMAND_REGISTRY = {
|
|
|
39186
39267
|
toolNoArgs: true
|
|
39187
39268
|
},
|
|
39188
39269
|
help: {
|
|
39189
|
-
handler: (ctx) =>
|
|
39270
|
+
handler: (ctx) => _internals61.handleHelpCommand(ctx),
|
|
39190
39271
|
description: "Show help for swarm commands",
|
|
39191
39272
|
category: "core",
|
|
39192
39273
|
args: "[command]",
|
|
@@ -39255,7 +39336,7 @@ var COMMAND_REGISTRY = {
|
|
|
39255
39336
|
},
|
|
39256
39337
|
"guardrail explain": {
|
|
39257
39338
|
handler: async (ctx) => {
|
|
39258
|
-
const { handleGuardrailExplain } = await import("./guardrail-explain-
|
|
39339
|
+
const { handleGuardrailExplain } = await import("./guardrail-explain-tgkk87z5.js");
|
|
39259
39340
|
return handleGuardrailExplain(ctx.directory, ctx.args);
|
|
39260
39341
|
},
|
|
39261
39342
|
description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
|
|
@@ -39265,7 +39346,7 @@ var COMMAND_REGISTRY = {
|
|
|
39265
39346
|
},
|
|
39266
39347
|
"guardrail-explain": {
|
|
39267
39348
|
handler: async (ctx) => {
|
|
39268
|
-
const { handleGuardrailExplain } = await import("./guardrail-explain-
|
|
39349
|
+
const { handleGuardrailExplain } = await import("./guardrail-explain-tgkk87z5.js");
|
|
39269
39350
|
return handleGuardrailExplain(ctx.directory, ctx.args);
|
|
39270
39351
|
},
|
|
39271
39352
|
description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
|
|
@@ -40090,24 +40171,24 @@ function validateAliases() {
|
|
|
40090
40171
|
continue;
|
|
40091
40172
|
}
|
|
40092
40173
|
const visited = new Set;
|
|
40093
|
-
const
|
|
40174
|
+
const path78 = [];
|
|
40094
40175
|
let current = target;
|
|
40095
40176
|
while (current) {
|
|
40096
40177
|
const currentEntry = COMMAND_REGISTRY[current];
|
|
40097
40178
|
if (!currentEntry)
|
|
40098
40179
|
break;
|
|
40099
40180
|
if (visited.has(current)) {
|
|
40100
|
-
const cycleStart =
|
|
40181
|
+
const cycleStart = path78.indexOf(current);
|
|
40101
40182
|
const fullChain = [
|
|
40102
40183
|
name,
|
|
40103
|
-
...
|
|
40184
|
+
...path78.slice(0, cycleStart > 0 ? cycleStart : path78.length),
|
|
40104
40185
|
current
|
|
40105
40186
|
].join(" \u2192 ");
|
|
40106
40187
|
errors.push(`Circular alias detected: ${fullChain}`);
|
|
40107
40188
|
break;
|
|
40108
40189
|
}
|
|
40109
40190
|
visited.add(current);
|
|
40110
|
-
|
|
40191
|
+
path78.push(current);
|
|
40111
40192
|
current = currentEntry.aliasOf || "";
|
|
40112
40193
|
}
|
|
40113
40194
|
}
|
|
@@ -40126,7 +40207,7 @@ function validateToolPolicy() {
|
|
|
40126
40207
|
}
|
|
40127
40208
|
return { valid: warnings.length === 0, warnings };
|
|
40128
40209
|
}
|
|
40129
|
-
var
|
|
40210
|
+
var _internals61 = {
|
|
40130
40211
|
handleHelpCommand,
|
|
40131
40212
|
validateAliases,
|
|
40132
40213
|
validateToolPolicy,
|
|
@@ -40136,16 +40217,16 @@ var _internals60 = {
|
|
|
40136
40217
|
findSimilarCommands,
|
|
40137
40218
|
buildDetailedHelp
|
|
40138
40219
|
};
|
|
40139
|
-
var validation =
|
|
40220
|
+
var validation = _internals61.validateAliases();
|
|
40140
40221
|
if (!validation.valid) {
|
|
40141
40222
|
throw new Error(`COMMAND_REGISTRY alias validation failed:
|
|
40142
40223
|
${validation.errors.join(`
|
|
40143
40224
|
`)}`);
|
|
40144
40225
|
}
|
|
40145
|
-
|
|
40226
|
+
_internals61.emitValidationWarnings("COMMAND_REGISTRY alias warnings", validation.warnings);
|
|
40146
40227
|
try {
|
|
40147
|
-
const toolPolicyValidation =
|
|
40148
|
-
|
|
40228
|
+
const toolPolicyValidation = _internals61.validateToolPolicy();
|
|
40229
|
+
_internals61.emitValidationWarnings("COMMAND_REGISTRY toolPolicy warnings", toolPolicyValidation.warnings);
|
|
40149
40230
|
} catch (e) {
|
|
40150
40231
|
warn(`COMMAND_REGISTRY toolPolicy validation failed (non-fatal): ${e.message}`);
|
|
40151
40232
|
}
|
|
@@ -40516,6 +40597,8 @@ DELEGATION ENVELOPE FIELDS \u2014 include these in every delegation for traceabi
|
|
|
40516
40597
|
|
|
40517
40598
|
Before delegating to {{AGENT_PREFIX}}reviewer: call check_gate_status for the current task_id and include the gate results in the GATES field of the reviewer message. Format: GATES: lint=PASS/FAIL, sast_scan=PASS/FAIL, secretscan=PASS/FAIL (use PASS/FAIL/skipped for each gate). If no gates have been run yet, use GATES: none.
|
|
40518
40599
|
|
|
40600
|
+
ACCEPTANCE FIELD RESOLUTION \u2014 before every {{AGENT_PREFIX}}coder (and {{AGENT_PREFIX}}reviewer) delegation, populate that delegation's ACCEPTANCE field like this: (1) read the current task's \`fr_refs\` from the plan; (2) if \`fr_refs\` is non-empty, look up EVERY listed FR-###/SC-### id in the current \`.swarm/spec.md\` and copy each one's full requirement text into ACCEPTANCE VERBATIM \u2014 byte-for-byte, no summarizing or paraphrasing, and concatenate all of them when a task maps to more than one; (3) if \`fr_refs\` is empty or absent, populate ACCEPTANCE with a task-derived one-line restatement of what DONE looks like instead (the same pattern as \`acceptanceCriteria\` above). ACCEPTANCE must never be empty \u2014 lacking a spec mapping is normal and is not a reason to omit it.
|
|
40601
|
+
|
|
40519
40602
|
<!-- BEHAVIORAL_GUIDANCE_START -->
|
|
40520
40603
|
PARTIAL GATE RATIONALIZATIONS \u2014 automated gates \u2260 agent review. Running SOME gates is NOT compliance:
|
|
40521
40604
|
\u2717 "I ran pre_check_batch so the code is verified" \u2192 pre_check_batch does NOT replace {{AGENT_PREFIX}}reviewer or {{AGENT_PREFIX}}test_engineer
|
|
@@ -40692,7 +40775,7 @@ FILE: src/auth/login.ts
|
|
|
40692
40775
|
INPUT: Validate email format, password >= 8 chars
|
|
40693
40776
|
OUTPUT: Modified file
|
|
40694
40777
|
CONSTRAINT: Do not modify other functions
|
|
40695
|
-
ACCEPTANCE:
|
|
40778
|
+
ACCEPTANCE: [copied verbatim from spec.md, or a task-derived DONE restatement \u2014 see ACCEPTANCE FIELD RESOLUTION]
|
|
40696
40779
|
SKILLS: file:.claude/skills/engineering-conventions/SKILL.md
|
|
40697
40780
|
|
|
40698
40781
|
{{AGENT_PREFIX}}reviewer
|
|
@@ -40700,8 +40783,9 @@ TASK: Review login validation
|
|
|
40700
40783
|
FILE: src/auth/login.ts
|
|
40701
40784
|
CHECK: [security, correctness, edge-cases]
|
|
40702
40785
|
GATES: lint=PASS, sast_scan=PASS, secretscan=PASS
|
|
40786
|
+
ACCEPTANCE: [copied verbatim from spec.md, or a task-derived DONE restatement \u2014 see ACCEPTANCE FIELD RESOLUTION; same text as the coder delegation for this task]
|
|
40703
40787
|
SKILLS_USED_BY_CODER: file:.claude/skills/engineering-conventions/SKILL.md
|
|
40704
|
-
OUTPUT: VERDICT + RISK + ISSUES
|
|
40788
|
+
OUTPUT: VERDICT + RISK + ISSUES + ACCEPTANCE_SATISFACTION
|
|
40705
40789
|
SKILLS: file:.claude/skills/engineering-conventions/SKILL.md
|
|
40706
40790
|
|
|
40707
40791
|
{{AGENT_PREFIX}}test_engineer
|
|
@@ -41064,6 +41148,8 @@ ACTION: Load skill ${bundledProjectSkillFileReference("issue-ingest")} immediate
|
|
|
41064
41148
|
HARD CONSTRAINTS:
|
|
41065
41149
|
- Preserve issue evidence, flag missing repro details, and route non-mega swarms through the active swarm's agents.
|
|
41066
41150
|
|
|
41151
|
+
RECOVERY: At mode entry, read .swarm/issue-reference.json to recover the source issue URL, number, and flags (plan/trace/noRepro) if the mode signal has been lost or context was compacted.
|
|
41152
|
+
|
|
41067
41153
|
### MODE: PLAN
|
|
41068
41154
|
Activates when: workflow mode detection selects PLAN; the user asks to create, ingest, validate, or continue an implementation plan; or MODE: ISSUE_INGEST transitions with \`plan=true\` or \`trace=true\`.
|
|
41069
41155
|
|
|
@@ -41096,6 +41182,8 @@ Execution preferences (auto-proceed phase transitions):
|
|
|
41096
41182
|
<!-- BEHAVIORAL_GUIDANCE_END -->
|
|
41097
41183
|
- Preserve task granularity, test task deduplication, phase count guidance, and TRACEABILITY CHECK rules from the loaded skill.
|
|
41098
41184
|
|
|
41185
|
+
RECOVERY: Read .swarm/issue-reference.json to recover the source issue URL and number for plan traceability if context was compacted.
|
|
41186
|
+
|
|
41099
41187
|
### MODE: CRITIC-GATE
|
|
41100
41188
|
Activates before implementation begins or when a plan needs independent review.
|
|
41101
41189
|
|
|
@@ -41136,6 +41224,8 @@ HARD CONSTRAINTS (apply regardless of skill load success):
|
|
|
41136
41224
|
|
|
41137
41225
|
The full retrospective protocol lives in ${bundledProjectSkillFileReference("phase-wrap")}. Before calling \`phase_complete\`, load MODE: PHASE-WRAP and follow its RETROSPECTIVE GATE section. Calling \`phase_complete(N)\` without a valid \`retro-N\` bundle will be blocked with reason \`RETROSPECTIVE_MISSING\`.
|
|
41138
41226
|
|
|
41227
|
+
RECOVERY: Read .swarm/issue-reference.json if context was compacted to recover the source issue reference.
|
|
41228
|
+
|
|
41139
41229
|
### MODE: PHASE-WRAP
|
|
41140
41230
|
Activates when a phase is ready to close.
|
|
41141
41231
|
|
|
@@ -41157,6 +41247,8 @@ HARD CONSTRAINTS:
|
|
|
41157
41247
|
- SC-001: auto-proceed only skips the phase-transition confirmation. The architect MUST still stop for blocked tasks, user questions, clarification needs, and any decision requiring human input. This behavior is NOT affected by the auto_proceed setting.
|
|
41158
41248
|
- Full-auto mode (critic oversight) is independent \u2014 its existing "Do NOT ask Ready for Phase N+1?" override continues to work. auto_proceed has no additional effect under full-auto.
|
|
41159
41249
|
|
|
41250
|
+
RECOVERY: Read .swarm/issue-reference.json for retrospective context and commit-pr Closes #N population.
|
|
41251
|
+
|
|
41160
41252
|
> **NOTE**: The \`critic_oversight\` agent (\`AUTONOMOUS_OVERSIGHT_PROMPT\`) is dispatched only via full-auto mode (\`src/full-auto/oversight.ts\`). It has no architect MODE dispatch path \u2014 it is **NOT** reachable from \`MODE: CRITIC-GATE\`, \`MODE: EXECUTE\`, or \`MODE: PHASE-WRAP\`. This is intentional: it serves as the sole quality gate in autonomous oversight mode.
|
|
41161
41253
|
|
|
41162
41254
|
## FILES
|
|
@@ -41193,6 +41285,11 @@ Swarm: {{SWARM_ID}}
|
|
|
41193
41285
|
## Patterns
|
|
41194
41286
|
- <pattern name>: <how and when to use it in this codebase>
|
|
41195
41287
|
|
|
41288
|
+
## Source Issue
|
|
41289
|
+
- URL: <read from .swarm/issue-reference.json>
|
|
41290
|
+
- Number: <read from .swarm/issue-reference.json>
|
|
41291
|
+
Read .swarm/issue-reference.json if it exists; populate this section with the GitHub issue URL, number, and flags.trace for workflow intent recovery.
|
|
41292
|
+
|
|
41196
41293
|
\`\`\`
|
|
41197
41294
|
|
|
41198
41295
|
`;
|
|
@@ -42213,7 +42310,7 @@ AUTOMATIC REJECTION: Any vaporware indicator triggers immediate rejection before
|
|
|
42213
42310
|
Emit event: 'reviewer_substance_check' with fields: { function_name: string, issue_type: string }
|
|
42214
42311
|
|
|
42215
42312
|
TIER 1: CORRECTNESS (mandatory, always run)
|
|
42216
|
-
Does the code do what the task acceptance criteria require? Check: every acceptance criterion has corresponding implementation. First-error focus: if you find a correctness issue, stop. Report it. Do not continue to style or optimization issues.
|
|
42313
|
+
Does the code do what the task acceptance criteria require? Check: every acceptance criterion has corresponding implementation. When your input includes an ACCEPTANCE field, that field \u2014 not your own impression of "looks correct" \u2014 is the authoritative acceptance criteria: verify the diff satisfies EVERY requirement stated in ACCEPTANCE (including verbatim FR/SC text when the task maps to one or more spec requirements), not merely that the diff is well-formed or plausible in isolation. A diff that is clean, idiomatic, and bug-free but does not satisfy an ACCEPTANCE requirement is a Tier 1 CORRECTNESS failure. First-error focus: if you find a correctness issue, stop. Report it. Do not continue to style or optimization issues.
|
|
42217
42314
|
|
|
42218
42315
|
TIER 2: SAFETY (mandatory for MODERATE+, always for COMPLEX)
|
|
42219
42316
|
Does the code introduce security vulnerabilities, data loss risks, or breaking changes? Check against: SAST findings, secret scan results, import analysis. Anti-rubber-stamp: "No issues found" requires evidence. State what you checked.
|
|
@@ -42251,9 +42348,12 @@ DIFF: [changed files/functions, or "infer from FILE" if omitted]
|
|
|
42251
42348
|
AFFECTS: [callers/consumers/dependents to inspect, or "infer from diff"]
|
|
42252
42349
|
CHECK: [list of dimensions to evaluate]
|
|
42253
42350
|
GATES: [pre-completed gate results (lint, SAST, secretscan, etc.), or "none" if unavailable]
|
|
42351
|
+
ACCEPTANCE: [verbatim FR/SC requirement text this diff must satisfy, copied byte-for-byte from spec.md when the task maps to one or more FR-###/SC-### items \u2014 never a paraphrase or summary. When the task maps to no spec requirement, this is a task-derived, one-line restatement of what DONE looks like instead. This field is never empty.]
|
|
42254
42352
|
SKILLS: [optional \u2014 either "none", repo-relative file: references (preferred), or inline skill content pasted by architect]
|
|
42255
42353
|
SKILLS_USED_BY_CODER: [list of skill paths that were passed to the coder for this task, or "none" if no skills were used]
|
|
42256
42354
|
|
|
42355
|
+
ACCEPTANCE HANDLING: ACCEPTANCE is the authoritative definition of "done" for this task \u2014 evaluate the diff against it explicitly and directly, not only against your own general impression of code quality or correctness in isolation. Before writing your verdict, check EACH item in ACCEPTANCE against the diff and be prepared to state whether it is met. If the diff fails to satisfy any item in ACCEPTANCE, that is a Tier 1 CORRECTNESS failure \u2014 REJECT even if the code otherwise looks clean and well-written, and cite the specific unmet ACCEPTANCE item(s) in your FIXES.
|
|
42356
|
+
|
|
42257
42357
|
SKILLS HANDLING: If SKILLS is present and not "none", read the skill names/descriptions first, then load every referenced skill that applies before beginning your review. If uncertain whether a skill applies, load it.
|
|
42258
42358
|
- A file entry may include a short description after the path; use the description to decide whether the full skill body is relevant.
|
|
42259
42359
|
- For \`file:\` entries, use the search tool to read the referenced \`SKILL.md\` file with \`include\` set to that exact repo-relative path, \`mode: regex\`, \`query: .*\`, \`max_results: 1000\`, and \`max_lines: 1000\`.
|
|
@@ -42279,6 +42379,7 @@ VERDICT: APPROVED | REJECTED
|
|
|
42279
42379
|
REUSE_RE_VERIFICATION: [VERIFIED | DUPLICATION_DETECTED | SKIPPED] \u2014 DUPLICATION_DETECTED is only valid when VERDICT is REJECTED
|
|
42280
42380
|
RISK: LOW | MEDIUM | HIGH | CRITICAL
|
|
42281
42381
|
ISSUES: list with line numbers, grouped by CHECK dimension
|
|
42382
|
+
ACCEPTANCE_SATISFACTION: SATISFIED | PARTIAL | NOT_SATISFIED \u2014 one line per item in the input ACCEPTANCE field, stating explicitly whether the diff satisfies it (with evidence: file:line or "no corresponding implementation found"). This is a distinct question from "does the diff look correct" \u2014 assess conformance to ACCEPTANCE even when the diff is otherwise well-written. NOT_SATISFIED on any item forces VERDICT: REJECTED.
|
|
42282
42383
|
TASK: [task id being reviewed, or "unknown"]
|
|
42283
42384
|
SKILL_COMPLIANCE: COMPLIANT | PARTIAL | VIOLATED \u2014 [list of violations or "all rules followed"]
|
|
42284
42385
|
DIRECTIVE_COMPLIANCE: one line per knowledge directive shown during this phase (IDs listed in the DIRECTIVES TO VERIFY block of your prompt, when present). Use exactly one of:
|
|
@@ -42479,7 +42580,7 @@ init_logger();
|
|
|
42479
42580
|
|
|
42480
42581
|
// src/hooks/guardrails/destructive-command.ts
|
|
42481
42582
|
import * as fsSync3 from "fs";
|
|
42482
|
-
import * as
|
|
42583
|
+
import * as path78 from "path";
|
|
42483
42584
|
var DC_MAX_UNWRAP_DEPTH = 5;
|
|
42484
42585
|
var DC_SAFE_TARGETS = new Set([
|
|
42485
42586
|
"node_modules",
|
|
@@ -42655,16 +42756,16 @@ function dcIsRemotePath(p) {
|
|
|
42655
42756
|
return DC_REMOTE_PREFIXES.some((pfx) => p.startsWith(pfx));
|
|
42656
42757
|
}
|
|
42657
42758
|
function dcLstatAncestorWalk(targetPath, cwd) {
|
|
42658
|
-
const normalizedTarget =
|
|
42659
|
-
const normalizedCwd =
|
|
42759
|
+
const normalizedTarget = path78.resolve(cwd, targetPath);
|
|
42760
|
+
const normalizedCwd = path78.resolve(cwd);
|
|
42660
42761
|
const ancestors = [];
|
|
42661
42762
|
let current = normalizedTarget;
|
|
42662
42763
|
while (true) {
|
|
42663
42764
|
ancestors.push(current);
|
|
42664
|
-
const parent =
|
|
42765
|
+
const parent = path78.dirname(current);
|
|
42665
42766
|
if (parent === current)
|
|
42666
42767
|
break;
|
|
42667
|
-
const rel =
|
|
42768
|
+
const rel = path78.relative(normalizedCwd, current);
|
|
42668
42769
|
if (rel === "" || rel.startsWith(".."))
|
|
42669
42770
|
break;
|
|
42670
42771
|
current = parent;
|
|
@@ -42703,14 +42804,14 @@ function dcValidateTargets(targets, cwd) {
|
|
|
42703
42804
|
const lstatBlock = dcLstatAncestorWalk(t, cwd);
|
|
42704
42805
|
if (lstatBlock)
|
|
42705
42806
|
return lstatBlock;
|
|
42706
|
-
const basename15 =
|
|
42807
|
+
const basename15 = path78.basename(t);
|
|
42707
42808
|
if (t === basename15 && DC_SAFE_TARGETS.has(t)) {
|
|
42708
42809
|
continue;
|
|
42709
42810
|
}
|
|
42710
42811
|
if (DC_FS_ROOTS.has(t) || DC_FS_ROOTS.has(t.replace(/\//g, "\\"))) {
|
|
42711
42812
|
return `BLOCKED: Destructive command targets filesystem root "${t}"`;
|
|
42712
42813
|
}
|
|
42713
|
-
if (
|
|
42814
|
+
if (path78.isAbsolute(t) || /^[A-Za-z]:/.test(t)) {
|
|
42714
42815
|
for (const blocked of DC_BLOCKED_ABSOLUTE_PREFIXES) {
|
|
42715
42816
|
if (t.startsWith(blocked)) {
|
|
42716
42817
|
return `BLOCKED: Destructive command targets system path "${t}" which is under protected prefix "${blocked}"`;
|
|
@@ -42725,9 +42826,9 @@ function dcCheckJunctionCreation(segment, cwd) {
|
|
|
42725
42826
|
if (mklinkMatch) {
|
|
42726
42827
|
const target = mklinkMatch[2].trim();
|
|
42727
42828
|
if (!dcHasUnresolvableVars(target)) {
|
|
42728
|
-
const resolved =
|
|
42729
|
-
const rel =
|
|
42730
|
-
if (rel.startsWith("..") ||
|
|
42829
|
+
const resolved = path78.resolve(cwd, target);
|
|
42830
|
+
const rel = path78.relative(cwd, resolved);
|
|
42831
|
+
if (rel.startsWith("..") || path78.isAbsolute(rel)) {
|
|
42731
42832
|
return `BLOCKED: Junction/symlink creation targeting path outside working directory: mklink target "${target}" resolves to "${resolved}" which is outside "${cwd}". Creating junctions to external paths and then deleting them recursively can destroy data.`;
|
|
42732
42833
|
}
|
|
42733
42834
|
}
|
|
@@ -42739,9 +42840,9 @@ function dcCheckJunctionCreation(segment, cwd) {
|
|
|
42739
42840
|
if (newItemMatch) {
|
|
42740
42841
|
const target = newItemMatch[1].trim();
|
|
42741
42842
|
if (!dcHasUnresolvableVars(target)) {
|
|
42742
|
-
const resolved =
|
|
42743
|
-
const rel =
|
|
42744
|
-
if (rel.startsWith("..") ||
|
|
42843
|
+
const resolved = path78.resolve(cwd, target);
|
|
42844
|
+
const rel = path78.relative(cwd, resolved);
|
|
42845
|
+
if (rel.startsWith("..") || path78.isAbsolute(rel)) {
|
|
42745
42846
|
return `BLOCKED: Junction/symlink creation targeting path outside working directory: New-Item target "${target}" resolves to "${resolved}" which is outside "${cwd}". This pattern caused the K2.6 data-loss incident.`;
|
|
42746
42847
|
}
|
|
42747
42848
|
}
|
|
@@ -42751,9 +42852,9 @@ function dcCheckJunctionCreation(segment, cwd) {
|
|
|
42751
42852
|
if (lnMatch) {
|
|
42752
42853
|
const target = lnMatch[1].trim();
|
|
42753
42854
|
if (!dcHasUnresolvableVars(target)) {
|
|
42754
|
-
const resolved =
|
|
42755
|
-
const rel =
|
|
42756
|
-
if (rel.startsWith("..") ||
|
|
42855
|
+
const resolved = path78.resolve(cwd, target);
|
|
42856
|
+
const rel = path78.relative(cwd, resolved);
|
|
42857
|
+
if (rel.startsWith("..") || path78.isAbsolute(rel)) {
|
|
42757
42858
|
return `BLOCKED: Symlink creation targeting path outside working directory: ln -s target "${target}" resolves to "${resolved}" which is outside "${cwd}". Symlinks to external paths combined with recursive deletion can destroy data.`;
|
|
42758
42859
|
}
|
|
42759
42860
|
}
|
|
@@ -42845,7 +42946,7 @@ function formatCommandNotFound(tokens) {
|
|
|
42845
42946
|
const attemptedCommand = tokens[0] || "";
|
|
42846
42947
|
const MAX_DISPLAY = 100;
|
|
42847
42948
|
const displayCommand = attemptedCommand.length > MAX_DISPLAY ? `${attemptedCommand.slice(0, MAX_DISPLAY)}...` : attemptedCommand;
|
|
42848
|
-
const similar =
|
|
42949
|
+
const similar = _internals61.findSimilarCommands(attemptedCommand);
|
|
42849
42950
|
const header = `Command \`/swarm ${displayCommand}\` not found.`;
|
|
42850
42951
|
const suggestions = similar.length > 0 ? `Did you mean:
|
|
42851
42952
|
${similar.map((cmd) => ` - /swarm ${cmd}`).join(`
|
|
@@ -43168,10 +43269,10 @@ function classifySwarmCommandChatFallbackUse(resolved) {
|
|
|
43168
43269
|
init_executor();
|
|
43169
43270
|
|
|
43170
43271
|
// src/hooks/shell-write-detect.ts
|
|
43171
|
-
import * as
|
|
43272
|
+
import * as path79 from "path";
|
|
43172
43273
|
import parse from "bash-parser";
|
|
43173
|
-
function buildDedupeKey(category, operator,
|
|
43174
|
-
return `${category}|${operator}|${
|
|
43274
|
+
function buildDedupeKey(category, operator, path80) {
|
|
43275
|
+
return `${category}|${operator}|${path80 ?? "null"}`;
|
|
43175
43276
|
}
|
|
43176
43277
|
var REDIRECT_WRITE_TOKENS = new Set([
|
|
43177
43278
|
"GREAT",
|
|
@@ -43231,16 +43332,16 @@ function detectProcessSubstitutionWrites(command) {
|
|
|
43231
43332
|
results.push(builtinResult);
|
|
43232
43333
|
const appendMatch = stage.match(/^\s*(.*?)\s*>>(\s*)(\S+)\s*$/);
|
|
43233
43334
|
if (appendMatch) {
|
|
43234
|
-
const
|
|
43235
|
-
if (
|
|
43236
|
-
results.push({ category: "redirect", operator: ">>", path:
|
|
43335
|
+
const path80 = appendMatch[3];
|
|
43336
|
+
if (path80 && !isNullDevice(path80)) {
|
|
43337
|
+
results.push({ category: "redirect", operator: ">>", path: path80 });
|
|
43237
43338
|
}
|
|
43238
43339
|
} else {
|
|
43239
43340
|
const writeMatch = stage.match(/^\s*(.*?)\s*>(?!>)(\s*)(\S+)\s*$/);
|
|
43240
43341
|
if (writeMatch) {
|
|
43241
|
-
const
|
|
43242
|
-
if (
|
|
43243
|
-
results.push({ category: "redirect", operator: ">", path:
|
|
43342
|
+
const path80 = writeMatch[3];
|
|
43343
|
+
if (path80 && !isNullDevice(path80)) {
|
|
43344
|
+
results.push({ category: "redirect", operator: ">", path: path80 });
|
|
43244
43345
|
}
|
|
43245
43346
|
}
|
|
43246
43347
|
}
|
|
@@ -43414,8 +43515,8 @@ function extractRedirectPath(fileNode) {
|
|
|
43414
43515
|
return null;
|
|
43415
43516
|
return text;
|
|
43416
43517
|
}
|
|
43417
|
-
function isNullDevice(
|
|
43418
|
-
return
|
|
43518
|
+
function isNullDevice(path80) {
|
|
43519
|
+
return path80 === "/dev/null" || path80 === "/dev/zero" || path80 === "/dev/urandom";
|
|
43419
43520
|
}
|
|
43420
43521
|
function isNumeric(s) {
|
|
43421
43522
|
return /^\d+$/.test(s);
|
|
@@ -43435,12 +43536,12 @@ function detectRedirects(cmd) {
|
|
|
43435
43536
|
if (!opType || !REDIRECT_ALL_WRITE_TOKENS.has(opType))
|
|
43436
43537
|
continue;
|
|
43437
43538
|
const fileNode = r.file;
|
|
43438
|
-
const
|
|
43539
|
+
const path80 = extractRedirectPath(fileNode);
|
|
43439
43540
|
const opLabel = operatorLabel(opNode);
|
|
43440
43541
|
if (REDIRECT_WRITE_TOKENS.has(opType)) {
|
|
43441
|
-
results.push({ category: "redirect", operator: opLabel, path:
|
|
43542
|
+
results.push({ category: "redirect", operator: opLabel, path: path80 });
|
|
43442
43543
|
} else if (REDIRECT_HERE_TOKENS.has(opType)) {
|
|
43443
|
-
results.push({ category: "here_doc", operator: opLabel, path:
|
|
43544
|
+
results.push({ category: "here_doc", operator: opLabel, path: path80 });
|
|
43444
43545
|
}
|
|
43445
43546
|
}
|
|
43446
43547
|
return results;
|
|
@@ -43483,9 +43584,9 @@ function detectBuiltinWrites(cmd) {
|
|
|
43483
43584
|
const suffixWords2 = getSuffixWords(cmd);
|
|
43484
43585
|
for (const word of suffixWords2) {
|
|
43485
43586
|
if (word.startsWith("of=")) {
|
|
43486
|
-
const
|
|
43487
|
-
if (
|
|
43488
|
-
results.push({ category: "builtin_write", operator: "dd of=", path:
|
|
43587
|
+
const path80 = word.slice(3);
|
|
43588
|
+
if (path80 && !isNullDevice(path80)) {
|
|
43589
|
+
results.push({ category: "builtin_write", operator: "dd of=", path: path80 });
|
|
43489
43590
|
}
|
|
43490
43591
|
}
|
|
43491
43592
|
}
|
|
@@ -43604,12 +43705,12 @@ function detectNetworkDownloaders(cmd) {
|
|
|
43604
43705
|
for (let i = 0;i < suffixWords.length; i++) {
|
|
43605
43706
|
const word = suffixWords[i];
|
|
43606
43707
|
if (word === "-o" && i + 1 < suffixWords.length) {
|
|
43607
|
-
const
|
|
43608
|
-
if (!
|
|
43708
|
+
const path80 = suffixWords[i + 1];
|
|
43709
|
+
if (!path80.startsWith("-")) {
|
|
43609
43710
|
results.push({
|
|
43610
43711
|
category: "network_download",
|
|
43611
43712
|
operator: "curl -o",
|
|
43612
|
-
path:
|
|
43713
|
+
path: path80
|
|
43613
43714
|
});
|
|
43614
43715
|
}
|
|
43615
43716
|
} else if (word.startsWith("-o") && word.length > 2) {
|
|
@@ -43624,12 +43725,12 @@ function detectNetworkDownloaders(cmd) {
|
|
|
43624
43725
|
for (let i = 0;i < suffixWords.length; i++) {
|
|
43625
43726
|
const word = suffixWords[i];
|
|
43626
43727
|
if (word === "-O" && i + 1 < suffixWords.length) {
|
|
43627
|
-
const
|
|
43628
|
-
if (!
|
|
43728
|
+
const path80 = suffixWords[i + 1];
|
|
43729
|
+
if (!path80.startsWith("-")) {
|
|
43629
43730
|
results.push({
|
|
43630
43731
|
category: "network_download",
|
|
43631
43732
|
operator: "wget -O",
|
|
43632
|
-
path:
|
|
43733
|
+
path: path80
|
|
43633
43734
|
});
|
|
43634
43735
|
}
|
|
43635
43736
|
} else if (word.startsWith("-O") && word.length > 2) {
|
|
@@ -43738,9 +43839,9 @@ function detectGitDestructive(cmd) {
|
|
|
43738
43839
|
if (first === "checkout") {
|
|
43739
43840
|
const dashDashIdx = suffixWords.indexOf("--");
|
|
43740
43841
|
if (dashDashIdx !== -1 && dashDashIdx + 1 < suffixWords.length) {
|
|
43741
|
-
const
|
|
43742
|
-
const op =
|
|
43743
|
-
results.push({ category: "git_destructive", operator: op, path:
|
|
43842
|
+
const path80 = suffixWords[dashDashIdx + 1];
|
|
43843
|
+
const op = path80 === "." ? "git checkout -- ." : "git checkout --";
|
|
43844
|
+
results.push({ category: "git_destructive", operator: op, path: path80 });
|
|
43744
43845
|
}
|
|
43745
43846
|
} else if (first === "restore") {
|
|
43746
43847
|
const hasHard = suffixWords.some((w) => w === "--hard" || w === "-H" || w.startsWith("-") && w.includes("H"));
|
|
@@ -43860,10 +43961,10 @@ function detectPowerShellWrites(command) {
|
|
|
43860
43961
|
if (redirectMatch) {
|
|
43861
43962
|
const beforeRedirect = redirectMatch[1];
|
|
43862
43963
|
const op = redirectMatch[2];
|
|
43863
|
-
const
|
|
43964
|
+
const path80 = redirectMatch[3];
|
|
43864
43965
|
const fdRedirectPattern = /\d>\s*$|\s\d>&$/;
|
|
43865
43966
|
if (!fdRedirectPattern.test(`${beforeRedirect} ${op}`)) {
|
|
43866
|
-
results.push({ category: "redirect", operator: op, path:
|
|
43967
|
+
results.push({ category: "redirect", operator: op, path: path80 });
|
|
43867
43968
|
}
|
|
43868
43969
|
}
|
|
43869
43970
|
const leadingRedirect = innerCommand.match(/^((?:>){1,2})\s+(\S+)$/);
|
|
@@ -43876,12 +43977,12 @@ function detectPowerShellWrites(command) {
|
|
|
43876
43977
|
}
|
|
43877
43978
|
const iwrMatch = trimmed.match(/^(?:Invoke-WebRequest|curl)\s.*?(?:-OutFile\s+(\S+)|-o\s+(\S+))/i);
|
|
43878
43979
|
if (iwrMatch) {
|
|
43879
|
-
const
|
|
43880
|
-
if (
|
|
43980
|
+
const path80 = iwrMatch[1] || iwrMatch[2];
|
|
43981
|
+
if (path80) {
|
|
43881
43982
|
results.push({
|
|
43882
43983
|
category: "network_download",
|
|
43883
43984
|
operator: "Invoke-WebRequest -OutFile",
|
|
43884
|
-
path:
|
|
43985
|
+
path: path80
|
|
43885
43986
|
});
|
|
43886
43987
|
}
|
|
43887
43988
|
}
|
|
@@ -43893,15 +43994,15 @@ function detectPowerShellWrites(command) {
|
|
|
43893
43994
|
const rest = cmd.slice(cmdletMatch[0].length).trim();
|
|
43894
43995
|
const pathFlagMatch = rest.match(/(?:-Path|-FilePath|-LiteralPath)\s+("([^"]+)"|'([^']+)'|(\S+))/i);
|
|
43895
43996
|
if (pathFlagMatch) {
|
|
43896
|
-
const
|
|
43897
|
-
return { category: "redirect", operator: cmdletName, path:
|
|
43997
|
+
const path80 = pathFlagMatch[2] ?? pathFlagMatch[3] ?? pathFlagMatch[4] ?? "";
|
|
43998
|
+
return { category: "redirect", operator: cmdletName, path: path80 };
|
|
43898
43999
|
}
|
|
43899
44000
|
const tokens = rest.match(/(?:[^\s"-]+|"[^"]*"|'[^']*'|-[^\s]+)/g) ?? [];
|
|
43900
44001
|
for (const token of tokens) {
|
|
43901
44002
|
if (token.startsWith("-"))
|
|
43902
44003
|
continue;
|
|
43903
|
-
const
|
|
43904
|
-
return { category: "redirect", operator: cmdletName, path:
|
|
44004
|
+
const path80 = token.replace(/^["']|["']$/g, "");
|
|
44005
|
+
return { category: "redirect", operator: cmdletName, path: path80 };
|
|
43905
44006
|
}
|
|
43906
44007
|
return null;
|
|
43907
44008
|
}
|
|
@@ -43917,9 +44018,9 @@ function detectPowerShellWrites(command) {
|
|
|
43917
44018
|
for (const token of tokens) {
|
|
43918
44019
|
if (token.startsWith("-"))
|
|
43919
44020
|
continue;
|
|
43920
|
-
const
|
|
43921
|
-
if (
|
|
43922
|
-
results.push({ category: "redirect", operator: cmdletName, path:
|
|
44021
|
+
const path80 = token.replace(/^["']|["']$/g, "");
|
|
44022
|
+
if (path80) {
|
|
44023
|
+
results.push({ category: "redirect", operator: cmdletName, path: path80 });
|
|
43923
44024
|
break;
|
|
43924
44025
|
}
|
|
43925
44026
|
}
|
|
@@ -43932,8 +44033,8 @@ function detectPowerShellWrites(command) {
|
|
|
43932
44033
|
const rest = cmd.slice(opMatch[0].length).trim();
|
|
43933
44034
|
const destFlagMatch = rest.match(/-Destination\s+(\S+|"[^"]+"|'[^']+')/i);
|
|
43934
44035
|
if (destFlagMatch) {
|
|
43935
|
-
const
|
|
43936
|
-
return { category: "builtin_write", operator: cmdletName, path:
|
|
44036
|
+
const path80 = destFlagMatch[1].replace(/^["']|["']$/g, "");
|
|
44037
|
+
return { category: "builtin_write", operator: cmdletName, path: path80 };
|
|
43937
44038
|
}
|
|
43938
44039
|
const tokens = [];
|
|
43939
44040
|
const flagTakingValue = new Set([
|
|
@@ -43972,11 +44073,11 @@ function detectPowerShellWrites(command) {
|
|
|
43972
44073
|
}
|
|
43973
44074
|
}
|
|
43974
44075
|
if (tokens.length >= 2) {
|
|
43975
|
-
const
|
|
43976
|
-
return { category: "builtin_write", operator: cmdletName, path:
|
|
44076
|
+
const path80 = tokens[tokens.length - 1].replace(/^["']|["']$/g, "");
|
|
44077
|
+
return { category: "builtin_write", operator: cmdletName, path: path80 };
|
|
43977
44078
|
} else if (tokens.length === 1) {
|
|
43978
|
-
const
|
|
43979
|
-
return { category: "builtin_write", operator: cmdletName, path:
|
|
44079
|
+
const path80 = tokens[0].replace(/^["']|["']$/g, "");
|
|
44080
|
+
return { category: "builtin_write", operator: cmdletName, path: path80 };
|
|
43980
44081
|
}
|
|
43981
44082
|
return null;
|
|
43982
44083
|
}
|
|
@@ -43990,14 +44091,14 @@ function detectPowerShellWrites(command) {
|
|
|
43990
44091
|
const afterCmdlet = pipeFileOpMatch[2].trim();
|
|
43991
44092
|
const destFlagMatch = afterCmdlet.match(/-Destination\s+(\S+|"[^"]+"|'[^']+')/i);
|
|
43992
44093
|
if (destFlagMatch) {
|
|
43993
|
-
const
|
|
43994
|
-
results.push({ category: "builtin_write", operator: cmdletName, path:
|
|
44094
|
+
const path80 = destFlagMatch[1].replace(/^["']|["']$/g, "");
|
|
44095
|
+
results.push({ category: "builtin_write", operator: cmdletName, path: path80 });
|
|
43995
44096
|
} else {
|
|
43996
44097
|
const tokens = afterCmdlet.match(/(?:[^\s"-]+|"[^"]*"|'[^']*'|-[^\s]+)/g) ?? [];
|
|
43997
44098
|
const nonFlagTokens = tokens.filter((t) => !t.startsWith("-") && t.length > 0);
|
|
43998
44099
|
if (nonFlagTokens.length > 0) {
|
|
43999
|
-
const
|
|
44000
|
-
results.push({ category: "builtin_write", operator: cmdletName, path:
|
|
44100
|
+
const path80 = nonFlagTokens[nonFlagTokens.length - 1].replace(/^["']|["']$/g, "");
|
|
44101
|
+
results.push({ category: "builtin_write", operator: cmdletName, path: path80 });
|
|
44001
44102
|
}
|
|
44002
44103
|
}
|
|
44003
44104
|
}
|
|
@@ -44050,10 +44151,10 @@ function detectCmdWrites(command) {
|
|
|
44050
44151
|
if (redirectMatch) {
|
|
44051
44152
|
const beforeRedirect = redirectMatch[1];
|
|
44052
44153
|
const op = redirectMatch[2];
|
|
44053
|
-
const
|
|
44154
|
+
const path80 = redirectMatch[3];
|
|
44054
44155
|
const fdRedirectPattern = /\d>&?$/;
|
|
44055
44156
|
if (!fdRedirectPattern.test(beforeRedirect)) {
|
|
44056
|
-
results.push({ category: "redirect", operator: op, path:
|
|
44157
|
+
results.push({ category: "redirect", operator: op, path: path80 });
|
|
44057
44158
|
}
|
|
44058
44159
|
}
|
|
44059
44160
|
const leadingRedirect = innerCommand.match(/^((?:>){1,2})\s+(\S+)$/);
|
|
@@ -44111,8 +44212,8 @@ function detectCmdWrites(command) {
|
|
|
44111
44212
|
const rawTokens = rest.match(/(\/?[^\s]+|"[^"]*"|'[^']*')/g) ?? [];
|
|
44112
44213
|
const tokens = rawTokens.filter((t) => !t.startsWith("/"));
|
|
44113
44214
|
if (tokens.length > 0) {
|
|
44114
|
-
const
|
|
44115
|
-
return { category: "builtin_write", operator: "del", path:
|
|
44215
|
+
const path80 = tokens[0].replace(/^["']|["']$/g, "");
|
|
44216
|
+
return { category: "builtin_write", operator: "del", path: path80 };
|
|
44116
44217
|
}
|
|
44117
44218
|
return null;
|
|
44118
44219
|
}
|
|
@@ -44122,16 +44223,16 @@ function detectCmdWrites(command) {
|
|
|
44122
44223
|
}
|
|
44123
44224
|
const rdMatch = innerCommand.match(/^rd\s+(?:\/s\s+|\/q\s+)*(\S+)/i);
|
|
44124
44225
|
if (rdMatch) {
|
|
44125
|
-
const
|
|
44126
|
-
if (!
|
|
44127
|
-
results.push({ category: "builtin_write", operator: "rd", path:
|
|
44226
|
+
const path80 = rdMatch[1].replace(/^["']|["']$/g, "");
|
|
44227
|
+
if (!path80.startsWith("/")) {
|
|
44228
|
+
results.push({ category: "builtin_write", operator: "rd", path: path80 });
|
|
44128
44229
|
}
|
|
44129
44230
|
}
|
|
44130
44231
|
const mdMatch = trimmed.match(/^md\s+(\S+)/i);
|
|
44131
44232
|
if (mdMatch) {
|
|
44132
|
-
const
|
|
44133
|
-
if (!
|
|
44134
|
-
results.push({ category: "builtin_write", operator: "md", path:
|
|
44233
|
+
const path80 = mdMatch[1].replace(/^["']|["']$/g, "");
|
|
44234
|
+
if (!path80.startsWith("/")) {
|
|
44235
|
+
results.push({ category: "builtin_write", operator: "md", path: path80 });
|
|
44135
44236
|
}
|
|
44136
44237
|
}
|
|
44137
44238
|
const echoMatch = trimmed.match(/^echo\s+(\S+.*?)\s+((?:>){1,2})\s*(\S+)$/i);
|
|
@@ -44247,10 +44348,10 @@ function resolvePath(pathText, cwd) {
|
|
|
44247
44348
|
return null;
|
|
44248
44349
|
const isWindowsPath = /^[a-zA-Z]:[\\\\/]/.test(cwd) || cwd.includes("\\");
|
|
44249
44350
|
if (isWindowsPath) {
|
|
44250
|
-
return
|
|
44351
|
+
return path79.win32.resolve(cwd, pathText);
|
|
44251
44352
|
}
|
|
44252
|
-
const normalizedRelativeWindowsPath = !
|
|
44253
|
-
return
|
|
44353
|
+
const normalizedRelativeWindowsPath = !path79.posix.isAbsolute(pathText) && !/^[a-zA-Z]:[\\/]/.test(pathText) ? pathText.replace(/\\/g, "/") : pathText;
|
|
44354
|
+
return path79.posix.resolve(cwd, normalizedRelativeWindowsPath);
|
|
44254
44355
|
}
|
|
44255
44356
|
function getCdTarget(cmd) {
|
|
44256
44357
|
if (!cmd || typeof cmd !== "object")
|
|
@@ -44317,7 +44418,7 @@ function collectWritesWithNodes(node, out, cwdStack) {
|
|
|
44317
44418
|
for (const cmd of node.commands) {
|
|
44318
44419
|
const cdTarget = getCdTarget(cmd);
|
|
44319
44420
|
if (cdTarget) {
|
|
44320
|
-
currentStack[0] =
|
|
44421
|
+
currentStack[0] = path79.posix.resolve(currentStack[0] ?? "/", cdTarget);
|
|
44321
44422
|
collectWritesWithNodes(cmd, out, currentStack);
|
|
44322
44423
|
} else {
|
|
44323
44424
|
collectWritesWithNodes(cmd, out, currentStack);
|
|
@@ -44363,7 +44464,7 @@ function collectWritesWithNodes(node, out, cwdStack) {
|
|
|
44363
44464
|
const effectiveCwd = cwdStack[0] ?? "/";
|
|
44364
44465
|
const cdTarget = getCdTarget(node);
|
|
44365
44466
|
if (cdTarget) {
|
|
44366
|
-
cwdStack[0] =
|
|
44467
|
+
cwdStack[0] = path79.posix.resolve(cwdStack[0] ?? "/", cdTarget);
|
|
44367
44468
|
return;
|
|
44368
44469
|
}
|
|
44369
44470
|
const writesFromRedirs = getWritesFromCommandRedirs(node, effectiveCwd);
|
|
@@ -44409,12 +44510,12 @@ function getWritesFromRedirectNode(redirect, _context) {
|
|
|
44409
44510
|
if (!opType || !REDIRECT_ALL_WRITE_TOKENS.has(opType))
|
|
44410
44511
|
return [];
|
|
44411
44512
|
const fileNode = r.file;
|
|
44412
|
-
const
|
|
44513
|
+
const path80 = extractRedirectPath(fileNode);
|
|
44413
44514
|
const opLabel = operatorLabel(opNode);
|
|
44414
44515
|
if (REDIRECT_WRITE_TOKENS.has(opType)) {
|
|
44415
|
-
return [{ category: "redirect", operator: opLabel, path:
|
|
44516
|
+
return [{ category: "redirect", operator: opLabel, path: path80 }];
|
|
44416
44517
|
} else if (REDIRECT_HERE_TOKENS.has(opType)) {
|
|
44417
|
-
return [{ category: "here_doc", operator: opLabel, path:
|
|
44518
|
+
return [{ category: "here_doc", operator: opLabel, path: path80 }];
|
|
44418
44519
|
}
|
|
44419
44520
|
return [];
|
|
44420
44521
|
}
|
|
@@ -44805,10 +44906,10 @@ function startAgentSession(sessionId, agentName, staleDurationMs = STALE_SESSION
|
|
|
44805
44906
|
}
|
|
44806
44907
|
telemetry.sessionStarted(sessionId, agentName);
|
|
44807
44908
|
swarmState.activeAgent.set(sessionId, agentName);
|
|
44808
|
-
|
|
44909
|
+
_internals64.applyRehydrationCache(sessionState);
|
|
44809
44910
|
if (directory) {
|
|
44810
44911
|
let rehydrationPromise;
|
|
44811
|
-
rehydrationPromise =
|
|
44912
|
+
rehydrationPromise = _internals64.rehydrateSessionFromDisk(directory, sessionState).then(async () => {
|
|
44812
44913
|
try {
|
|
44813
44914
|
sessionState.prSubscriptions = await rehydratePrSubscriptions(sessionId, directory);
|
|
44814
44915
|
} catch (err) {
|
|
@@ -44989,7 +45090,7 @@ function ensureAgentSession(sessionId, agentName, directory) {
|
|
|
44989
45090
|
maybeSweepStaleSessions();
|
|
44990
45091
|
return session;
|
|
44991
45092
|
}
|
|
44992
|
-
|
|
45093
|
+
_internals64.startAgentSession(sessionId, agentName ?? "unknown", 7200000, directory);
|
|
44993
45094
|
session = swarmState.agentSessions.get(sessionId);
|
|
44994
45095
|
if (!session) {
|
|
44995
45096
|
throw new Error(`Failed to create guardrail session for ${sessionId}`);
|
|
@@ -45167,8 +45268,8 @@ function evidenceToWorkflowState(evidence) {
|
|
|
45167
45268
|
}
|
|
45168
45269
|
async function readPlanFromDisk(directory) {
|
|
45169
45270
|
try {
|
|
45170
|
-
const planPath =
|
|
45171
|
-
const content = await
|
|
45271
|
+
const planPath = path80.join(directory, ".swarm", "plan.json");
|
|
45272
|
+
const content = await fs41.readFile(planPath, "utf-8");
|
|
45172
45273
|
const parsed = JSON.parse(content);
|
|
45173
45274
|
return PlanSchema.parse(parsed);
|
|
45174
45275
|
} catch {
|
|
@@ -45178,8 +45279,8 @@ async function readPlanFromDisk(directory) {
|
|
|
45178
45279
|
async function readGateEvidenceFromDisk(directory) {
|
|
45179
45280
|
const evidenceMap = new Map;
|
|
45180
45281
|
try {
|
|
45181
|
-
const evidenceDir =
|
|
45182
|
-
const entries = await
|
|
45282
|
+
const evidenceDir = path80.join(directory, ".swarm", "evidence");
|
|
45283
|
+
const entries = await fs41.readdir(evidenceDir, { withFileTypes: true });
|
|
45183
45284
|
for (const entry of entries) {
|
|
45184
45285
|
if (!entry.isFile() || !entry.name.endsWith(".json")) {
|
|
45185
45286
|
continue;
|
|
@@ -45189,8 +45290,8 @@ async function readGateEvidenceFromDisk(directory) {
|
|
|
45189
45290
|
continue;
|
|
45190
45291
|
}
|
|
45191
45292
|
try {
|
|
45192
|
-
const filePath =
|
|
45193
|
-
const content = await
|
|
45293
|
+
const filePath = path80.join(evidenceDir, entry.name);
|
|
45294
|
+
const content = await fs41.readFile(filePath, "utf-8");
|
|
45194
45295
|
const parsed = JSON.parse(content);
|
|
45195
45296
|
if (parsed && typeof parsed.taskId === "string" && Array.isArray(parsed.required_gates)) {
|
|
45196
45297
|
evidenceMap.set(taskId, parsed);
|
|
@@ -45277,8 +45378,8 @@ function applyRehydrationCache(session) {
|
|
|
45277
45378
|
}
|
|
45278
45379
|
}
|
|
45279
45380
|
async function rehydrateSessionFromDisk(directory, session) {
|
|
45280
|
-
await
|
|
45281
|
-
|
|
45381
|
+
await _internals64.buildRehydrationCache(directory);
|
|
45382
|
+
_internals64.applyRehydrationCache(session);
|
|
45282
45383
|
}
|
|
45283
45384
|
function hasActiveTurboMode(sessionID) {
|
|
45284
45385
|
if (sessionID) {
|
|
@@ -45366,7 +45467,7 @@ async function rehydratePrSubscriptions(sessionID, directory) {
|
|
|
45366
45467
|
}
|
|
45367
45468
|
return map;
|
|
45368
45469
|
}
|
|
45369
|
-
var
|
|
45470
|
+
var _internals64 = {
|
|
45370
45471
|
swarmState,
|
|
45371
45472
|
resetSwarmState,
|
|
45372
45473
|
ensureAgentSession,
|
|
@@ -45505,4 +45606,4 @@ function createCuratorLLMDelegate(directory, mode = "init", sessionId) {
|
|
|
45505
45606
|
};
|
|
45506
45607
|
}
|
|
45507
45608
|
|
|
45508
|
-
export { package_default, handleAcknowledgeSpecDriftCommand, handleAgentsCommand, handleAnalyzeCommand, handleArchiveCommand, DC_SAFE_TARGETS, dcNormalizeCommand, dcUnwrapWrappers, dcSplitSegments, dcValidateTargets, dcCheckJunctionCreation, dcExtractWindowsCmdTargets, dcExtractPowerShellTargets, normalizeSwarmCommandInput, canonicalCommandKey, formatCommandNotFound, executeSwarmCommand, SWARM_COMMAND_TOOL_COMMANDS, SWARM_COMMAND_TOOL_ALLOWLIST, HUMAN_ONLY_SWARM_COMMANDS, classifySwarmCommandToolUse, classifySwarmCommandChatFallbackUse, detectPosixWrites, detectWindowsWrites, resolveWriteTargets, handleAutoProceedCommand, handleBenchmarkCommand, handleBrainstormCommand, handleCheckpointCommand, handleCiSimulateCommand, handleClarifyCommand, createCuratorLLMDelegate, _internals14 as _internals, normalizeRecommendationEntryIdToken, parseKnowledgeRecommendations, parseKnowledgeRecommendationsWithDiagnostics, parseStructuredCuratorBlocks, readCuratorSummary, writeCuratorSummary, appendCuratorRecommendation, mergeCuratorPhaseSummary, filterPhaseEvents, checkPhaseCompliance, runCuratorInit, runCuratorPhase, applyCuratorKnowledgeUpdates, isHiveEligible, countDistinctProjects, checkHivePromotions, _internals17 as _internals1, createHivePromoterHook, promoteToHive, promoteFromSwarm, handleCloseCommand, handleCodebaseReviewCommand, handleConcurrencyCommand, handleConfigCommand, handleConsolidateCommand, handleCostsCommand, handleCouncilCommand, handleCurateCommand, handleDarkMatterCommand, handleDeepDiveCommand, handleDeepResearchCommand, getPluginConfigDir, getPluginCachePaths, getPluginLockFilePaths, handleDiagnoseCommand, handleDoctorCommand, handleEvidenceCommand, handleEvidenceSummaryCommand, handleExportCommand, handleFullAutoCommand, handleGateAuditCommand, handleGateStatsCommand, handleHandoffCommand, handleHistoryCommand, handleKnowledgeQuarantineCommand, handleKnowledgeRestoreCommand, handleKnowledgeMigrateCommand, handleKnowledgeListCommand, handleKnowledgeUnactionableCommand, handleKnowledgeRetryHardeningCommand, handleLearningCommand, handleLinkCommand, handleMemoryCommand, handleMemoryStatusCommand, handleMemoryValueLogCommand, handleMemoryMigrateCommand, handleMemoryImportCommand, handleMemoryExportCommand, handlePlanCommand, handlePreflightCommand, handlePromoteCommand, handleQaGatesCommand, handleResetCommand, handleResetSessionCommand, handleRetrieveCommand, handleRollbackCommand, handleSddStatusCommand, handleSddValidateCommand, handleSddProjectCommand, handleSddCommand, handleSimulateCommand, handleSpecifyCommand, handleStatusCommand, handleSyncPlanCommand, handleTurboCommand, handleUnlinkCommand, handleWriteRetroCommand, handleHelpCommand, COMMAND_REGISTRY, VALID_COMMANDS,
|
|
45609
|
+
export { package_default, handleAcknowledgeSpecDriftCommand, handleAgentsCommand, handleAnalyzeCommand, handleArchiveCommand, DC_SAFE_TARGETS, dcNormalizeCommand, dcUnwrapWrappers, dcSplitSegments, dcValidateTargets, dcCheckJunctionCreation, dcExtractWindowsCmdTargets, dcExtractPowerShellTargets, normalizeSwarmCommandInput, canonicalCommandKey, formatCommandNotFound, executeSwarmCommand, SWARM_COMMAND_TOOL_COMMANDS, SWARM_COMMAND_TOOL_ALLOWLIST, HUMAN_ONLY_SWARM_COMMANDS, classifySwarmCommandToolUse, classifySwarmCommandChatFallbackUse, detectPosixWrites, detectWindowsWrites, resolveWriteTargets, handleAutoProceedCommand, handleBenchmarkCommand, handleBrainstormCommand, handleCheckpointCommand, handleCiSimulateCommand, handleClarifyCommand, createCuratorLLMDelegate, _internals14 as _internals, normalizeRecommendationEntryIdToken, parseKnowledgeRecommendations, parseKnowledgeRecommendationsWithDiagnostics, parseStructuredCuratorBlocks, readCuratorSummary, writeCuratorSummary, appendCuratorRecommendation, mergeCuratorPhaseSummary, filterPhaseEvents, checkPhaseCompliance, runCuratorInit, runCuratorPhase, applyCuratorKnowledgeUpdates, isHiveEligible, countDistinctProjects, checkHivePromotions, _internals17 as _internals1, createHivePromoterHook, promoteToHive, promoteFromSwarm, handleCloseCommand, handleCodebaseReviewCommand, handleConcurrencyCommand, handleConfigCommand, handleConsolidateCommand, handleCostsCommand, handleCouncilCommand, handleCurateCommand, handleDarkMatterCommand, handleDeepDiveCommand, handleDeepResearchCommand, getPluginConfigDir, getPluginCachePaths, getPluginLockFilePaths, handleDiagnoseCommand, handleDoctorCommand, handleEvidenceCommand, handleEvidenceSummaryCommand, handleExportCommand, handleFullAutoCommand, handleGateAuditCommand, handleGateStatsCommand, handleHandoffCommand, handleHistoryCommand, handleKnowledgeQuarantineCommand, handleKnowledgeRestoreCommand, handleKnowledgeMigrateCommand, handleKnowledgeListCommand, handleKnowledgeUnactionableCommand, handleKnowledgeRetryHardeningCommand, handleLearningCommand, handleLinkCommand, handleMemoryCommand, handleMemoryStatusCommand, handleMemoryValueLogCommand, handleMemoryMigrateCommand, handleMemoryImportCommand, handleMemoryExportCommand, handlePlanCommand, handlePreflightCommand, handlePromoteCommand, handleQaGatesCommand, handleResetCommand, handleResetSessionCommand, handleRetrieveCommand, handleRollbackCommand, handleSddStatusCommand, handleSddValidateCommand, handleSddProjectCommand, handleSddCommand, handleSimulateCommand, handleSpecifyCommand, handleStatusCommand, handleSyncPlanCommand, handleTurboCommand, handleUnlinkCommand, handleWriteRetroCommand, handleHelpCommand, COMMAND_REGISTRY, VALID_COMMANDS, _internals61 as _internals2, resolveCommand };
|