opencode-swarm 7.98.2 → 7.99.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/dist/agents/_prompt-helpers.d.ts +1 -0
- package/dist/cli/{config-doctor-7yrxfa6b.js → config-doctor-9fhfy6p7.js} +2 -2
- package/dist/cli/{evidence-summary-service-559nas1m.js → evidence-summary-service-gvd7mw7v.js} +5 -5
- package/dist/cli/{explorer-jc46negv.js → explorer-rwfvbbx5.js} +1 -1
- package/dist/cli/{gate-evidence-nphg8hay.js → gate-evidence-ywys9vfs.js} +4 -4
- package/dist/cli/guardrail-explain-6g1japmf.js +30 -0
- package/dist/cli/{guardrail-log-53z1cf46.js → guardrail-log-ya49kpwn.js} +3 -3
- package/dist/cli/{index-91qtsbce.js → index-3naa2ajc.js} +1 -1
- package/dist/cli/{index-a0dv2c7k.js → index-5fxjagjt.js} +1 -1
- package/dist/cli/{index-471qxz9g.js → index-7hnwnw5g.js} +11 -1
- package/dist/cli/{index-kv4dd5c5.js → index-9b7qp18e.js} +1 -1
- package/dist/cli/{index-72k57f21.js → index-brpm7xs3.js} +1157 -803
- package/dist/cli/{index-hb10a2g8.js → index-f7nma02k.js} +2 -2
- package/dist/cli/{index-gnd1280x.js → index-h9ptj4b1.js} +1 -1
- package/dist/cli/{index-yrzfbqqh.js → index-qcr60fgm.js} +29 -16
- package/dist/cli/{index-mh1ej70w.js → index-r8f89sm9.js} +2 -2
- package/dist/cli/{index-zy22fg5h.js → index-svf2zjxs.js} +5 -1
- package/dist/cli/{index-rvweaxsd.js → index-sy329dh4.js} +2 -2
- package/dist/cli/{index-xchgryg4.js → index-vn263hqt.js} +16 -2
- package/dist/cli/{index-fjxjb66n.js → index-vwyjkzgs.js} +3 -3
- package/dist/cli/{index-5z2e78tv.js → index-xsswhy6k.js} +1 -1
- package/dist/cli/{index-chan9mkv.js → index-xy3gw0rw.js} +17 -15
- package/dist/cli/{index-2a6ppa65.js → index-ydgy7vg5.js} +12 -7
- package/dist/cli/index.js +13 -13
- package/dist/cli/{knowledge-store-pa58msy5.js → knowledge-store-tsa8ezka.js} +4 -4
- package/dist/cli/{pending-delegations-8b2js1vq.js → pending-delegations-c785p5n2.js} +2 -2
- package/dist/cli/{pr-subscriptions-ttvr1ta9.js → pr-subscriptions-fqrzm0tv.js} +3 -3
- package/dist/cli/{schema-mygkbbe9.js → schema-nz638xc3.js} +5 -1
- package/dist/cli/{skill-generator-3tkwcg4x.js → skill-generator-99rrfwae.js} +5 -5
- package/dist/cli/{telemetry-aa1ma1dr.js → telemetry-jm7t8031.js} +1 -1
- package/dist/commands/costs.d.ts +4 -0
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/registry.d.ts +9 -2
- package/dist/config/evidence-schema.d.ts +44 -44
- package/dist/config/index.d.ts +2 -2
- package/dist/config/schema.d.ts +24 -0
- package/dist/evidence/manager.d.ts +5 -0
- package/dist/hooks/knowledge-migrator.d.ts +7 -0
- package/dist/index.js +3074 -2478
- package/dist/services/cost-accounting.d.ts +65 -0
- package/dist/telemetry.d.ts +2 -1
- package/dist/turbo/lean/conflicts.d.ts +2 -13
- package/dist/utils/path.d.ts +1 -0
- package/package.json +1 -1
- package/dist/cli/guardrail-explain-xktjjh53.js +0 -30
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
READ_ONLY_LANE_GUIDANCE
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-ydgy7vg5.js";
|
|
5
5
|
import {
|
|
6
6
|
DEFAULT_SKILL_MIN_CONFIDENCE,
|
|
7
7
|
DEFAULT_SKILL_MIN_CONFIRMATIONS,
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
validateActionability,
|
|
24
24
|
validateActionableFields,
|
|
25
25
|
validateLesson
|
|
26
|
-
} from "./index-
|
|
26
|
+
} from "./index-vwyjkzgs.js";
|
|
27
27
|
import {
|
|
28
28
|
appendKnowledge,
|
|
29
29
|
appendRejectedLesson,
|
|
@@ -51,13 +51,13 @@ import {
|
|
|
51
51
|
transactFile,
|
|
52
52
|
transactKnowledge,
|
|
53
53
|
writeLinkPointer
|
|
54
|
-
} from "./index-
|
|
54
|
+
} from "./index-f7nma02k.js";
|
|
55
55
|
import {
|
|
56
56
|
detectStraySwarmDirs,
|
|
57
57
|
readDoctorArtifact,
|
|
58
58
|
removeStraySwarmDir,
|
|
59
59
|
runConfigDoctor
|
|
60
|
-
} from "./index-
|
|
60
|
+
} from "./index-svf2zjxs.js";
|
|
61
61
|
import {
|
|
62
62
|
AGENT_TOOL_MAP,
|
|
63
63
|
ALL_SUBAGENT_NAMES,
|
|
@@ -70,7 +70,7 @@ import {
|
|
|
70
70
|
TOOL_NAME_SET,
|
|
71
71
|
resolveExternalSkillsConfig,
|
|
72
72
|
stripKnownSwarmPrefix
|
|
73
|
-
} from "./index-
|
|
73
|
+
} from "./index-7hnwnw5g.js";
|
|
74
74
|
import {
|
|
75
75
|
MAX_TRANSIENT_RETRIES,
|
|
76
76
|
PlanSchema,
|
|
@@ -114,7 +114,7 @@ import {
|
|
|
114
114
|
transientBackoff,
|
|
115
115
|
validateProjectRoot,
|
|
116
116
|
writeProjectedSpecSync
|
|
117
|
-
} from "./index-
|
|
117
|
+
} from "./index-qcr60fgm.js";
|
|
118
118
|
import {
|
|
119
119
|
_internals as _internals2,
|
|
120
120
|
_internals1 as _internals3,
|
|
@@ -132,13 +132,13 @@ import {
|
|
|
132
132
|
} from "./index-v4fcn4tr.js";
|
|
133
133
|
import {
|
|
134
134
|
atomicWriteFile
|
|
135
|
-
} from "./index-
|
|
135
|
+
} from "./index-9b7qp18e.js";
|
|
136
136
|
import {
|
|
137
137
|
buildCorrelationId,
|
|
138
138
|
listActive,
|
|
139
139
|
subscribe,
|
|
140
140
|
unsubscribe
|
|
141
|
-
} from "./index-
|
|
141
|
+
} from "./index-5fxjagjt.js";
|
|
142
142
|
import {
|
|
143
143
|
readSwarmFileAsync,
|
|
144
144
|
safeHook,
|
|
@@ -156,7 +156,7 @@ import {
|
|
|
156
156
|
import {
|
|
157
157
|
require_proper_lockfile,
|
|
158
158
|
tryAcquireLock
|
|
159
|
-
} from "./index-
|
|
159
|
+
} from "./index-3naa2ajc.js";
|
|
160
160
|
import {
|
|
161
161
|
exports_external
|
|
162
162
|
} from "./index-293f68mj.js";
|
|
@@ -166,7 +166,7 @@ import {
|
|
|
166
166
|
} from "./index-b9v501fr.js";
|
|
167
167
|
import {
|
|
168
168
|
telemetry
|
|
169
|
-
} from "./index-
|
|
169
|
+
} from "./index-vn263hqt.js";
|
|
170
170
|
import {
|
|
171
171
|
__esm,
|
|
172
172
|
__export,
|
|
@@ -909,7 +909,7 @@ var init_executor = __esm(() => {
|
|
|
909
909
|
// package.json
|
|
910
910
|
var package_default = {
|
|
911
911
|
name: "opencode-swarm",
|
|
912
|
-
version: "7.
|
|
912
|
+
version: "7.99.1",
|
|
913
913
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
914
914
|
main: "dist/index.js",
|
|
915
915
|
types: "dist/index.d.ts",
|
|
@@ -3624,15 +3624,30 @@ function classifySwarmCommandToolUse(resolved) {
|
|
|
3624
3624
|
}
|
|
3625
3625
|
}
|
|
3626
3626
|
if (canonicalKey === "benchmark") {
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3627
|
+
for (let i = 0;i < args.length; i++) {
|
|
3628
|
+
const arg = args[i];
|
|
3629
|
+
if (arg === "--cumulative" || arg === "--ci-gate")
|
|
3630
|
+
continue;
|
|
3631
|
+
if (arg === "--max-cost-usd" && i + 1 < args.length && /^\d+(\.\d+)?$/.test(args[i + 1])) {
|
|
3632
|
+
i++;
|
|
3633
|
+
continue;
|
|
3634
|
+
}
|
|
3630
3635
|
return {
|
|
3631
3636
|
allowed: false,
|
|
3632
|
-
message: "Only `--cumulative
|
|
3637
|
+
message: "Only `--cumulative`, `--ci-gate`, and `--max-cost-usd <n>` are supported for `/swarm benchmark` through swarm_command."
|
|
3633
3638
|
};
|
|
3634
3639
|
}
|
|
3635
3640
|
}
|
|
3641
|
+
if (canonicalKey === "costs") {
|
|
3642
|
+
if (args.length === 0)
|
|
3643
|
+
return { allowed: true };
|
|
3644
|
+
if (args.length === 1 && args[0] === "--json")
|
|
3645
|
+
return { allowed: true };
|
|
3646
|
+
return {
|
|
3647
|
+
allowed: false,
|
|
3648
|
+
message: "Usage through swarm_command: `/swarm costs` or `/swarm costs --json`."
|
|
3649
|
+
};
|
|
3650
|
+
}
|
|
3636
3651
|
if (canonicalKey === "show-plan") {
|
|
3637
3652
|
if (args.length > 1 || args[0] && !/^\d+$/.test(args[0])) {
|
|
3638
3653
|
return {
|
|
@@ -3723,6 +3738,9 @@ function clearAllScopes(directory) {
|
|
|
3723
3738
|
// src/hooks/shell-write-detect.ts
|
|
3724
3739
|
import * as path8 from "path";
|
|
3725
3740
|
import parse from "bash-parser";
|
|
3741
|
+
function buildDedupeKey(category, operator, path9) {
|
|
3742
|
+
return `${category}|${operator}|${path9 ?? "null"}`;
|
|
3743
|
+
}
|
|
3726
3744
|
var REDIRECT_WRITE_TOKENS = new Set([
|
|
3727
3745
|
"GREAT",
|
|
3728
3746
|
"DGREAT",
|
|
@@ -4741,7 +4759,7 @@ function detectPosixWrites(command) {
|
|
|
4741
4759
|
}
|
|
4742
4760
|
const seen = new Set;
|
|
4743
4761
|
const writes = allWrites.filter((wt) => {
|
|
4744
|
-
const key =
|
|
4762
|
+
const key = buildDedupeKey(wt.category, wt.operator, wt.path);
|
|
4745
4763
|
if (seen.has(key))
|
|
4746
4764
|
return false;
|
|
4747
4765
|
seen.add(key);
|
|
@@ -4766,7 +4784,7 @@ function detectWindowsWrites(command, shell) {
|
|
|
4766
4784
|
}
|
|
4767
4785
|
const seen = new Set;
|
|
4768
4786
|
const writes = allWrites.filter((wt) => {
|
|
4769
|
-
const key =
|
|
4787
|
+
const key = buildDedupeKey(wt.category, wt.operator, wt.path);
|
|
4770
4788
|
if (seen.has(key))
|
|
4771
4789
|
return false;
|
|
4772
4790
|
seen.add(key);
|
|
@@ -5021,7 +5039,7 @@ function resolveWriteTargets(command, writes, cwd) {
|
|
|
5021
5039
|
collectWritesWithNodes(ast, writesWithNodes, cwdStack);
|
|
5022
5040
|
const seen = new Set;
|
|
5023
5041
|
const deduplicated = writesWithNodes.filter((wwn) => {
|
|
5024
|
-
const key =
|
|
5042
|
+
const key = buildDedupeKey(wwn.write.category, wwn.write.operator, wwn.write.path);
|
|
5025
5043
|
if (seen.has(key))
|
|
5026
5044
|
return false;
|
|
5027
5045
|
seen.add(key);
|
|
@@ -5031,11 +5049,11 @@ function resolveWriteTargets(command, writes, cwd) {
|
|
|
5031
5049
|
for (const { write, context } of deduplicated) {
|
|
5032
5050
|
const resolvedPath = resolvePath(write.path, context);
|
|
5033
5051
|
const resolved = write.path !== null && !isDynamicPath(write.path);
|
|
5034
|
-
const key =
|
|
5052
|
+
const key = buildDedupeKey(write.category, write.operator, write.path);
|
|
5035
5053
|
resolvedMap.set(key, { resolvedPath, resolved });
|
|
5036
5054
|
}
|
|
5037
5055
|
return writes.map((original) => {
|
|
5038
|
-
const key =
|
|
5056
|
+
const key = buildDedupeKey(original.category, original.operator, original.path);
|
|
5039
5057
|
const resolved = resolvedMap.get(key);
|
|
5040
5058
|
if (resolved) {
|
|
5041
5059
|
return {
|
|
@@ -5981,7 +5999,7 @@ function hasActiveEpicMode(sessionID) {
|
|
|
5981
5999
|
async function rehydratePrSubscriptions(sessionID, directory) {
|
|
5982
6000
|
const map = new Map;
|
|
5983
6001
|
try {
|
|
5984
|
-
const { listActive: listActive2 } = await import("./pr-subscriptions-
|
|
6002
|
+
const { listActive: listActive2 } = await import("./pr-subscriptions-fqrzm0tv.js");
|
|
5985
6003
|
const records = await listActive2(directory);
|
|
5986
6004
|
for (const record of records) {
|
|
5987
6005
|
if (record.sessionID !== sessionID)
|
|
@@ -6058,6 +6076,199 @@ async function handleAutoProceedCommand(_directory, args, sessionID) {
|
|
|
6058
6076
|
}
|
|
6059
6077
|
}
|
|
6060
6078
|
|
|
6079
|
+
// src/services/cost-accounting.ts
|
|
6080
|
+
import * as fs7 from "fs";
|
|
6081
|
+
import * as os6 from "os";
|
|
6082
|
+
import * as path12 from "path";
|
|
6083
|
+
function summarizeTelemetryCosts(directory) {
|
|
6084
|
+
const summary = createEmptySummary();
|
|
6085
|
+
for (const event of readTelemetryEvents(directory)) {
|
|
6086
|
+
if (event.event !== "delegation_end")
|
|
6087
|
+
continue;
|
|
6088
|
+
addDelegationEvent(summary, event);
|
|
6089
|
+
}
|
|
6090
|
+
return finalizeSummary(summary);
|
|
6091
|
+
}
|
|
6092
|
+
function readTelemetryEvents(directory) {
|
|
6093
|
+
const swarmDir = path12.join(directory, ".swarm");
|
|
6094
|
+
const files = [
|
|
6095
|
+
path12.join(swarmDir, "telemetry.jsonl.1"),
|
|
6096
|
+
path12.join(swarmDir, "telemetry.jsonl")
|
|
6097
|
+
];
|
|
6098
|
+
const tmpDir = fs7.mkdtempSync(path12.join(os6.tmpdir(), "telemetry-snapshot-"));
|
|
6099
|
+
const snapshotFiles = [];
|
|
6100
|
+
try {
|
|
6101
|
+
for (const file of files) {
|
|
6102
|
+
if (!fs7.existsSync(file))
|
|
6103
|
+
continue;
|
|
6104
|
+
const snap = path12.join(tmpDir, path12.basename(file));
|
|
6105
|
+
try {
|
|
6106
|
+
fs7.copyFileSync(file, snap);
|
|
6107
|
+
snapshotFiles.push(snap);
|
|
6108
|
+
} catch {}
|
|
6109
|
+
}
|
|
6110
|
+
} catch {}
|
|
6111
|
+
const events = [];
|
|
6112
|
+
for (const file of snapshotFiles) {
|
|
6113
|
+
let content = "";
|
|
6114
|
+
try {
|
|
6115
|
+
content = fs7.readFileSync(file, "utf-8");
|
|
6116
|
+
} catch {
|
|
6117
|
+
continue;
|
|
6118
|
+
}
|
|
6119
|
+
for (const line of content.split(/\r?\n/)) {
|
|
6120
|
+
const trimmed = line.trim();
|
|
6121
|
+
if (!trimmed)
|
|
6122
|
+
continue;
|
|
6123
|
+
try {
|
|
6124
|
+
const parsed = JSON.parse(trimmed);
|
|
6125
|
+
if (isRecord(parsed))
|
|
6126
|
+
events.push(parsed);
|
|
6127
|
+
} catch {}
|
|
6128
|
+
}
|
|
6129
|
+
}
|
|
6130
|
+
try {
|
|
6131
|
+
for (const f of snapshotFiles) {
|
|
6132
|
+
try {
|
|
6133
|
+
fs7.unlinkSync(f);
|
|
6134
|
+
} catch {}
|
|
6135
|
+
}
|
|
6136
|
+
fs7.rmdirSync(tmpDir);
|
|
6137
|
+
} catch {}
|
|
6138
|
+
return events;
|
|
6139
|
+
}
|
|
6140
|
+
function readNumber(record, keys) {
|
|
6141
|
+
for (const key of keys) {
|
|
6142
|
+
const value = record[key];
|
|
6143
|
+
if (typeof value === "number" && Number.isFinite(value) && value >= 0)
|
|
6144
|
+
return value;
|
|
6145
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
6146
|
+
const parsed = Number(value);
|
|
6147
|
+
if (Number.isFinite(parsed) && parsed >= 0)
|
|
6148
|
+
return parsed;
|
|
6149
|
+
}
|
|
6150
|
+
}
|
|
6151
|
+
return null;
|
|
6152
|
+
}
|
|
6153
|
+
function isRecord(value) {
|
|
6154
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6155
|
+
}
|
|
6156
|
+
function createEmptySummary() {
|
|
6157
|
+
return {
|
|
6158
|
+
total_cost_usd: 0,
|
|
6159
|
+
total_reported_usd: 0,
|
|
6160
|
+
total_estimated_usd: 0,
|
|
6161
|
+
total_input_tokens: 0,
|
|
6162
|
+
total_output_tokens: 0,
|
|
6163
|
+
total_reasoning_tokens: 0,
|
|
6164
|
+
total_cache_tokens: 0,
|
|
6165
|
+
delegations: 0,
|
|
6166
|
+
unavailable_delegations: 0,
|
|
6167
|
+
by_agent: [],
|
|
6168
|
+
by_task: [],
|
|
6169
|
+
by_gate: [],
|
|
6170
|
+
by_retry: [],
|
|
6171
|
+
by_source: {
|
|
6172
|
+
reported: { delegations: 0, cost_usd: 0 },
|
|
6173
|
+
estimated: { delegations: 0, cost_usd: 0 },
|
|
6174
|
+
unavailable: { delegations: 0, cost_usd: 0 }
|
|
6175
|
+
}
|
|
6176
|
+
};
|
|
6177
|
+
}
|
|
6178
|
+
function addDelegationEvent(summary, event) {
|
|
6179
|
+
const costSource = parseCostSource(event.cost_source);
|
|
6180
|
+
const cost = readNumber(event, ["cost_usd"]) ?? 0;
|
|
6181
|
+
const usage = {
|
|
6182
|
+
tokens_input: readNumber(event, ["tokens_input"]) ?? 0,
|
|
6183
|
+
tokens_output: readNumber(event, ["tokens_output"]) ?? 0,
|
|
6184
|
+
tokens_reasoning: readNumber(event, ["tokens_reasoning"]) ?? 0,
|
|
6185
|
+
tokens_cache: readNumber(event, ["tokens_cache"]) ?? 0
|
|
6186
|
+
};
|
|
6187
|
+
summary.delegations++;
|
|
6188
|
+
summary.total_cost_usd += cost;
|
|
6189
|
+
summary.total_input_tokens += usage.tokens_input;
|
|
6190
|
+
summary.total_output_tokens += usage.tokens_output;
|
|
6191
|
+
summary.total_reasoning_tokens += usage.tokens_reasoning;
|
|
6192
|
+
summary.total_cache_tokens += usage.tokens_cache;
|
|
6193
|
+
summary.by_source[costSource].delegations++;
|
|
6194
|
+
summary.by_source[costSource].cost_usd += cost;
|
|
6195
|
+
if (costSource === "reported")
|
|
6196
|
+
summary.total_reported_usd += cost;
|
|
6197
|
+
if (costSource === "estimated")
|
|
6198
|
+
summary.total_estimated_usd += cost;
|
|
6199
|
+
if (costSource === "unavailable")
|
|
6200
|
+
summary.unavailable_delegations++;
|
|
6201
|
+
addRow(summary.by_agent, String(event.agentName ?? event.agent ?? "unknown"), {
|
|
6202
|
+
cost,
|
|
6203
|
+
costSource,
|
|
6204
|
+
usage
|
|
6205
|
+
});
|
|
6206
|
+
addRow(summary.by_task, String(event.taskId ?? event.task_id ?? "unknown"), {
|
|
6207
|
+
cost,
|
|
6208
|
+
costSource,
|
|
6209
|
+
usage
|
|
6210
|
+
});
|
|
6211
|
+
addRow(summary.by_gate, String(event.gate ?? "unknown"), {
|
|
6212
|
+
cost,
|
|
6213
|
+
costSource,
|
|
6214
|
+
usage
|
|
6215
|
+
});
|
|
6216
|
+
addRow(summary.by_retry, String(readNumber(event, ["retry_index", "retryIndex"]) ?? 0), {
|
|
6217
|
+
cost,
|
|
6218
|
+
costSource,
|
|
6219
|
+
usage
|
|
6220
|
+
});
|
|
6221
|
+
}
|
|
6222
|
+
function addRow(rows, name, input) {
|
|
6223
|
+
let row = rows.find((candidate) => candidate.name === name);
|
|
6224
|
+
if (!row) {
|
|
6225
|
+
row = {
|
|
6226
|
+
name,
|
|
6227
|
+
delegations: 0,
|
|
6228
|
+
cost_usd: 0,
|
|
6229
|
+
input_tokens: 0,
|
|
6230
|
+
output_tokens: 0,
|
|
6231
|
+
reasoning_tokens: 0,
|
|
6232
|
+
cache_tokens: 0,
|
|
6233
|
+
unavailable_delegations: 0
|
|
6234
|
+
};
|
|
6235
|
+
rows.push(row);
|
|
6236
|
+
}
|
|
6237
|
+
row.delegations++;
|
|
6238
|
+
row.cost_usd += input.cost;
|
|
6239
|
+
row.input_tokens += input.usage.tokens_input;
|
|
6240
|
+
row.output_tokens += input.usage.tokens_output;
|
|
6241
|
+
row.reasoning_tokens += input.usage.tokens_reasoning;
|
|
6242
|
+
row.cache_tokens += input.usage.tokens_cache;
|
|
6243
|
+
if (input.costSource === "unavailable")
|
|
6244
|
+
row.unavailable_delegations++;
|
|
6245
|
+
}
|
|
6246
|
+
function finalizeSummary(summary) {
|
|
6247
|
+
summary.total_cost_usd = roundUsd(summary.total_cost_usd);
|
|
6248
|
+
summary.total_reported_usd = roundUsd(summary.total_reported_usd);
|
|
6249
|
+
summary.total_estimated_usd = roundUsd(summary.total_estimated_usd);
|
|
6250
|
+
for (const source of Object.values(summary.by_source)) {
|
|
6251
|
+
source.cost_usd = roundUsd(source.cost_usd);
|
|
6252
|
+
}
|
|
6253
|
+
for (const rows of [
|
|
6254
|
+
summary.by_agent,
|
|
6255
|
+
summary.by_task,
|
|
6256
|
+
summary.by_gate,
|
|
6257
|
+
summary.by_retry
|
|
6258
|
+
]) {
|
|
6259
|
+
for (const row of rows)
|
|
6260
|
+
row.cost_usd = roundUsd(row.cost_usd);
|
|
6261
|
+
rows.sort((a, b) => b.cost_usd - a.cost_usd || b.delegations - a.delegations);
|
|
6262
|
+
}
|
|
6263
|
+
return summary;
|
|
6264
|
+
}
|
|
6265
|
+
function parseCostSource(value) {
|
|
6266
|
+
return value === "reported" || value === "estimated" || value === "unavailable" ? value : "unavailable";
|
|
6267
|
+
}
|
|
6268
|
+
function roundUsd(value) {
|
|
6269
|
+
return Math.round(value * 1e6) / 1e6;
|
|
6270
|
+
}
|
|
6271
|
+
|
|
6061
6272
|
// src/commands/benchmark.ts
|
|
6062
6273
|
var CI = {
|
|
6063
6274
|
review_pass_rate: 70,
|
|
@@ -6073,7 +6284,9 @@ async function handleBenchmarkCommand(directory, args) {
|
|
|
6073
6284
|
let cumulative = args.includes("--cumulative");
|
|
6074
6285
|
if (args.includes("--ci-gate"))
|
|
6075
6286
|
cumulative = true;
|
|
6287
|
+
const maxCostUsd = parseMaxCostUsd(args);
|
|
6076
6288
|
const mode = cumulative ? "cumulative" : "in-memory";
|
|
6289
|
+
const costSummary = cumulative ? summarizeTelemetryCosts(directory) : undefined;
|
|
6077
6290
|
const agentMap = new Map;
|
|
6078
6291
|
for (const [, s] of swarmState.agentSessions) {
|
|
6079
6292
|
const e = agentMap.get(s.agentName) || {
|
|
@@ -6265,6 +6478,15 @@ async function handleBenchmarkCommand(directory, args) {
|
|
|
6265
6478
|
passed: !hasQualityEvidence || testToCodeRatio >= CI.min_test_to_code_ratio
|
|
6266
6479
|
}
|
|
6267
6480
|
];
|
|
6481
|
+
if (maxCostUsd !== null) {
|
|
6482
|
+
checks.push({
|
|
6483
|
+
name: "Total cost",
|
|
6484
|
+
value: costSummary?.total_cost_usd ?? 0,
|
|
6485
|
+
threshold: maxCostUsd,
|
|
6486
|
+
operator: "<=",
|
|
6487
|
+
passed: (costSummary?.total_cost_usd ?? 0) <= maxCostUsd
|
|
6488
|
+
});
|
|
6489
|
+
}
|
|
6268
6490
|
ciGate = { passed: checks.every((c) => c.passed), checks };
|
|
6269
6491
|
}
|
|
6270
6492
|
const lines = [
|
|
@@ -6316,16 +6538,23 @@ async function handleBenchmarkCommand(directory, args) {
|
|
|
6316
6538
|
lines.push(`- Test-to-Code Ratio: ${qualityMetrics.testToCodeRatio}% (min: ${qualityMetrics.thresholds.minTestToCodeRatio}%) ${qualityMetrics.testToCodeRatio >= qualityMetrics.thresholds.minTestToCodeRatio ? "\u2705" : "\u274C"}`);
|
|
6317
6539
|
lines.push("");
|
|
6318
6540
|
}
|
|
6541
|
+
if (costSummary) {
|
|
6542
|
+
lines.push("### Cost Signals");
|
|
6543
|
+
lines.push(`- Total tracked cost: $${costSummary.total_cost_usd.toFixed(6)} (${costSummary.delegations} delegations)`, `- Reported: $${costSummary.total_reported_usd.toFixed(6)}; estimated: $${costSummary.total_estimated_usd.toFixed(6)}; unavailable: ${costSummary.unavailable_delegations}`);
|
|
6544
|
+
lines.push("");
|
|
6545
|
+
}
|
|
6319
6546
|
if (ciGate) {
|
|
6320
6547
|
lines.push("### CI Gate", ciGate.passed ? "\u2705 PASSED" : "\u274C FAILED");
|
|
6321
6548
|
for (const c of ciGate.checks) {
|
|
6322
6549
|
let valueStr;
|
|
6323
6550
|
if (c.name === "Complexity Delta" || c.name === "Public API Delta") {
|
|
6324
6551
|
valueStr = `${c.value}`;
|
|
6552
|
+
} else if (c.name === "Total cost") {
|
|
6553
|
+
valueStr = `$${c.value.toFixed(6)}`;
|
|
6325
6554
|
} else {
|
|
6326
6555
|
valueStr = `${c.value}%`;
|
|
6327
6556
|
}
|
|
6328
|
-
const thresholdStr = c.name === "Complexity Delta" || c.name === "Public API Delta" ? `${c.threshold}` : `${c.threshold}%`;
|
|
6557
|
+
const thresholdStr = c.name === "Complexity Delta" || c.name === "Public API Delta" ? `${c.threshold}` : c.name === "Total cost" ? `$${c.threshold.toFixed(6)}` : `${c.threshold}%`;
|
|
6329
6558
|
lines.push(`- ${c.name}: ${valueStr} ${c.operator} ${thresholdStr} ${c.passed ? "\u2705" : "\u274C"}`);
|
|
6330
6559
|
}
|
|
6331
6560
|
lines.push("");
|
|
@@ -6366,6 +6595,18 @@ async function handleBenchmarkCommand(directory, args) {
|
|
|
6366
6595
|
thresholds: qualityMetrics.thresholds,
|
|
6367
6596
|
has_evidence: qualityMetrics.hasEvidence
|
|
6368
6597
|
};
|
|
6598
|
+
if (costSummary)
|
|
6599
|
+
json.costs = {
|
|
6600
|
+
total_cost_usd: costSummary.total_cost_usd,
|
|
6601
|
+
total_reported_usd: costSummary.total_reported_usd,
|
|
6602
|
+
total_estimated_usd: costSummary.total_estimated_usd,
|
|
6603
|
+
total_input_tokens: costSummary.total_input_tokens,
|
|
6604
|
+
total_output_tokens: costSummary.total_output_tokens,
|
|
6605
|
+
total_reasoning_tokens: costSummary.total_reasoning_tokens,
|
|
6606
|
+
total_cache_tokens: costSummary.total_cache_tokens,
|
|
6607
|
+
delegations: costSummary.delegations,
|
|
6608
|
+
unavailable_delegations: costSummary.unavailable_delegations
|
|
6609
|
+
};
|
|
6369
6610
|
if (ciGate)
|
|
6370
6611
|
json.ci_gate = {
|
|
6371
6612
|
passed: ciGate.passed,
|
|
@@ -6381,6 +6622,20 @@ async function handleBenchmarkCommand(directory, args) {
|
|
|
6381
6622
|
return lines.join(`
|
|
6382
6623
|
`);
|
|
6383
6624
|
}
|
|
6625
|
+
function parseMaxCostUsd(args) {
|
|
6626
|
+
const index = args.indexOf("--max-cost-usd");
|
|
6627
|
+
if (index === -1)
|
|
6628
|
+
return null;
|
|
6629
|
+
const raw = args[index + 1];
|
|
6630
|
+
if (!raw || raw.startsWith("--")) {
|
|
6631
|
+
throw new Error("Invalid --max-cost-usd value: expected a non-negative number.");
|
|
6632
|
+
}
|
|
6633
|
+
const parsed = Number(raw);
|
|
6634
|
+
if (!Number.isFinite(parsed) || parsed < 0) {
|
|
6635
|
+
throw new Error("Invalid --max-cost-usd value: expected a non-negative number.");
|
|
6636
|
+
}
|
|
6637
|
+
return parsed;
|
|
6638
|
+
}
|
|
6384
6639
|
|
|
6385
6640
|
// src/commands/brainstorm.ts
|
|
6386
6641
|
function sanitizeTopic(raw) {
|
|
@@ -6402,8 +6657,8 @@ async function handleBrainstormCommand(_directory, args) {
|
|
|
6402
6657
|
|
|
6403
6658
|
// src/tools/checkpoint.ts
|
|
6404
6659
|
import * as child_process from "child_process";
|
|
6405
|
-
import * as
|
|
6406
|
-
import * as
|
|
6660
|
+
import * as fs8 from "fs";
|
|
6661
|
+
import * as path13 from "path";
|
|
6407
6662
|
|
|
6408
6663
|
// src/tools/create-tool.ts
|
|
6409
6664
|
function classifyToolError(error2) {
|
|
@@ -6490,13 +6745,13 @@ function validateLabel(label) {
|
|
|
6490
6745
|
return null;
|
|
6491
6746
|
}
|
|
6492
6747
|
function getCheckpointLogPath(directory) {
|
|
6493
|
-
return
|
|
6748
|
+
return path13.join(directory, CHECKPOINT_LOG_PATH);
|
|
6494
6749
|
}
|
|
6495
6750
|
function readCheckpointLog(directory) {
|
|
6496
6751
|
const logPath = getCheckpointLogPath(directory);
|
|
6497
6752
|
try {
|
|
6498
|
-
if (
|
|
6499
|
-
const content =
|
|
6753
|
+
if (fs8.existsSync(logPath)) {
|
|
6754
|
+
const content = fs8.readFileSync(logPath, "utf-8");
|
|
6500
6755
|
const parsed = JSON.parse(content);
|
|
6501
6756
|
if (!parsed.checkpoints || !Array.isArray(parsed.checkpoints)) {
|
|
6502
6757
|
return { version: 1, checkpoints: [] };
|
|
@@ -6508,13 +6763,13 @@ function readCheckpointLog(directory) {
|
|
|
6508
6763
|
}
|
|
6509
6764
|
function writeCheckpointLog(log2, directory) {
|
|
6510
6765
|
const logPath = getCheckpointLogPath(directory);
|
|
6511
|
-
const dir =
|
|
6512
|
-
if (!
|
|
6513
|
-
|
|
6766
|
+
const dir = path13.dirname(logPath);
|
|
6767
|
+
if (!fs8.existsSync(dir)) {
|
|
6768
|
+
fs8.mkdirSync(dir, { recursive: true });
|
|
6514
6769
|
}
|
|
6515
6770
|
const tempPath = `${logPath}.tmp`;
|
|
6516
|
-
|
|
6517
|
-
|
|
6771
|
+
fs8.writeFileSync(tempPath, JSON.stringify(log2, null, 2), "utf-8");
|
|
6772
|
+
fs8.renameSync(tempPath, logPath);
|
|
6518
6773
|
}
|
|
6519
6774
|
function gitExec(args, cwd) {
|
|
6520
6775
|
for (let attempt = 0;attempt < MAX_TRANSIENT_RETRIES; attempt++) {
|
|
@@ -6545,10 +6800,10 @@ function gitExec(args, cwd) {
|
|
|
6545
6800
|
}
|
|
6546
6801
|
function appendRetentionEvent(directory, event) {
|
|
6547
6802
|
try {
|
|
6548
|
-
const eventsPath =
|
|
6803
|
+
const eventsPath = path13.join(directory, ".swarm", "events.jsonl");
|
|
6549
6804
|
const line = `${JSON.stringify({ ...event, timestamp: new Date().toISOString() })}
|
|
6550
6805
|
`;
|
|
6551
|
-
|
|
6806
|
+
fs8.appendFileSync(eventsPath, line);
|
|
6552
6807
|
} catch {}
|
|
6553
6808
|
}
|
|
6554
6809
|
function getCurrentSha(directory) {
|
|
@@ -6910,8 +7165,8 @@ async function handleClarifyCommand(_directory, args) {
|
|
|
6910
7165
|
// src/commands/close.ts
|
|
6911
7166
|
import { spawnSync as spawnSync5 } from "child_process";
|
|
6912
7167
|
import * as fsSync2 from "fs";
|
|
6913
|
-
import { promises as
|
|
6914
|
-
import
|
|
7168
|
+
import { promises as fs13 } from "fs";
|
|
7169
|
+
import path26 from "path";
|
|
6915
7170
|
|
|
6916
7171
|
// src/hooks/abort-utils.ts
|
|
6917
7172
|
function isAbortError(err) {
|
|
@@ -7040,8 +7295,8 @@ function createCuratorLLMDelegate(directory, mode = "init", sessionId) {
|
|
|
7040
7295
|
}
|
|
7041
7296
|
|
|
7042
7297
|
// src/hooks/curator-postmortem.ts
|
|
7043
|
-
import { existsSync as
|
|
7044
|
-
import * as
|
|
7298
|
+
import { existsSync as existsSync6, readdirSync, readFileSync as readFileSync6 } from "fs";
|
|
7299
|
+
import * as path14 from "path";
|
|
7045
7300
|
var MAX_INPUT_TEXT_CHARS = 500;
|
|
7046
7301
|
var MAX_KNOWLEDGE_ENTRIES = 500;
|
|
7047
7302
|
var MAX_PROPOSALS = 50;
|
|
@@ -7086,9 +7341,9 @@ async function collectKnowledgeSummary(directory) {
|
|
|
7086
7341
|
}
|
|
7087
7342
|
function readJsonlFile(filePath, maxLines) {
|
|
7088
7343
|
try {
|
|
7089
|
-
if (!
|
|
7344
|
+
if (!existsSync6(filePath))
|
|
7090
7345
|
return [];
|
|
7091
|
-
const content =
|
|
7346
|
+
const content = readFileSync6(filePath, "utf-8");
|
|
7092
7347
|
const results = [];
|
|
7093
7348
|
const max = maxLines !== undefined && maxLines > 0 ? maxLines : Infinity;
|
|
7094
7349
|
for (const line of content.split(`
|
|
@@ -7108,16 +7363,16 @@ function readJsonlFile(filePath, maxLines) {
|
|
|
7108
7363
|
}
|
|
7109
7364
|
function collectRetrospectives(directory) {
|
|
7110
7365
|
const results = [];
|
|
7111
|
-
const evidenceDir =
|
|
7366
|
+
const evidenceDir = path14.join(directory, ".swarm", "evidence");
|
|
7112
7367
|
try {
|
|
7113
|
-
if (!
|
|
7368
|
+
if (!existsSync6(evidenceDir))
|
|
7114
7369
|
return results;
|
|
7115
7370
|
const retroDirs = readdirSync(evidenceDir, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name.startsWith("retro-")).slice(0, MAX_RETROSPECTIVES);
|
|
7116
7371
|
for (const entry of retroDirs) {
|
|
7117
|
-
const retroPath =
|
|
7118
|
-
if (
|
|
7372
|
+
const retroPath = path14.join(evidenceDir, entry.name, "evidence.json");
|
|
7373
|
+
if (existsSync6(retroPath)) {
|
|
7119
7374
|
try {
|
|
7120
|
-
results.push(
|
|
7375
|
+
results.push(readFileSync6(retroPath, "utf-8"));
|
|
7121
7376
|
} catch {}
|
|
7122
7377
|
}
|
|
7123
7378
|
}
|
|
@@ -7126,14 +7381,14 @@ function collectRetrospectives(directory) {
|
|
|
7126
7381
|
}
|
|
7127
7382
|
function collectDriftReports(directory) {
|
|
7128
7383
|
const results = [];
|
|
7129
|
-
const swarmDir =
|
|
7384
|
+
const swarmDir = path14.join(directory, ".swarm");
|
|
7130
7385
|
try {
|
|
7131
|
-
if (!
|
|
7386
|
+
if (!existsSync6(swarmDir))
|
|
7132
7387
|
return results;
|
|
7133
7388
|
const driftFiles = readdirSync(swarmDir).filter((e) => e.startsWith("drift-report-phase-") && e.endsWith(".json")).slice(0, MAX_DRIFT_REPORTS);
|
|
7134
7389
|
for (const entry of driftFiles) {
|
|
7135
7390
|
try {
|
|
7136
|
-
results.push(
|
|
7391
|
+
results.push(readFileSync6(path14.join(swarmDir, entry), "utf-8"));
|
|
7137
7392
|
} catch {}
|
|
7138
7393
|
}
|
|
7139
7394
|
} catch {}
|
|
@@ -7141,24 +7396,24 @@ function collectDriftReports(directory) {
|
|
|
7141
7396
|
}
|
|
7142
7397
|
function collectPendingProposals(directory) {
|
|
7143
7398
|
const results = [];
|
|
7144
|
-
const insightPath =
|
|
7145
|
-
if (
|
|
7399
|
+
const insightPath = path14.join(directory, ".swarm", "insight-candidates.jsonl");
|
|
7400
|
+
if (existsSync6(insightPath)) {
|
|
7146
7401
|
try {
|
|
7147
7402
|
results.push({
|
|
7148
7403
|
source: "insight-candidates",
|
|
7149
|
-
content:
|
|
7404
|
+
content: readFileSync6(insightPath, "utf-8")
|
|
7150
7405
|
});
|
|
7151
7406
|
} catch {}
|
|
7152
7407
|
}
|
|
7153
|
-
const proposalsDir =
|
|
7408
|
+
const proposalsDir = path14.join(directory, ".swarm", "skills", "proposals");
|
|
7154
7409
|
try {
|
|
7155
|
-
if (
|
|
7410
|
+
if (existsSync6(proposalsDir)) {
|
|
7156
7411
|
const proposalFiles = readdirSync(proposalsDir).filter((e) => e.endsWith(".md") || e.endsWith(".json")).slice(0, MAX_PROPOSALS);
|
|
7157
7412
|
for (const entry of proposalFiles) {
|
|
7158
7413
|
try {
|
|
7159
7414
|
results.push({
|
|
7160
7415
|
source: `proposals/${entry}`,
|
|
7161
|
-
content:
|
|
7416
|
+
content: readFileSync6(path14.join(proposalsDir, entry), "utf-8")
|
|
7162
7417
|
});
|
|
7163
7418
|
} catch {}
|
|
7164
7419
|
}
|
|
@@ -7168,9 +7423,9 @@ function collectPendingProposals(directory) {
|
|
|
7168
7423
|
}
|
|
7169
7424
|
function isReportValid(reportPath) {
|
|
7170
7425
|
try {
|
|
7171
|
-
if (!
|
|
7426
|
+
if (!existsSync6(reportPath))
|
|
7172
7427
|
return false;
|
|
7173
|
-
const content =
|
|
7428
|
+
const content = readFileSync6(reportPath, "utf-8").trim();
|
|
7174
7429
|
if (content.length === 0)
|
|
7175
7430
|
return false;
|
|
7176
7431
|
if (!content.startsWith("# Post-Mortem Report:"))
|
|
@@ -7379,7 +7634,7 @@ async function runCuratorPostMortem(directory, options = {}) {
|
|
|
7379
7634
|
warnings.push(`Pending proposals capped at ${MAX_PROPOSALS} (had ${proposals.length}); older entries truncated.`);
|
|
7380
7635
|
proposals = proposals.slice(0, MAX_PROPOSALS);
|
|
7381
7636
|
}
|
|
7382
|
-
const unactionablePath =
|
|
7637
|
+
const unactionablePath = path14.join(resolveKnowledgeStoreDir(directory), "knowledge-unactionable.jsonl");
|
|
7383
7638
|
let unactionable = readJsonlFile(unactionablePath, MAX_UNACTIONABLE);
|
|
7384
7639
|
if (unactionable.length > MAX_UNACTIONABLE) {
|
|
7385
7640
|
warnings.push(`Unactionable entries capped at ${MAX_UNACTIONABLE} (had ${unactionable.length}); older entries truncated.`);
|
|
@@ -7398,7 +7653,7 @@ async function runCuratorPostMortem(directory, options = {}) {
|
|
|
7398
7653
|
let reportContent;
|
|
7399
7654
|
if (options.llmDelegate) {
|
|
7400
7655
|
try {
|
|
7401
|
-
const { CURATOR_POSTMORTEM_PROMPT: CURATOR_POSTMORTEM_PROMPT2 } = await import("./explorer-
|
|
7656
|
+
const { CURATOR_POSTMORTEM_PROMPT: CURATOR_POSTMORTEM_PROMPT2 } = await import("./explorer-rwfvbbx5.js");
|
|
7402
7657
|
const userInput = assembleLLMInput(effectivePlanId, planSummary, knowledgeSummary, curatorDigest, proposals, unactionable, retrospectives, driftReports);
|
|
7403
7658
|
const ac = new AbortController;
|
|
7404
7659
|
const timer = setTimeout(() => ac.abort(), 300000);
|
|
@@ -7429,7 +7684,7 @@ ${llmOutput}`;
|
|
|
7429
7684
|
}
|
|
7430
7685
|
try {
|
|
7431
7686
|
const { mkdirSync: mkdirSync6 } = await import("fs");
|
|
7432
|
-
mkdirSync6(
|
|
7687
|
+
mkdirSync6(path14.dirname(reportPath), { recursive: true });
|
|
7433
7688
|
await atomicWriteFile(reportPath, reportContent);
|
|
7434
7689
|
} catch (err) {
|
|
7435
7690
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -7477,7 +7732,7 @@ var _internals13 = {
|
|
|
7477
7732
|
};
|
|
7478
7733
|
|
|
7479
7734
|
// src/hooks/hive-promoter.ts
|
|
7480
|
-
import
|
|
7735
|
+
import path17 from "path";
|
|
7481
7736
|
|
|
7482
7737
|
// src/background/event-bus.ts
|
|
7483
7738
|
class AutomationEventBus {
|
|
@@ -7981,9 +8236,9 @@ init_logger();
|
|
|
7981
8236
|
|
|
7982
8237
|
// src/services/skill-improver-quota.ts
|
|
7983
8238
|
var import_proper_lockfile2 = __toESM(require_proper_lockfile(), 1);
|
|
7984
|
-
import { existsSync as
|
|
8239
|
+
import { existsSync as existsSync7 } from "fs";
|
|
7985
8240
|
import { mkdir as mkdir3, readFile as readFile3, rename, writeFile as writeFile2 } from "fs/promises";
|
|
7986
|
-
import * as
|
|
8241
|
+
import * as path15 from "path";
|
|
7987
8242
|
var LOCK_ACQUIRE_TIMEOUT_MS = 1e4;
|
|
7988
8243
|
var LOCK_RETRY_OPTS = {
|
|
7989
8244
|
retries: {
|
|
@@ -8012,7 +8267,7 @@ async function acquireLock(dir) {
|
|
|
8012
8267
|
}
|
|
8013
8268
|
function resolveQuotaPath(directory, scope = "skill-improver") {
|
|
8014
8269
|
const fileName = scope === "knowledge-enrichment" ? "knowledge-enrichment-quota.json" : "skill-improver-quota.json";
|
|
8015
|
-
return
|
|
8270
|
+
return path15.join(directory, ".swarm", fileName);
|
|
8016
8271
|
}
|
|
8017
8272
|
function todayKey(window, now = new Date) {
|
|
8018
8273
|
if (window === "utc") {
|
|
@@ -8024,7 +8279,7 @@ function todayKey(window, now = new Date) {
|
|
|
8024
8279
|
return `${yr}-${m}-${d}`;
|
|
8025
8280
|
}
|
|
8026
8281
|
async function readState(filePath) {
|
|
8027
|
-
if (!
|
|
8282
|
+
if (!existsSync7(filePath))
|
|
8028
8283
|
return null;
|
|
8029
8284
|
try {
|
|
8030
8285
|
const raw = await readFile3(filePath, "utf-8");
|
|
@@ -8038,7 +8293,7 @@ async function readState(filePath) {
|
|
|
8038
8293
|
}
|
|
8039
8294
|
}
|
|
8040
8295
|
async function writeState(filePath, state) {
|
|
8041
|
-
await mkdir3(
|
|
8296
|
+
await mkdir3(path15.dirname(filePath), { recursive: true });
|
|
8042
8297
|
const tmp = `${filePath}.tmp-${process.pid}`;
|
|
8043
8298
|
await writeFile2(tmp, JSON.stringify(state, null, 2), "utf-8");
|
|
8044
8299
|
await rename(tmp, filePath);
|
|
@@ -8061,10 +8316,10 @@ async function getQuotaState(directory, opts) {
|
|
|
8061
8316
|
}
|
|
8062
8317
|
async function reserveQuota(directory, opts) {
|
|
8063
8318
|
const filePath = resolveQuotaPath(directory, opts.scope);
|
|
8064
|
-
await mkdir3(
|
|
8319
|
+
await mkdir3(path15.dirname(filePath), { recursive: true });
|
|
8065
8320
|
let release = null;
|
|
8066
8321
|
try {
|
|
8067
|
-
release = await acquireLock(
|
|
8322
|
+
release = await acquireLock(path15.dirname(filePath));
|
|
8068
8323
|
const state = await getQuotaState(directory, opts);
|
|
8069
8324
|
if (state.calls_used + opts.nCalls > opts.maxCalls) {
|
|
8070
8325
|
return {
|
|
@@ -8091,10 +8346,10 @@ async function reserveQuota(directory, opts) {
|
|
|
8091
8346
|
}
|
|
8092
8347
|
async function releaseQuota(directory, opts) {
|
|
8093
8348
|
const filePath = resolveQuotaPath(directory, opts.scope);
|
|
8094
|
-
await mkdir3(
|
|
8349
|
+
await mkdir3(path15.dirname(filePath), { recursive: true });
|
|
8095
8350
|
let release = null;
|
|
8096
8351
|
try {
|
|
8097
|
-
release = await acquireLock(
|
|
8352
|
+
release = await acquireLock(path15.dirname(filePath));
|
|
8098
8353
|
const state = await getQuotaState(directory, opts);
|
|
8099
8354
|
const next = {
|
|
8100
8355
|
...state,
|
|
@@ -8117,8 +8372,8 @@ init_logger();
|
|
|
8117
8372
|
|
|
8118
8373
|
// src/hooks/skill-usage-log.ts
|
|
8119
8374
|
import * as crypto3 from "crypto";
|
|
8120
|
-
import * as
|
|
8121
|
-
import * as
|
|
8375
|
+
import * as fs9 from "fs";
|
|
8376
|
+
import * as path16 from "path";
|
|
8122
8377
|
function resolveLogPath(directory) {
|
|
8123
8378
|
return validateSwarmPath(directory, "skill-usage.jsonl");
|
|
8124
8379
|
}
|
|
@@ -8127,16 +8382,16 @@ function normalizeComplianceVerdict(verdict) {
|
|
|
8127
8382
|
}
|
|
8128
8383
|
var _internals14 = {
|
|
8129
8384
|
generateId: () => crypto3.randomUUID(),
|
|
8130
|
-
appendFileSync:
|
|
8131
|
-
readFileSync:
|
|
8132
|
-
writeFileSync:
|
|
8133
|
-
renameSync:
|
|
8134
|
-
mkdirSync:
|
|
8135
|
-
existsSync:
|
|
8136
|
-
statSync:
|
|
8137
|
-
openSync:
|
|
8138
|
-
readSync:
|
|
8139
|
-
closeSync:
|
|
8385
|
+
appendFileSync: fs9.appendFileSync.bind(fs9),
|
|
8386
|
+
readFileSync: fs9.readFileSync.bind(fs9),
|
|
8387
|
+
writeFileSync: fs9.writeFileSync.bind(fs9),
|
|
8388
|
+
renameSync: fs9.renameSync.bind(fs9),
|
|
8389
|
+
mkdirSync: fs9.mkdirSync.bind(fs9),
|
|
8390
|
+
existsSync: fs9.existsSync.bind(fs9),
|
|
8391
|
+
statSync: fs9.statSync.bind(fs9),
|
|
8392
|
+
openSync: fs9.openSync.bind(fs9),
|
|
8393
|
+
readSync: fs9.readSync.bind(fs9),
|
|
8394
|
+
closeSync: fs9.closeSync.bind(fs9),
|
|
8140
8395
|
pruneSkillUsageLog,
|
|
8141
8396
|
resolveSourceKnowledgeIds,
|
|
8142
8397
|
applySkillUsageFeedback,
|
|
@@ -8217,7 +8472,7 @@ function appendFeedbackAppliedMarker(directory, processedEntryIds) {
|
|
|
8217
8472
|
if (processedEntryIds.length === 0)
|
|
8218
8473
|
return;
|
|
8219
8474
|
const resolved = resolveLogPath(directory);
|
|
8220
|
-
const dir =
|
|
8475
|
+
const dir = path16.dirname(resolved);
|
|
8221
8476
|
if (!_internals14.existsSync(dir)) {
|
|
8222
8477
|
_internals14.mkdirSync(dir, { recursive: true });
|
|
8223
8478
|
}
|
|
@@ -8262,7 +8517,7 @@ function appendSkillUsageEntry(directory, entry) {
|
|
|
8262
8517
|
throw new Error("sessionID is required and must be a non-empty string");
|
|
8263
8518
|
}
|
|
8264
8519
|
const resolved = validateSwarmPath(directory, "skill-usage.jsonl");
|
|
8265
|
-
const dir =
|
|
8520
|
+
const dir = path16.dirname(resolved);
|
|
8266
8521
|
if (!_internals14.existsSync(dir)) {
|
|
8267
8522
|
_internals14.mkdirSync(dir, { recursive: true });
|
|
8268
8523
|
}
|
|
@@ -8438,8 +8693,8 @@ function pruneSkillUsageLog(directory, maxEntriesPerSkill = 500) {
|
|
|
8438
8693
|
}
|
|
8439
8694
|
if (entries.length === 0) {
|
|
8440
8695
|
if (preservedMarkers.length > 0) {
|
|
8441
|
-
const dir2 =
|
|
8442
|
-
const tmpPath2 =
|
|
8696
|
+
const dir2 = path16.dirname(resolved);
|
|
8697
|
+
const tmpPath2 = path16.join(dir2, `skill-usage-${Date.now()}.tmp`);
|
|
8443
8698
|
const content2 = preservedMarkers.join(`
|
|
8444
8699
|
`).concat(preservedMarkers.length > 0 ? `
|
|
8445
8700
|
` : "");
|
|
@@ -8481,8 +8736,8 @@ function pruneSkillUsageLog(directory, maxEntriesPerSkill = 500) {
|
|
|
8481
8736
|
if (pruned === 0) {
|
|
8482
8737
|
return { pruned: 0, remaining: entries.length };
|
|
8483
8738
|
}
|
|
8484
|
-
const dir =
|
|
8485
|
-
const tmpPath =
|
|
8739
|
+
const dir = path16.dirname(resolved);
|
|
8740
|
+
const tmpPath = path16.join(dir, `skill-usage-${Date.now()}.tmp`);
|
|
8486
8741
|
const entryLines = surviving.map((e) => JSON.stringify(e));
|
|
8487
8742
|
const allLines = [...entryLines, ...preservedMarkers];
|
|
8488
8743
|
const content = allLines.join(`
|
|
@@ -8511,9 +8766,9 @@ async function resolveSourceKnowledgeIds(directory, skillPath) {
|
|
|
8511
8766
|
if (/\.\.[/\\]/.test(cleanPath)) {
|
|
8512
8767
|
return [];
|
|
8513
8768
|
}
|
|
8514
|
-
const absolute =
|
|
8515
|
-
const baseDir =
|
|
8516
|
-
const isContained = process.platform === "win32" ? absolute.toLowerCase().startsWith((baseDir +
|
|
8769
|
+
const absolute = path16.normalize(path16.isAbsolute(cleanPath) ? cleanPath : path16.resolve(directory, cleanPath));
|
|
8770
|
+
const baseDir = path16.normalize(path16.resolve(directory));
|
|
8771
|
+
const isContained = process.platform === "win32" ? absolute.toLowerCase().startsWith((baseDir + path16.sep).toLowerCase()) : absolute.startsWith(baseDir + path16.sep);
|
|
8517
8772
|
if (!isContained) {
|
|
8518
8773
|
return [];
|
|
8519
8774
|
}
|
|
@@ -8825,7 +9080,7 @@ async function promoteToHive(directory, lesson, category) {
|
|
|
8825
9080
|
schema_version: 1,
|
|
8826
9081
|
created_at: new Date().toISOString(),
|
|
8827
9082
|
updated_at: new Date().toISOString(),
|
|
8828
|
-
source_project:
|
|
9083
|
+
source_project: path17.basename(directory) || "unknown",
|
|
8829
9084
|
encounter_score: 1
|
|
8830
9085
|
};
|
|
8831
9086
|
await appendKnowledge(resolveHiveKnowledgePath(), newHiveEntry);
|
|
@@ -8877,9 +9132,9 @@ async function promoteFromSwarm(directory, lessonId) {
|
|
|
8877
9132
|
|
|
8878
9133
|
// src/hooks/knowledge-curator.ts
|
|
8879
9134
|
import { createHash as createHash3 } from "crypto";
|
|
8880
|
-
import { existsSync as
|
|
9135
|
+
import { existsSync as existsSync11 } from "fs";
|
|
8881
9136
|
import { appendFile as appendFile2, mkdir as mkdir5, readFile as readFile6, writeFile as writeFile5 } from "fs/promises";
|
|
8882
|
-
import * as
|
|
9137
|
+
import * as path22 from "path";
|
|
8883
9138
|
|
|
8884
9139
|
// src/services/synonym-map.ts
|
|
8885
9140
|
var import_proper_lockfile3 = __toESM(require_proper_lockfile(), 1);
|
|
@@ -8891,7 +9146,7 @@ import {
|
|
|
8891
9146
|
unlink as unlink2,
|
|
8892
9147
|
writeFile as writeFile3
|
|
8893
9148
|
} from "fs/promises";
|
|
8894
|
-
import * as
|
|
9149
|
+
import * as path18 from "path";
|
|
8895
9150
|
var SYNONYM_MAP_FILENAME = "synonym-map.json";
|
|
8896
9151
|
var MAX_TOKEN_LENGTH = 64;
|
|
8897
9152
|
var DEFAULT_MAX_PAIRS = 500;
|
|
@@ -9046,7 +9301,7 @@ async function readSynonymMap(directory, maxPairs = DEFAULT_MAX_PAIRS) {
|
|
|
9046
9301
|
}
|
|
9047
9302
|
}
|
|
9048
9303
|
async function writeSynonymMapAtomic(filePath, map) {
|
|
9049
|
-
await mkdir4(
|
|
9304
|
+
await mkdir4(path18.dirname(filePath), { recursive: true });
|
|
9050
9305
|
const tmp = `${filePath}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`;
|
|
9051
9306
|
try {
|
|
9052
9307
|
await writeFile3(tmp, JSON.stringify(map, null, 2), "utf-8");
|
|
@@ -9059,7 +9314,7 @@ async function writeSynonymMapAtomic(filePath, map) {
|
|
|
9059
9314
|
}
|
|
9060
9315
|
async function rebuildSynonymMap(directory, entries, maxPairs = DEFAULT_MAX_PAIRS) {
|
|
9061
9316
|
const filePath = resolveSynonymMapPath(directory);
|
|
9062
|
-
const dir =
|
|
9317
|
+
const dir = path18.dirname(filePath);
|
|
9063
9318
|
await mkdir4(dir, { recursive: true });
|
|
9064
9319
|
let release = null;
|
|
9065
9320
|
try {
|
|
@@ -9122,19 +9377,19 @@ function reinforceSwarmKnowledgeEntry(entry, confirmation) {
|
|
|
9122
9377
|
}
|
|
9123
9378
|
|
|
9124
9379
|
// src/hooks/micro-reflector.ts
|
|
9125
|
-
import { existsSync as
|
|
9380
|
+
import { existsSync as existsSync10 } from "fs";
|
|
9126
9381
|
import { readFile as readFile5, writeFile as writeFile4 } from "fs/promises";
|
|
9127
|
-
import * as
|
|
9382
|
+
import * as path21 from "path";
|
|
9128
9383
|
init_logger();
|
|
9129
9384
|
|
|
9130
9385
|
// src/hooks/skill-propagation-gate.ts
|
|
9131
|
-
import * as
|
|
9132
|
-
import * as
|
|
9386
|
+
import * as fs11 from "fs";
|
|
9387
|
+
import * as path20 from "path";
|
|
9133
9388
|
init_logger();
|
|
9134
9389
|
|
|
9135
9390
|
// src/hooks/skill-scoring.ts
|
|
9136
|
-
import * as
|
|
9137
|
-
import * as
|
|
9391
|
+
import * as fs10 from "fs";
|
|
9392
|
+
import * as path19 from "path";
|
|
9138
9393
|
var FREQUENCY_CAP = 10;
|
|
9139
9394
|
var FREQUENCY_WEIGHT = 0.3;
|
|
9140
9395
|
var COMPLIANCE_WEIGHT = 0.3;
|
|
@@ -9162,10 +9417,10 @@ var _internals15 = {
|
|
|
9162
9417
|
computeTriggerMatchBoost: null
|
|
9163
9418
|
};
|
|
9164
9419
|
function extractSkillName(skillPath) {
|
|
9165
|
-
const base =
|
|
9420
|
+
const base = path19.basename(skillPath, path19.extname(skillPath));
|
|
9166
9421
|
if (base !== "SKILL")
|
|
9167
9422
|
return base;
|
|
9168
|
-
const parent =
|
|
9423
|
+
const parent = path19.basename(path19.dirname(skillPath));
|
|
9169
9424
|
return parent;
|
|
9170
9425
|
}
|
|
9171
9426
|
function stripQuotes(value) {
|
|
@@ -9307,25 +9562,25 @@ function parseSkillFrontmatter(content, skillPath) {
|
|
|
9307
9562
|
return meta;
|
|
9308
9563
|
}
|
|
9309
9564
|
function readFilePrefix(filePath) {
|
|
9310
|
-
const fd =
|
|
9565
|
+
const fd = fs10.openSync(filePath, "r");
|
|
9311
9566
|
try {
|
|
9312
9567
|
const buffer = Buffer.alloc(SKILL_FRONTMATTER_READ_BYTES);
|
|
9313
|
-
const bytesRead =
|
|
9568
|
+
const bytesRead = fs10.readSync(fd, buffer, 0, SKILL_FRONTMATTER_READ_BYTES, 0);
|
|
9314
9569
|
return buffer.toString("utf-8", 0, bytesRead);
|
|
9315
9570
|
} finally {
|
|
9316
|
-
|
|
9571
|
+
fs10.closeSync(fd);
|
|
9317
9572
|
}
|
|
9318
9573
|
}
|
|
9319
9574
|
function readSkillMetadata(skillPath, directory) {
|
|
9320
9575
|
const normalizedPath = skillPath.replace(/^file:/, "").replace(/\\/g, "/");
|
|
9321
9576
|
const fallback = parseSkillFrontmatter("", normalizedPath);
|
|
9322
9577
|
try {
|
|
9323
|
-
if (
|
|
9578
|
+
if (path19.isAbsolute(normalizedPath) || normalizedPath.split("/").includes("..")) {
|
|
9324
9579
|
return fallback;
|
|
9325
9580
|
}
|
|
9326
|
-
const root =
|
|
9327
|
-
const absolutePath =
|
|
9328
|
-
if (absolutePath !== root && !absolutePath.startsWith(root +
|
|
9581
|
+
const root = path19.resolve(directory);
|
|
9582
|
+
const absolutePath = path19.resolve(directory, normalizedPath);
|
|
9583
|
+
if (absolutePath !== root && !absolutePath.startsWith(root + path19.sep)) {
|
|
9329
9584
|
return fallback;
|
|
9330
9585
|
}
|
|
9331
9586
|
const content = readFilePrefix(absolutePath);
|
|
@@ -9459,10 +9714,10 @@ function getSkillStats(skillPath, directory) {
|
|
|
9459
9714
|
};
|
|
9460
9715
|
}
|
|
9461
9716
|
function formatSkillIndexWithContext(skills, directory) {
|
|
9462
|
-
const usageLogPath =
|
|
9717
|
+
const usageLogPath = path19.join(directory, ".swarm", "skill-usage.jsonl");
|
|
9463
9718
|
let hasHistory = false;
|
|
9464
9719
|
try {
|
|
9465
|
-
const stat4 =
|
|
9720
|
+
const stat4 = fs10.statSync(usageLogPath);
|
|
9466
9721
|
hasHistory = stat4.size > 0;
|
|
9467
9722
|
} catch {}
|
|
9468
9723
|
if (!hasHistory) {
|
|
@@ -9593,7 +9848,7 @@ function parseYamlValue(value) {
|
|
|
9593
9848
|
return trimmed;
|
|
9594
9849
|
}
|
|
9595
9850
|
function loadRoutingSkills(directory, targetAgent) {
|
|
9596
|
-
const routingPath =
|
|
9851
|
+
const routingPath = path20.join(directory, ".opencode", "skill-routing.yaml");
|
|
9597
9852
|
if (!_internals16.existsSync(routingPath))
|
|
9598
9853
|
return [];
|
|
9599
9854
|
try {
|
|
@@ -9625,13 +9880,13 @@ var SKILL_SEARCH_ROOTS = [
|
|
|
9625
9880
|
];
|
|
9626
9881
|
var MAX_SCORING_SESSION_ENTRIES = 500;
|
|
9627
9882
|
var _internals16 = {
|
|
9628
|
-
readdirSync:
|
|
9629
|
-
existsSync:
|
|
9630
|
-
statSync:
|
|
9631
|
-
mkdirSync:
|
|
9632
|
-
appendFileSync:
|
|
9633
|
-
readFileSync:
|
|
9634
|
-
writeFileSync:
|
|
9883
|
+
readdirSync: fs11.readdirSync.bind(fs11),
|
|
9884
|
+
existsSync: fs11.existsSync.bind(fs11),
|
|
9885
|
+
statSync: fs11.statSync.bind(fs11),
|
|
9886
|
+
mkdirSync: fs11.mkdirSync.bind(fs11),
|
|
9887
|
+
appendFileSync: fs11.appendFileSync.bind(fs11),
|
|
9888
|
+
readFileSync: fs11.readFileSync.bind(fs11),
|
|
9889
|
+
writeFileSync: fs11.writeFileSync.bind(fs11),
|
|
9635
9890
|
skillPropagationGateBefore: null,
|
|
9636
9891
|
skillPropagationTransformScan: null,
|
|
9637
9892
|
SKILL_CAPABLE_AGENTS,
|
|
@@ -9653,7 +9908,7 @@ var _internals16 = {
|
|
|
9653
9908
|
function discoverAvailableSkills(directory) {
|
|
9654
9909
|
const results = [];
|
|
9655
9910
|
for (const root of SKILL_SEARCH_ROOTS) {
|
|
9656
|
-
const rootPath =
|
|
9911
|
+
const rootPath = path20.join(directory, root);
|
|
9657
9912
|
if (!_internals16.existsSync(rootPath))
|
|
9658
9913
|
continue;
|
|
9659
9914
|
let entries;
|
|
@@ -9665,13 +9920,13 @@ function discoverAvailableSkills(directory) {
|
|
|
9665
9920
|
for (const entry of entries) {
|
|
9666
9921
|
if (entry.startsWith("."))
|
|
9667
9922
|
continue;
|
|
9668
|
-
const skillDir =
|
|
9669
|
-
if (_internals16.existsSync(
|
|
9923
|
+
const skillDir = path20.join(rootPath, entry);
|
|
9924
|
+
if (_internals16.existsSync(path20.join(skillDir, "retired.marker")) || _internals16.existsSync(path20.join(skillDir, "stale.marker")))
|
|
9670
9925
|
continue;
|
|
9671
|
-
const skillFile =
|
|
9926
|
+
const skillFile = path20.join(skillDir, "SKILL.md");
|
|
9672
9927
|
try {
|
|
9673
9928
|
if (_internals16.statSync(skillDir).isDirectory() && _internals16.existsSync(skillFile)) {
|
|
9674
|
-
results.push(
|
|
9929
|
+
results.push(path20.join(root, entry, "SKILL.md").replace(/\\/g, "/"));
|
|
9675
9930
|
}
|
|
9676
9931
|
} catch (err) {
|
|
9677
9932
|
warn(`[skill-propagation-gate] failed to stat skill directory ${entry}: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -9740,9 +9995,9 @@ function extractSkillsFieldFromPrompt(prompt) {
|
|
|
9740
9995
|
return "";
|
|
9741
9996
|
}
|
|
9742
9997
|
function writeWarnEvent(directory, record) {
|
|
9743
|
-
const filePath =
|
|
9998
|
+
const filePath = path20.join(directory, ".swarm", "events.jsonl");
|
|
9744
9999
|
try {
|
|
9745
|
-
const dir =
|
|
10000
|
+
const dir = path20.dirname(filePath);
|
|
9746
10001
|
if (!_internals16.existsSync(dir)) {
|
|
9747
10002
|
_internals16.mkdirSync(dir, { recursive: true });
|
|
9748
10003
|
}
|
|
@@ -9871,8 +10126,8 @@ async function skillPropagationGateBefore(directory, input, config) {
|
|
|
9871
10126
|
if (routingPaths.length > 0) {
|
|
9872
10127
|
const existingPaths = new Set(scored.map((s) => s.skillPath));
|
|
9873
10128
|
for (const routingPath of routingPaths) {
|
|
9874
|
-
const routedSkillDir =
|
|
9875
|
-
if (_internals16.existsSync(
|
|
10129
|
+
const routedSkillDir = path20.dirname(path20.join(directory, routingPath));
|
|
10130
|
+
if (_internals16.existsSync(path20.join(routedSkillDir, "retired.marker")) || _internals16.existsSync(path20.join(routedSkillDir, "stale.marker")))
|
|
9876
10131
|
continue;
|
|
9877
10132
|
if (!existingPaths.has(routingPath)) {
|
|
9878
10133
|
scored.push({
|
|
@@ -9891,8 +10146,8 @@ async function skillPropagationGateBefore(directory, input, config) {
|
|
|
9891
10146
|
let skillsForIndex = availableSkills;
|
|
9892
10147
|
if (scoringSkipped) {
|
|
9893
10148
|
skillsForIndex = [...availableSkills].sort((a, b) => {
|
|
9894
|
-
const nameA =
|
|
9895
|
-
const nameB =
|
|
10149
|
+
const nameA = path20.basename(path20.dirname(a));
|
|
10150
|
+
const nameB = path20.basename(path20.dirname(b));
|
|
9896
10151
|
return nameA.localeCompare(nameB);
|
|
9897
10152
|
});
|
|
9898
10153
|
} else if (typeof scored !== "undefined" && scored.length > 0) {
|
|
@@ -9900,7 +10155,7 @@ async function skillPropagationGateBefore(directory, input, config) {
|
|
|
9900
10155
|
}
|
|
9901
10156
|
const formattedIndex = _internals16.formatSkillIndexWithContext(skillsForIndex, directory);
|
|
9902
10157
|
if (formattedIndex.length > 0) {
|
|
9903
|
-
const contextPath =
|
|
10158
|
+
const contextPath = path20.join(directory, ".swarm", "context.md");
|
|
9904
10159
|
let existingContent = "";
|
|
9905
10160
|
if (_internals16.existsSync(contextPath)) {
|
|
9906
10161
|
existingContent = _internals16.readFileSync(contextPath, "utf-8");
|
|
@@ -9922,7 +10177,7 @@ ${newSection}`;
|
|
|
9922
10177
|
updatedContent = existingContent + newSection;
|
|
9923
10178
|
}
|
|
9924
10179
|
}
|
|
9925
|
-
const swarmDir =
|
|
10180
|
+
const swarmDir = path20.dirname(contextPath);
|
|
9926
10181
|
if (!_internals16.existsSync(swarmDir)) {
|
|
9927
10182
|
_internals16.mkdirSync(swarmDir, { recursive: true });
|
|
9928
10183
|
}
|
|
@@ -10148,9 +10403,9 @@ function resolveInsightCandidatesPath(directory) {
|
|
|
10148
10403
|
}
|
|
10149
10404
|
async function readTaskTrajectory(directory, taskId) {
|
|
10150
10405
|
try {
|
|
10151
|
-
const rel =
|
|
10406
|
+
const rel = path21.join("evidence", sanitizeTaskId(taskId), "trajectory.jsonl");
|
|
10152
10407
|
const filePath = validateSwarmPath(directory, rel);
|
|
10153
|
-
if (!
|
|
10408
|
+
if (!existsSync10(filePath))
|
|
10154
10409
|
return [];
|
|
10155
10410
|
const content = await readFile5(filePath, "utf-8");
|
|
10156
10411
|
const out = [];
|
|
@@ -10206,7 +10461,7 @@ var WRITE_TOOLS = new Set([
|
|
|
10206
10461
|
"apply_patch",
|
|
10207
10462
|
"swarm_apply_patch"
|
|
10208
10463
|
]);
|
|
10209
|
-
function
|
|
10464
|
+
function isRecord2(value) {
|
|
10210
10465
|
return typeof value === "object" && value !== null;
|
|
10211
10466
|
}
|
|
10212
10467
|
function normalizePathField(value) {
|
|
@@ -10216,13 +10471,13 @@ function firstPathFromRecord(record) {
|
|
|
10216
10471
|
return normalizePathField(record.path) ?? normalizePathField(record.filePath) ?? normalizePathField(record.file);
|
|
10217
10472
|
}
|
|
10218
10473
|
function normalizeWriteTrigger(input, output) {
|
|
10219
|
-
if (!
|
|
10474
|
+
if (!isRecord2(input))
|
|
10220
10475
|
return null;
|
|
10221
10476
|
const toolName = typeof input.toolName === "string" ? input.toolName : typeof input.tool === "string" ? input.tool : null;
|
|
10222
10477
|
if (!toolName || !WRITE_TOOLS.has(toolName))
|
|
10223
10478
|
return null;
|
|
10224
|
-
const inputArgs =
|
|
10225
|
-
const outputArgs =
|
|
10479
|
+
const inputArgs = isRecord2(input.args) ? input.args : null;
|
|
10480
|
+
const outputArgs = isRecord2(output) && isRecord2(output.args) ? output.args : null;
|
|
10226
10481
|
const filePath = firstPathFromRecord(input) ?? (inputArgs ? firstPathFromRecord(inputArgs) : null) ?? (outputArgs ? firstPathFromRecord(outputArgs) : null);
|
|
10227
10482
|
if (!filePath)
|
|
10228
10483
|
return null;
|
|
@@ -10578,8 +10833,8 @@ RETRY: your last output was missing ${result.missing.join("; ")}; produce valid
|
|
|
10578
10833
|
}
|
|
10579
10834
|
async function appendCuratorSkippedEvent(directory, record) {
|
|
10580
10835
|
try {
|
|
10581
|
-
const filePath =
|
|
10582
|
-
await mkdir5(
|
|
10836
|
+
const filePath = path22.join(directory, ".swarm", "events.jsonl");
|
|
10837
|
+
await mkdir5(path22.dirname(filePath), { recursive: true });
|
|
10583
10838
|
await appendFile2(filePath, `${JSON.stringify({
|
|
10584
10839
|
timestamp: new Date().toISOString(),
|
|
10585
10840
|
event: "curator_skipped",
|
|
@@ -10619,7 +10874,7 @@ function readInsightJsonl(content) {
|
|
|
10619
10874
|
async function consumeInsightCandidates(directory, batchLimit = MESO_INSIGHT_BATCH_LIMIT) {
|
|
10620
10875
|
try {
|
|
10621
10876
|
const filePath = resolveInsightCandidatesPath(directory);
|
|
10622
|
-
if (!
|
|
10877
|
+
if (!existsSync11(filePath))
|
|
10623
10878
|
return [];
|
|
10624
10879
|
const consumed = [];
|
|
10625
10880
|
await transactFile(filePath, async (p) => readInsightJsonl(await readFile6(p, "utf-8").catch(() => "")), async (p, data) => {
|
|
@@ -11032,8 +11287,8 @@ var _internals17 = {
|
|
|
11032
11287
|
};
|
|
11033
11288
|
|
|
11034
11289
|
// src/services/session-reflection.ts
|
|
11035
|
-
import { promises as
|
|
11036
|
-
import * as
|
|
11290
|
+
import { promises as fs12 } from "fs";
|
|
11291
|
+
import * as path23 from "path";
|
|
11037
11292
|
|
|
11038
11293
|
// src/hooks/skill-improver-llm-factory.ts
|
|
11039
11294
|
function resolveSkillImproverAgentName(sessionId) {
|
|
@@ -11186,13 +11441,13 @@ async function gatherRetroLessonsAndTaxonomy(directory) {
|
|
|
11186
11441
|
const lessons = [];
|
|
11187
11442
|
const taxonomy = {};
|
|
11188
11443
|
try {
|
|
11189
|
-
const evidenceDir =
|
|
11190
|
-
const entries = await
|
|
11444
|
+
const evidenceDir = path23.join(directory, ".swarm", "evidence");
|
|
11445
|
+
const entries = await fs12.readdir(evidenceDir);
|
|
11191
11446
|
const retroDirs = entries.filter((e) => e.startsWith("retro-")).sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
|
|
11192
11447
|
for (const retroDir of retroDirs) {
|
|
11193
|
-
const evidencePath =
|
|
11448
|
+
const evidencePath = path23.join(evidenceDir, retroDir, "evidence.json");
|
|
11194
11449
|
try {
|
|
11195
|
-
const content = await
|
|
11450
|
+
const content = await fs12.readFile(evidencePath, "utf-8");
|
|
11196
11451
|
const parsed = JSON.parse(content);
|
|
11197
11452
|
const bundleEntries = parsed.entries ?? [parsed];
|
|
11198
11453
|
for (const entry of bundleEntries) {
|
|
@@ -11219,14 +11474,14 @@ async function gatherRetroLessonsAndTaxonomy(directory) {
|
|
|
11219
11474
|
async function gatherGateFailures(directory) {
|
|
11220
11475
|
const failures = new Map;
|
|
11221
11476
|
try {
|
|
11222
|
-
const evidenceDir =
|
|
11223
|
-
const entries = await
|
|
11477
|
+
const evidenceDir = path23.join(directory, ".swarm", "evidence");
|
|
11478
|
+
const entries = await fs12.readdir(evidenceDir);
|
|
11224
11479
|
for (const entry of entries) {
|
|
11225
11480
|
if (entry.startsWith("retro-"))
|
|
11226
11481
|
continue;
|
|
11227
|
-
const evidencePath =
|
|
11482
|
+
const evidencePath = path23.join(evidenceDir, entry, "evidence.json");
|
|
11228
11483
|
try {
|
|
11229
|
-
const content = await
|
|
11484
|
+
const content = await fs12.readFile(evidencePath, "utf-8");
|
|
11230
11485
|
const parsed = JSON.parse(content);
|
|
11231
11486
|
const bundleEntries = parsed.entries ?? [parsed];
|
|
11232
11487
|
for (const e of bundleEntries) {
|
|
@@ -11418,19 +11673,19 @@ async function writeSessionReflection(directory, result) {
|
|
|
11418
11673
|
lines.push(result.architectReport);
|
|
11419
11674
|
const content = lines.join(`
|
|
11420
11675
|
`);
|
|
11421
|
-
await
|
|
11676
|
+
await fs12.writeFile(reflectionPath, content, "utf-8");
|
|
11422
11677
|
return reflectionPath;
|
|
11423
11678
|
}
|
|
11424
11679
|
|
|
11425
11680
|
// src/services/skill-improver.ts
|
|
11426
|
-
import { existsSync as
|
|
11681
|
+
import { existsSync as existsSync13 } from "fs";
|
|
11427
11682
|
import { mkdir as mkdir7, readFile as readFile7, rename as rename3, writeFile as writeFile7 } from "fs/promises";
|
|
11428
|
-
import * as
|
|
11683
|
+
import * as path25 from "path";
|
|
11429
11684
|
init_logger();
|
|
11430
11685
|
|
|
11431
11686
|
// src/services/trajectory-cluster.ts
|
|
11432
11687
|
import { mkdir as mkdir6, writeFile as writeFile6 } from "fs/promises";
|
|
11433
|
-
import * as
|
|
11688
|
+
import * as path24 from "path";
|
|
11434
11689
|
init_logger();
|
|
11435
11690
|
var MACRO_TRAJECTORY_WINDOW = 200;
|
|
11436
11691
|
var MOTIF_MIN_TASKS = 2;
|
|
@@ -11562,11 +11817,11 @@ async function writeMotifProposals(directory, opts = {}) {
|
|
|
11562
11817
|
if (motifs.length === 0)
|
|
11563
11818
|
return result;
|
|
11564
11819
|
const max = opts.maxProposals ?? 10;
|
|
11565
|
-
const proposalsDir = validateSwarmPath(directory,
|
|
11820
|
+
const proposalsDir = validateSwarmPath(directory, path24.join("skills", "proposals"));
|
|
11566
11821
|
await mkdir6(proposalsDir, { recursive: true });
|
|
11567
11822
|
for (const motif of motifs.slice(0, max)) {
|
|
11568
11823
|
const slug = `motif-${slugify(motif.signature)}`;
|
|
11569
|
-
const filePath =
|
|
11824
|
+
const filePath = path24.join(proposalsDir, `${slug}.md`);
|
|
11570
11825
|
await writeFile6(filePath, buildMotifProposal(motif), "utf-8");
|
|
11571
11826
|
result.proposalsWritten.push(filePath);
|
|
11572
11827
|
}
|
|
@@ -11707,11 +11962,11 @@ async function writeSuccessMotifProposals(directory, opts = {}) {
|
|
|
11707
11962
|
if (motifs.length === 0)
|
|
11708
11963
|
return result;
|
|
11709
11964
|
const max = opts.maxProposals ?? 10;
|
|
11710
|
-
const proposalsDir = validateSwarmPath(directory,
|
|
11965
|
+
const proposalsDir = validateSwarmPath(directory, path24.join("skills", "proposals"));
|
|
11711
11966
|
await mkdir6(proposalsDir, { recursive: true });
|
|
11712
11967
|
for (const motif of motifs.slice(0, max)) {
|
|
11713
11968
|
const slug = workflowSlug(motif.signature);
|
|
11714
|
-
const filePath =
|
|
11969
|
+
const filePath = path24.join(proposalsDir, `${slug}.md`);
|
|
11715
11970
|
await writeFile6(filePath, buildWorkflowProposal(motif), "utf-8");
|
|
11716
11971
|
result.proposalsWritten.push(filePath);
|
|
11717
11972
|
}
|
|
@@ -11723,14 +11978,14 @@ async function writeSuccessMotifProposals(directory, opts = {}) {
|
|
|
11723
11978
|
}
|
|
11724
11979
|
|
|
11725
11980
|
// src/services/unactionable-hardening.ts
|
|
11726
|
-
import { existsSync as
|
|
11981
|
+
import { existsSync as existsSync12 } from "fs";
|
|
11727
11982
|
init_logger();
|
|
11728
11983
|
var HARDENING_BATCH_LIMIT = 5;
|
|
11729
11984
|
async function hardenUnactionableEntries(params) {
|
|
11730
11985
|
const result = { hardened: 0, retired: 0, remaining: 0 };
|
|
11731
11986
|
try {
|
|
11732
11987
|
const queuePath = resolveUnactionablePath(params.directory);
|
|
11733
|
-
if (!
|
|
11988
|
+
if (!existsSync12(queuePath))
|
|
11734
11989
|
return result;
|
|
11735
11990
|
const limit = params.batchLimit ?? HARDENING_BATCH_LIMIT;
|
|
11736
11991
|
const dedupThreshold = params.dedupThreshold ?? 0.6;
|
|
@@ -11834,7 +12089,7 @@ function timestampSlug(d) {
|
|
|
11834
12089
|
return d.toISOString().replace(/[:.]/g, "-");
|
|
11835
12090
|
}
|
|
11836
12091
|
async function atomicWrite(p, content) {
|
|
11837
|
-
await mkdir7(
|
|
12092
|
+
await mkdir7(path25.dirname(p), { recursive: true });
|
|
11838
12093
|
const tmp = `${p}.tmp-${process.pid}-${Date.now()}`;
|
|
11839
12094
|
await writeFile7(tmp, content, "utf-8");
|
|
11840
12095
|
await rename3(tmp, p);
|
|
@@ -11842,7 +12097,7 @@ async function atomicWrite(p, content) {
|
|
|
11842
12097
|
async function gatherInventory(directory) {
|
|
11843
12098
|
const swarm = await readKnowledge(resolveSwarmKnowledgePath(directory));
|
|
11844
12099
|
const hivePath = resolveHiveKnowledgePath();
|
|
11845
|
-
const hive =
|
|
12100
|
+
const hive = existsSync13(hivePath) ? await readKnowledge(hivePath) : [];
|
|
11846
12101
|
const archived = [...swarm, ...hive].filter((e) => e.status === "archived").length;
|
|
11847
12102
|
const skills = await listSkills(directory);
|
|
11848
12103
|
const knowledgeById = new Map([...swarm, ...hive].map((entry) => [entry.id, entry]));
|
|
@@ -12237,8 +12492,8 @@ async function runSkillImprover(req) {
|
|
|
12237
12492
|
}
|
|
12238
12493
|
throw err;
|
|
12239
12494
|
}
|
|
12240
|
-
const proposalDir =
|
|
12241
|
-
const proposalFile =
|
|
12495
|
+
const proposalDir = path25.join(req.directory, ".swarm", "skill-improver", "proposals");
|
|
12496
|
+
const proposalFile = path25.join(proposalDir, `${timestampSlug(now)}.md`);
|
|
12242
12497
|
const finalBody = source === "llm" ? buildLLMProposalFrame({
|
|
12243
12498
|
body,
|
|
12244
12499
|
targets,
|
|
@@ -12721,20 +12976,20 @@ function countSessionKnowledgeEntries(entries, sessionStart, fallbackCount) {
|
|
|
12721
12976
|
async function copyDirRecursiveWithFailures(src, dest) {
|
|
12722
12977
|
let count = 0;
|
|
12723
12978
|
const failures = [];
|
|
12724
|
-
const entries = await
|
|
12725
|
-
await
|
|
12979
|
+
const entries = await fs13.readdir(src);
|
|
12980
|
+
await fs13.mkdir(dest, { recursive: true });
|
|
12726
12981
|
for (const entry of entries) {
|
|
12727
|
-
const srcEntry =
|
|
12728
|
-
const destEntry =
|
|
12982
|
+
const srcEntry = path26.join(src, entry);
|
|
12983
|
+
const destEntry = path26.join(dest, entry);
|
|
12729
12984
|
try {
|
|
12730
|
-
const stat4 = await
|
|
12985
|
+
const stat4 = await fs13.stat(srcEntry);
|
|
12731
12986
|
if (stat4.isDirectory()) {
|
|
12732
12987
|
const subResult = await copyDirRecursiveWithFailures(srcEntry, destEntry);
|
|
12733
12988
|
count += subResult.copied;
|
|
12734
12989
|
failures.push(...subResult.failures);
|
|
12735
12990
|
} else {
|
|
12736
12991
|
try {
|
|
12737
|
-
await
|
|
12992
|
+
await fs13.copyFile(srcEntry, destEntry);
|
|
12738
12993
|
count++;
|
|
12739
12994
|
} catch (err) {
|
|
12740
12995
|
const errno = err?.code;
|
|
@@ -12909,20 +13164,20 @@ async function runFinalizeStage(ctx) {
|
|
|
12909
13164
|
ctx.warnings.push(`Session retrospective write threw: ${retroError instanceof Error ? retroError.message : String(retroError)}`);
|
|
12910
13165
|
}
|
|
12911
13166
|
}
|
|
12912
|
-
const lessonsFilePath =
|
|
13167
|
+
const lessonsFilePath = path26.join(ctx.swarmDir, "close-lessons.md");
|
|
12913
13168
|
try {
|
|
12914
|
-
const lessonsText = await
|
|
13169
|
+
const lessonsText = await fs13.readFile(lessonsFilePath, "utf-8");
|
|
12915
13170
|
ctx.explicitLessons = lessonsText.split(`
|
|
12916
13171
|
`).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
|
|
12917
13172
|
} catch {}
|
|
12918
13173
|
try {
|
|
12919
|
-
const evidenceDir =
|
|
12920
|
-
const evidenceEntries = await
|
|
13174
|
+
const evidenceDir = path26.join(ctx.swarmDir, "evidence");
|
|
13175
|
+
const evidenceEntries = await fs13.readdir(evidenceDir);
|
|
12921
13176
|
const retroDirs = evidenceEntries.filter((e) => e.startsWith("retro-")).sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
|
|
12922
13177
|
for (const retroDir of retroDirs) {
|
|
12923
|
-
const evidencePath =
|
|
13178
|
+
const evidencePath = path26.join(evidenceDir, retroDir, "evidence.json");
|
|
12924
13179
|
try {
|
|
12925
|
-
const content = await
|
|
13180
|
+
const content = await fs13.readFile(evidencePath, "utf-8");
|
|
12926
13181
|
const parsed = JSON.parse(content);
|
|
12927
13182
|
const entries = parsed.entries ?? [parsed];
|
|
12928
13183
|
for (const entry of entries) {
|
|
@@ -12966,7 +13221,7 @@ async function runFinalizeStage(ctx) {
|
|
|
12966
13221
|
console.warn("[close-command] curateAndStoreSwarm error:", error2);
|
|
12967
13222
|
}
|
|
12968
13223
|
if (ctx.curationSucceeded && ctx.allLessons.length > 0) {
|
|
12969
|
-
await
|
|
13224
|
+
await fs13.unlink(lessonsFilePath).catch(() => {});
|
|
12970
13225
|
}
|
|
12971
13226
|
if (ctx.curationSucceeded) {
|
|
12972
13227
|
if (ctx.config.hive_enabled === false) {} else {
|
|
@@ -13072,7 +13327,7 @@ async function runFinalizeStage(ctx) {
|
|
|
13072
13327
|
}
|
|
13073
13328
|
}
|
|
13074
13329
|
try {
|
|
13075
|
-
const { CuratorConfigSchema: CCS } = await import("./schema-
|
|
13330
|
+
const { CuratorConfigSchema: CCS } = await import("./schema-nz638xc3.js");
|
|
13076
13331
|
const { config: pmLoadedConfig } = _internals20.loadPluginConfigWithMeta(ctx.directory);
|
|
13077
13332
|
const curatorCfg = CCS.parse(pmLoadedConfig.curator ?? {});
|
|
13078
13333
|
if (curatorCfg.enabled && curatorCfg.postmortem_enabled) {
|
|
@@ -13102,7 +13357,7 @@ async function copySqliteSafe(srcPath, destPath) {
|
|
|
13102
13357
|
let checkpointVerified = false;
|
|
13103
13358
|
try {
|
|
13104
13359
|
const result = spawnSync5("sqlite3", [srcPath, "PRAGMA wal_checkpoint(TRUNCATE);"], {
|
|
13105
|
-
cwd:
|
|
13360
|
+
cwd: path26.dirname(srcPath),
|
|
13106
13361
|
encoding: "utf-8",
|
|
13107
13362
|
stdio: ["ignore", "pipe", "pipe"],
|
|
13108
13363
|
timeout: 1e4,
|
|
@@ -13113,7 +13368,7 @@ async function copySqliteSafe(srcPath, destPath) {
|
|
|
13113
13368
|
const code = result.error.code;
|
|
13114
13369
|
if (code === "ENOENT") {
|
|
13115
13370
|
try {
|
|
13116
|
-
await
|
|
13371
|
+
await fs13.copyFile(srcPath, destPath);
|
|
13117
13372
|
return {
|
|
13118
13373
|
success: true,
|
|
13119
13374
|
reason: "copied without WAL checkpoint (sqlite3 CLI unavailable)"
|
|
@@ -13152,7 +13407,7 @@ async function copySqliteSafe(srcPath, destPath) {
|
|
|
13152
13407
|
};
|
|
13153
13408
|
}
|
|
13154
13409
|
try {
|
|
13155
|
-
await
|
|
13410
|
+
await fs13.copyFile(srcPath, destPath);
|
|
13156
13411
|
if (checkpointVerified) {
|
|
13157
13412
|
return { success: true };
|
|
13158
13413
|
}
|
|
@@ -13170,9 +13425,9 @@ async function copySqliteSafe(srcPath, destPath) {
|
|
|
13170
13425
|
async function runArchiveStage(ctx) {
|
|
13171
13426
|
ctx.timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
13172
13427
|
ctx.archiveSuffix = Math.random().toString(36).slice(2, 8);
|
|
13173
|
-
ctx.archiveDir =
|
|
13428
|
+
ctx.archiveDir = path26.join(ctx.swarmDir, "archive", `swarm-${ctx.timestamp}-${ctx.archiveSuffix}`);
|
|
13174
13429
|
try {
|
|
13175
|
-
await
|
|
13430
|
+
await fs13.mkdir(ctx.archiveDir, { recursive: true });
|
|
13176
13431
|
const WAL_SIDECAR_FILES = new Set(["swarm.db-shm", "swarm.db-wal"]);
|
|
13177
13432
|
const linkedKnowledgeShared = isLinked(ctx.directory);
|
|
13178
13433
|
if (linkedKnowledgeShared) {
|
|
@@ -13185,8 +13440,8 @@ async function runArchiveStage(ctx) {
|
|
|
13185
13440
|
if (linkedKnowledgeShared && KNOWLEDGE_FAMILY_ARTIFACTS.has(artifact)) {
|
|
13186
13441
|
continue;
|
|
13187
13442
|
}
|
|
13188
|
-
const srcPath =
|
|
13189
|
-
const destPath =
|
|
13443
|
+
const srcPath = path26.join(ctx.swarmDir, artifact);
|
|
13444
|
+
const destPath = path26.join(ctx.archiveDir, artifact);
|
|
13190
13445
|
if (artifact === "swarm.db") {
|
|
13191
13446
|
const result = await copySqliteSafe(srcPath, destPath);
|
|
13192
13447
|
if (result.skipped) {} else if (result.success) {
|
|
@@ -13202,7 +13457,7 @@ async function runArchiveStage(ctx) {
|
|
|
13202
13457
|
}
|
|
13203
13458
|
} else {
|
|
13204
13459
|
try {
|
|
13205
|
-
await
|
|
13460
|
+
await fs13.copyFile(srcPath, destPath);
|
|
13206
13461
|
ctx.archivedFileCount++;
|
|
13207
13462
|
if (ACTIVE_STATE_TO_CLEAN.includes(artifact)) {
|
|
13208
13463
|
ctx.archivedActiveStateFiles.add(artifact);
|
|
@@ -13218,8 +13473,8 @@ async function runArchiveStage(ctx) {
|
|
|
13218
13473
|
}
|
|
13219
13474
|
}
|
|
13220
13475
|
for (const dirName of ACTIVE_STATE_DIRS_TO_CLEAN) {
|
|
13221
|
-
const srcDir =
|
|
13222
|
-
const destDir =
|
|
13476
|
+
const srcDir = path26.join(ctx.swarmDir, dirName);
|
|
13477
|
+
const destDir = path26.join(ctx.archiveDir, dirName);
|
|
13223
13478
|
try {
|
|
13224
13479
|
const result = await copyDirRecursiveWithFailures(srcDir, destDir);
|
|
13225
13480
|
ctx.archivedFileCount += result.copied;
|
|
@@ -13292,9 +13547,9 @@ async function runCleanStage(ctx) {
|
|
|
13292
13547
|
ctx.warnings.push(reason ? `Preserved ${artifact} because it was not successfully archived: ${reason}.` : `Preserved ${artifact} because it was not successfully archived.`);
|
|
13293
13548
|
continue;
|
|
13294
13549
|
}
|
|
13295
|
-
const filePath =
|
|
13550
|
+
const filePath = path26.join(ctx.swarmDir, artifact);
|
|
13296
13551
|
try {
|
|
13297
|
-
await
|
|
13552
|
+
await fs13.unlink(filePath);
|
|
13298
13553
|
cleanedFiles.push(artifact);
|
|
13299
13554
|
} catch (err) {
|
|
13300
13555
|
const errno = err?.code;
|
|
@@ -13311,18 +13566,18 @@ async function runCleanStage(ctx) {
|
|
|
13311
13566
|
if (!ctx.archivedActiveStateDirs.has(dirName)) {
|
|
13312
13567
|
continue;
|
|
13313
13568
|
}
|
|
13314
|
-
const dirPath =
|
|
13569
|
+
const dirPath = path26.join(ctx.swarmDir, dirName);
|
|
13315
13570
|
try {
|
|
13316
|
-
await
|
|
13571
|
+
await fs13.rm(dirPath, { recursive: true, force: true });
|
|
13317
13572
|
cleanedFiles.push(`${dirName}/`);
|
|
13318
13573
|
} catch {}
|
|
13319
13574
|
}
|
|
13320
13575
|
try {
|
|
13321
|
-
const swarmFiles = await
|
|
13576
|
+
const swarmFiles = await fs13.readdir(ctx.swarmDir);
|
|
13322
13577
|
const configBackups = swarmFiles.filter((f) => f.startsWith("config-backup-") && f.endsWith(".json"));
|
|
13323
13578
|
for (const backup of configBackups) {
|
|
13324
13579
|
try {
|
|
13325
|
-
await
|
|
13580
|
+
await fs13.unlink(path26.join(ctx.swarmDir, backup));
|
|
13326
13581
|
configBackupsRemoved++;
|
|
13327
13582
|
} catch (err) {
|
|
13328
13583
|
const errno = err?.code;
|
|
@@ -13335,7 +13590,7 @@ async function runCleanStage(ctx) {
|
|
|
13335
13590
|
const ledgerSiblings = swarmFiles.filter((f) => (f.startsWith("plan-ledger.archived-") || f.startsWith("plan-ledger.backup-")) && f.endsWith(".jsonl"));
|
|
13336
13591
|
for (const sibling of ledgerSiblings) {
|
|
13337
13592
|
try {
|
|
13338
|
-
await
|
|
13593
|
+
await fs13.unlink(path26.join(ctx.swarmDir, sibling));
|
|
13339
13594
|
} catch (err) {
|
|
13340
13595
|
const errno = err?.code;
|
|
13341
13596
|
if (errno === "ENOENT") {} else {
|
|
@@ -13353,16 +13608,16 @@ async function runCleanStage(ctx) {
|
|
|
13353
13608
|
}
|
|
13354
13609
|
let swarmPlanFilesRemoved = 0;
|
|
13355
13610
|
const candidates = [
|
|
13356
|
-
|
|
13357
|
-
|
|
13358
|
-
|
|
13359
|
-
|
|
13360
|
-
|
|
13361
|
-
|
|
13611
|
+
path26.join(ctx.directory, ".swarm", "plan-export", "SWARM_PLAN.json"),
|
|
13612
|
+
path26.join(ctx.directory, ".swarm", "plan-export", "SWARM_PLAN.md"),
|
|
13613
|
+
path26.join(ctx.directory, ".swarm", "SWARM_PLAN.json"),
|
|
13614
|
+
path26.join(ctx.directory, ".swarm", "SWARM_PLAN.md"),
|
|
13615
|
+
path26.join(ctx.directory, "SWARM_PLAN.json"),
|
|
13616
|
+
path26.join(ctx.directory, "SWARM_PLAN.md")
|
|
13362
13617
|
];
|
|
13363
13618
|
for (const candidate of candidates) {
|
|
13364
13619
|
try {
|
|
13365
|
-
await
|
|
13620
|
+
await fs13.unlink(candidate);
|
|
13366
13621
|
swarmPlanFilesRemoved++;
|
|
13367
13622
|
} catch (err) {
|
|
13368
13623
|
if (err?.code !== "ENOENT") {
|
|
@@ -13372,11 +13627,11 @@ async function runCleanStage(ctx) {
|
|
|
13372
13627
|
}
|
|
13373
13628
|
let tmpFilesRemoved = 0;
|
|
13374
13629
|
try {
|
|
13375
|
-
const swarmFiles = await
|
|
13630
|
+
const swarmFiles = await fs13.readdir(ctx.swarmDir);
|
|
13376
13631
|
const tmpFiles = swarmFiles.filter((f) => f.startsWith(".tmp."));
|
|
13377
13632
|
for (const tmp of tmpFiles) {
|
|
13378
13633
|
try {
|
|
13379
|
-
await
|
|
13634
|
+
await fs13.unlink(path26.join(ctx.swarmDir, tmp));
|
|
13380
13635
|
tmpFilesRemoved++;
|
|
13381
13636
|
} catch (err) {
|
|
13382
13637
|
const errno = err?.code;
|
|
@@ -13397,7 +13652,7 @@ async function runCleanStage(ctx) {
|
|
|
13397
13652
|
cleanedFiles.push(`${tmpFilesRemoved} .tmp.* file(s)`);
|
|
13398
13653
|
}
|
|
13399
13654
|
clearAllScopes(ctx.directory);
|
|
13400
|
-
const contextPath =
|
|
13655
|
+
const contextPath = path26.join(ctx.swarmDir, "context.md");
|
|
13401
13656
|
const contextContent = [
|
|
13402
13657
|
"# Context",
|
|
13403
13658
|
"",
|
|
@@ -13409,9 +13664,9 @@ async function runCleanStage(ctx) {
|
|
|
13409
13664
|
""
|
|
13410
13665
|
].join(`
|
|
13411
13666
|
`);
|
|
13412
|
-
const contextTempPath =
|
|
13667
|
+
const contextTempPath = path26.join(path26.dirname(contextPath), `${path26.basename(contextPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
|
|
13413
13668
|
try {
|
|
13414
|
-
await
|
|
13669
|
+
await fs13.writeFile(contextTempPath, contextContent, "utf-8");
|
|
13415
13670
|
fsSync2.renameSync(contextTempPath, contextPath);
|
|
13416
13671
|
} catch (error2) {
|
|
13417
13672
|
try {
|
|
@@ -13473,7 +13728,7 @@ async function runAlignStage(ctx) {
|
|
|
13473
13728
|
return { gitAlignResult, prunedBranches };
|
|
13474
13729
|
}
|
|
13475
13730
|
async function handleCloseCommand(directory, args, options = {}) {
|
|
13476
|
-
const swarmDir =
|
|
13731
|
+
const swarmDir = path26.join(directory, ".swarm");
|
|
13477
13732
|
try {
|
|
13478
13733
|
const stat4 = fsSync2.lstatSync(swarmDir);
|
|
13479
13734
|
if (stat4.isSymbolicLink()) {
|
|
@@ -13487,18 +13742,18 @@ async function handleCloseCommand(directory, args, options = {}) {
|
|
|
13487
13742
|
const planPath = validateSwarmPath(directory, "plan.json");
|
|
13488
13743
|
let planExists = false;
|
|
13489
13744
|
let planData = {
|
|
13490
|
-
title:
|
|
13745
|
+
title: path26.basename(directory) || "Ad-hoc session",
|
|
13491
13746
|
phases: []
|
|
13492
13747
|
};
|
|
13493
13748
|
try {
|
|
13494
|
-
const content = await
|
|
13749
|
+
const content = await fs13.readFile(planPath, "utf-8");
|
|
13495
13750
|
planData = JSON.parse(content);
|
|
13496
13751
|
planExists = true;
|
|
13497
13752
|
} catch (error2) {
|
|
13498
13753
|
if (error2?.code !== "ENOENT") {
|
|
13499
13754
|
return `\u274C Failed to read plan.json: ${error2 instanceof Error ? error2.message : String(error2)}`;
|
|
13500
13755
|
}
|
|
13501
|
-
const swarmDirExists = await
|
|
13756
|
+
const swarmDirExists = await fs13.access(swarmDir).then(() => true).catch(() => false);
|
|
13502
13757
|
if (!swarmDirExists) {
|
|
13503
13758
|
return `\u274C No .swarm/ directory found in ${directory}. Run /swarm close from the project root, or run /swarm plan first.`;
|
|
13504
13759
|
}
|
|
@@ -13512,15 +13767,15 @@ async function handleCloseCommand(directory, args, options = {}) {
|
|
|
13512
13767
|
}
|
|
13513
13768
|
try {
|
|
13514
13769
|
if (!planExists) {
|
|
13515
|
-
const archiveDir =
|
|
13770
|
+
const archiveDir = path26.join(swarmDir, "archive");
|
|
13516
13771
|
try {
|
|
13517
|
-
const archiveEntries = await
|
|
13772
|
+
const archiveEntries = await fs13.readdir(archiveDir);
|
|
13518
13773
|
const hasArchiveBundle = archiveEntries.some((entry) => entry.startsWith("swarm-"));
|
|
13519
13774
|
if (hasArchiveBundle) {
|
|
13520
13775
|
const hasActiveState = [
|
|
13521
13776
|
...ACTIVE_STATE_TO_CLEAN,
|
|
13522
13777
|
...ACTIVE_STATE_DIRS_TO_CLEAN
|
|
13523
|
-
].some((entry) => fsSync2.existsSync(
|
|
13778
|
+
].some((entry) => fsSync2.existsSync(path26.join(swarmDir, entry)));
|
|
13524
13779
|
if (!hasActiveState) {
|
|
13525
13780
|
return `\u2705 Already finalized \u2014 nothing to do.
|
|
13526
13781
|
|
|
@@ -13643,9 +13898,9 @@ This project was already finalized in a previous /swarm close run. The plan has
|
|
|
13643
13898
|
...ctx.warnings.length > 0 ? ["## Warnings", ...ctx.warnings.map((w) => `- ${w}`), ""] : []
|
|
13644
13899
|
].join(`
|
|
13645
13900
|
`);
|
|
13646
|
-
const closeSummaryTempPath =
|
|
13901
|
+
const closeSummaryTempPath = path26.join(path26.dirname(closeSummaryPath), `${path26.basename(closeSummaryPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
|
|
13647
13902
|
try {
|
|
13648
|
-
await
|
|
13903
|
+
await fs13.writeFile(closeSummaryTempPath, summaryContent, "utf-8");
|
|
13649
13904
|
fsSync2.renameSync(closeSummaryTempPath, closeSummaryPath);
|
|
13650
13905
|
} catch (error2) {
|
|
13651
13906
|
try {
|
|
@@ -13985,15 +14240,15 @@ function buildStatusMessage(session, plan) {
|
|
|
13985
14240
|
}
|
|
13986
14241
|
|
|
13987
14242
|
// src/commands/config.ts
|
|
13988
|
-
import * as
|
|
13989
|
-
import * as
|
|
14243
|
+
import * as os7 from "os";
|
|
14244
|
+
import * as path27 from "path";
|
|
13990
14245
|
function getUserConfigDir2() {
|
|
13991
|
-
return process.env.XDG_CONFIG_HOME ||
|
|
14246
|
+
return process.env.XDG_CONFIG_HOME || path27.join(os7.homedir(), ".config");
|
|
13992
14247
|
}
|
|
13993
14248
|
async function handleConfigCommand(directory, _args) {
|
|
13994
14249
|
const config = loadPluginConfig(directory);
|
|
13995
|
-
const userConfigPath =
|
|
13996
|
-
const projectConfigPath =
|
|
14250
|
+
const userConfigPath = path27.join(getUserConfigDir2(), "opencode", "opencode-swarm.json");
|
|
14251
|
+
const projectConfigPath = path27.join(directory, ".opencode", "opencode-swarm.json");
|
|
13997
14252
|
const lines = [
|
|
13998
14253
|
"## Swarm Configuration",
|
|
13999
14254
|
"",
|
|
@@ -14011,9 +14266,9 @@ async function handleConfigCommand(directory, _args) {
|
|
|
14011
14266
|
}
|
|
14012
14267
|
|
|
14013
14268
|
// src/services/skill-consolidation.ts
|
|
14014
|
-
import { existsSync as
|
|
14269
|
+
import { existsSync as existsSync15 } from "fs";
|
|
14015
14270
|
import { mkdir as mkdir8, readFile as readFile8, rename as rename4, writeFile as writeFile8 } from "fs/promises";
|
|
14016
|
-
import * as
|
|
14271
|
+
import * as path28 from "path";
|
|
14017
14272
|
|
|
14018
14273
|
// src/utils/timeout.ts
|
|
14019
14274
|
async function withTimeout(promise, ms, timeoutError) {
|
|
@@ -14038,11 +14293,11 @@ var DEFAULT_CONSOLIDATION_MAX_CALLS_PER_RUN = 1;
|
|
|
14038
14293
|
var CONSOLIDATION_RUN_TIMEOUT_MS = 5 * 60 * 1000;
|
|
14039
14294
|
var runningByDirectory = new Map;
|
|
14040
14295
|
function consolidationStatePath(directory) {
|
|
14041
|
-
return
|
|
14296
|
+
return path28.join(directory, ".swarm", "skill-improver", "consolidation-state.json");
|
|
14042
14297
|
}
|
|
14043
14298
|
async function readState2(directory) {
|
|
14044
14299
|
const filePath = consolidationStatePath(directory);
|
|
14045
|
-
if (!
|
|
14300
|
+
if (!existsSync15(filePath))
|
|
14046
14301
|
return {};
|
|
14047
14302
|
try {
|
|
14048
14303
|
const parsed = JSON.parse(await readFile8(filePath, "utf-8"));
|
|
@@ -14054,7 +14309,7 @@ async function readState2(directory) {
|
|
|
14054
14309
|
}
|
|
14055
14310
|
}
|
|
14056
14311
|
async function atomicWrite2(filePath, content) {
|
|
14057
|
-
await mkdir8(
|
|
14312
|
+
await mkdir8(path28.dirname(filePath), { recursive: true });
|
|
14058
14313
|
const tmp = `${filePath}.tmp-${process.pid}-${Date.now()}`;
|
|
14059
14314
|
await writeFile8(tmp, content, "utf-8");
|
|
14060
14315
|
await rename4(tmp, filePath);
|
|
@@ -14134,7 +14389,7 @@ async function runSkillConsolidationInner(req) {
|
|
|
14134
14389
|
};
|
|
14135
14390
|
}
|
|
14136
14391
|
async function runSkillConsolidation(req) {
|
|
14137
|
-
const key =
|
|
14392
|
+
const key = path28.resolve(req.directory);
|
|
14138
14393
|
const existing = runningByDirectory.get(key);
|
|
14139
14394
|
if (existing) {
|
|
14140
14395
|
return {
|
|
@@ -14216,6 +14471,55 @@ async function handleConsolidateCommand(directory, args, options = {}) {
|
|
|
14216
14471
|
}
|
|
14217
14472
|
}
|
|
14218
14473
|
|
|
14474
|
+
// src/commands/costs.ts
|
|
14475
|
+
async function handleCostsCommand(directory, args) {
|
|
14476
|
+
const summary = summarizeTelemetryCosts(directory);
|
|
14477
|
+
const json = args.includes("--json");
|
|
14478
|
+
if (json) {
|
|
14479
|
+
return [
|
|
14480
|
+
"[COSTS_JSON]",
|
|
14481
|
+
JSON.stringify(summary, null, 2),
|
|
14482
|
+
"[/COSTS_JSON]"
|
|
14483
|
+
].join(`
|
|
14484
|
+
`);
|
|
14485
|
+
}
|
|
14486
|
+
return renderCostSummary(summary);
|
|
14487
|
+
}
|
|
14488
|
+
function renderCostSummary(summary) {
|
|
14489
|
+
const lines = [
|
|
14490
|
+
"## Swarm Costs",
|
|
14491
|
+
"",
|
|
14492
|
+
`Total tracked cost: ${formatUsd(summary.total_cost_usd)}`,
|
|
14493
|
+
`Delegations: ${summary.delegations}`,
|
|
14494
|
+
`Tokens: input ${summary.total_input_tokens.toLocaleString()}, output ${summary.total_output_tokens.toLocaleString()}, reasoning ${summary.total_reasoning_tokens.toLocaleString()}, cache ${summary.total_cache_tokens.toLocaleString()}`,
|
|
14495
|
+
`Cost source: reported ${formatUsd(summary.total_reported_usd)}, estimated ${formatUsd(summary.total_estimated_usd)}, unavailable ${summary.unavailable_delegations}`,
|
|
14496
|
+
"",
|
|
14497
|
+
"### By Agent"
|
|
14498
|
+
];
|
|
14499
|
+
appendCostRows(lines, "Agent", summary.by_agent, "No delegation cost telemetry recorded.");
|
|
14500
|
+
lines.push("", "### By Task");
|
|
14501
|
+
appendCostRows(lines, "Task", summary.by_task, "No task cost telemetry recorded.");
|
|
14502
|
+
lines.push("", "### By Gate");
|
|
14503
|
+
appendCostRows(lines, "Gate", summary.by_gate, "No gate cost telemetry recorded.");
|
|
14504
|
+
lines.push("", "### By Retry Loop");
|
|
14505
|
+
appendCostRows(lines, "Retry", summary.by_retry, "No retry-loop cost telemetry recorded.");
|
|
14506
|
+
return lines.join(`
|
|
14507
|
+
`);
|
|
14508
|
+
}
|
|
14509
|
+
function appendCostRows(lines, label, rows, emptyMessage) {
|
|
14510
|
+
if (rows.length === 0) {
|
|
14511
|
+
lines.push(emptyMessage);
|
|
14512
|
+
return;
|
|
14513
|
+
}
|
|
14514
|
+
lines.push(`| ${label} | Delegations | Cost | Input | Output | Reasoning | Cache | Unavailable |`, "|------|-------------|------|-------|--------|-----------|-------|-------------|");
|
|
14515
|
+
for (const row of rows) {
|
|
14516
|
+
lines.push(`| ${row.name} | ${row.delegations} | ${formatUsd(row.cost_usd)} | ${row.input_tokens.toLocaleString()} | ${row.output_tokens.toLocaleString()} | ${row.reasoning_tokens.toLocaleString()} | ${row.cache_tokens.toLocaleString()} | ${row.unavailable_delegations} |`);
|
|
14517
|
+
}
|
|
14518
|
+
}
|
|
14519
|
+
function formatUsd(value) {
|
|
14520
|
+
return `$${value.toFixed(6)}`;
|
|
14521
|
+
}
|
|
14522
|
+
|
|
14219
14523
|
// src/commands/council.ts
|
|
14220
14524
|
var MAX_QUESTION_LEN = 2000;
|
|
14221
14525
|
function sanitizeQuestion(raw) {
|
|
@@ -14286,8 +14590,8 @@ async function handleCouncilCommand(_directory, args) {
|
|
|
14286
14590
|
|
|
14287
14591
|
// src/commands/coupling.ts
|
|
14288
14592
|
import { randomBytes } from "crypto";
|
|
14289
|
-
import * as
|
|
14290
|
-
import * as
|
|
14593
|
+
import * as fs14 from "fs";
|
|
14594
|
+
import * as path30 from "path";
|
|
14291
14595
|
|
|
14292
14596
|
// src/turbo/epic/cochange-source.ts
|
|
14293
14597
|
import * as child_process3 from "child_process";
|
|
@@ -14297,7 +14601,7 @@ import { promisify as promisify2 } from "util";
|
|
|
14297
14601
|
import * as child_process2 from "child_process";
|
|
14298
14602
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
14299
14603
|
import { readdir as readdir4, readFile as readFile9, stat as stat4 } from "fs/promises";
|
|
14300
|
-
import * as
|
|
14604
|
+
import * as path29 from "path";
|
|
14301
14605
|
import { promisify } from "util";
|
|
14302
14606
|
function getExecFileAsync() {
|
|
14303
14607
|
return promisify(child_process2.execFile);
|
|
@@ -14401,7 +14705,7 @@ async function scanSourceFiles(dir) {
|
|
|
14401
14705
|
try {
|
|
14402
14706
|
const entries = await readdir4(dir, { withFileTypes: true });
|
|
14403
14707
|
for (const entry of entries) {
|
|
14404
|
-
const fullPath =
|
|
14708
|
+
const fullPath = path29.join(dir, entry.name);
|
|
14405
14709
|
if (entry.isDirectory()) {
|
|
14406
14710
|
if (skipDirs.has(entry.name)) {
|
|
14407
14711
|
continue;
|
|
@@ -14409,7 +14713,7 @@ async function scanSourceFiles(dir) {
|
|
|
14409
14713
|
const subFiles = await scanSourceFiles(fullPath);
|
|
14410
14714
|
results.push(...subFiles);
|
|
14411
14715
|
} else if (entry.isFile()) {
|
|
14412
|
-
const ext =
|
|
14716
|
+
const ext = path29.extname(entry.name);
|
|
14413
14717
|
if ([".ts", ".tsx", ".js", ".jsx", ".mjs"].includes(ext)) {
|
|
14414
14718
|
results.push(fullPath);
|
|
14415
14719
|
}
|
|
@@ -14431,8 +14735,8 @@ async function getStaticEdges(directory) {
|
|
|
14431
14735
|
continue;
|
|
14432
14736
|
}
|
|
14433
14737
|
try {
|
|
14434
|
-
const sourceDir =
|
|
14435
|
-
const resolvedPath =
|
|
14738
|
+
const sourceDir = path29.dirname(sourceFile);
|
|
14739
|
+
const resolvedPath = path29.resolve(sourceDir, importPath);
|
|
14436
14740
|
const extensions = [
|
|
14437
14741
|
"",
|
|
14438
14742
|
".ts",
|
|
@@ -14457,8 +14761,8 @@ async function getStaticEdges(directory) {
|
|
|
14457
14761
|
if (!targetFile) {
|
|
14458
14762
|
continue;
|
|
14459
14763
|
}
|
|
14460
|
-
const relSource =
|
|
14461
|
-
const relTarget =
|
|
14764
|
+
const relSource = path29.relative(directory, sourceFile).replace(/\\/g, "/");
|
|
14765
|
+
const relTarget = path29.relative(directory, targetFile).replace(/\\/g, "/");
|
|
14462
14766
|
const [key] = relSource < relTarget ? [`${relSource}::${relTarget}`, relSource, relTarget] : [`${relTarget}::${relSource}`, relTarget, relSource];
|
|
14463
14767
|
edges.add(key);
|
|
14464
14768
|
} catch {}
|
|
@@ -14470,7 +14774,7 @@ async function getStaticEdges(directory) {
|
|
|
14470
14774
|
function isTestImplementationPair(fileA, fileB) {
|
|
14471
14775
|
const testPatterns = [".test.ts", ".test.js", ".spec.ts", ".spec.js"];
|
|
14472
14776
|
const getBaseName = (filePath) => {
|
|
14473
|
-
const base =
|
|
14777
|
+
const base = path29.basename(filePath);
|
|
14474
14778
|
for (const pattern of testPatterns) {
|
|
14475
14779
|
if (base.endsWith(pattern)) {
|
|
14476
14780
|
return base.slice(0, -pattern.length);
|
|
@@ -14480,16 +14784,16 @@ function isTestImplementationPair(fileA, fileB) {
|
|
|
14480
14784
|
};
|
|
14481
14785
|
const baseA = getBaseName(fileA);
|
|
14482
14786
|
const baseB = getBaseName(fileB);
|
|
14483
|
-
return baseA === baseB && baseA !==
|
|
14787
|
+
return baseA === baseB && baseA !== path29.basename(fileA) && baseA !== path29.basename(fileB);
|
|
14484
14788
|
}
|
|
14485
14789
|
function hasSharedPrefix(fileA, fileB) {
|
|
14486
|
-
const dirA =
|
|
14487
|
-
const dirB =
|
|
14790
|
+
const dirA = path29.dirname(fileA);
|
|
14791
|
+
const dirB = path29.dirname(fileB);
|
|
14488
14792
|
if (dirA !== dirB) {
|
|
14489
14793
|
return false;
|
|
14490
14794
|
}
|
|
14491
|
-
const baseA =
|
|
14492
|
-
const baseB =
|
|
14795
|
+
const baseA = path29.basename(fileA).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
|
|
14796
|
+
const baseB = path29.basename(fileB).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
|
|
14493
14797
|
if (baseA.startsWith(baseB) || baseB.startsWith(baseA)) {
|
|
14494
14798
|
return true;
|
|
14495
14799
|
}
|
|
@@ -14544,8 +14848,8 @@ function darkMatterToKnowledgeEntries(pairs, projectName) {
|
|
|
14544
14848
|
const entries = [];
|
|
14545
14849
|
const now = new Date().toISOString();
|
|
14546
14850
|
for (const pair of pairs.slice(0, 10)) {
|
|
14547
|
-
const baseA =
|
|
14548
|
-
const baseB =
|
|
14851
|
+
const baseA = path29.basename(pair.fileA);
|
|
14852
|
+
const baseB = path29.basename(pair.fileB);
|
|
14549
14853
|
let lesson = `Files ${pair.fileA} and ${pair.fileB} co-change with NPMI=${pair.npmi.toFixed(3)} but have no import relationship. This hidden coupling suggests a shared architectural concern \u2014 changes to one likely require changes to the other.`;
|
|
14550
14854
|
if (lesson.length > 280) {
|
|
14551
14855
|
lesson = `Files ${baseA} and ${baseB} co-change with NPMI=${pair.npmi.toFixed(3)} but have no import relationship. This hidden coupling suggests a shared architectural concern \u2014 changes to one likely require changes to the other.`;
|
|
@@ -14971,17 +15275,17 @@ function parseArgs3(args) {
|
|
|
14971
15275
|
return parsed;
|
|
14972
15276
|
}
|
|
14973
15277
|
function persistReportJson(directory, report) {
|
|
14974
|
-
const epicDir =
|
|
14975
|
-
|
|
14976
|
-
const filePath =
|
|
15278
|
+
const epicDir = path30.join(directory, ".swarm", "epic");
|
|
15279
|
+
fs14.mkdirSync(epicDir, { recursive: true });
|
|
15280
|
+
const filePath = path30.join(epicDir, "coupling-report.json");
|
|
14977
15281
|
const tmpPath = `${filePath}.tmp.${randomBytes(8).toString("hex")}`;
|
|
14978
|
-
|
|
15282
|
+
fs14.writeFileSync(tmpPath, `${JSON.stringify(report, null, 2)}
|
|
14979
15283
|
`, "utf-8");
|
|
14980
15284
|
try {
|
|
14981
|
-
|
|
15285
|
+
fs14.renameSync(tmpPath, filePath);
|
|
14982
15286
|
} catch (err) {
|
|
14983
15287
|
try {
|
|
14984
|
-
|
|
15288
|
+
fs14.unlinkSync(tmpPath);
|
|
14985
15289
|
} catch {}
|
|
14986
15290
|
throw err;
|
|
14987
15291
|
}
|
|
@@ -15032,7 +15336,7 @@ Usage: /swarm coupling [--phase <n>] [--threshold <-1..1>] [--min-co-changes <n>
|
|
|
15032
15336
|
persistStatus = {
|
|
15033
15337
|
requested: true,
|
|
15034
15338
|
written: true,
|
|
15035
|
-
path:
|
|
15339
|
+
path: path30.relative(directory, writtenAt)
|
|
15036
15340
|
};
|
|
15037
15341
|
} catch (err) {
|
|
15038
15342
|
persistStatus = {
|
|
@@ -15091,7 +15395,7 @@ function formatCurationSummary(summary) {
|
|
|
15091
15395
|
}
|
|
15092
15396
|
|
|
15093
15397
|
// src/commands/dark-matter.ts
|
|
15094
|
-
import
|
|
15398
|
+
import path31 from "path";
|
|
15095
15399
|
async function handleDarkMatterCommand(directory, args) {
|
|
15096
15400
|
const options = {};
|
|
15097
15401
|
for (let i = 0;i < args.length; i++) {
|
|
@@ -15123,7 +15427,7 @@ Ensure this is a git repository with commit history.`;
|
|
|
15123
15427
|
const output = formatDarkMatterOutput(pairs);
|
|
15124
15428
|
if (pairs.length > 0) {
|
|
15125
15429
|
try {
|
|
15126
|
-
const projectName =
|
|
15430
|
+
const projectName = path31.basename(path31.resolve(directory));
|
|
15127
15431
|
const entries = darkMatterToKnowledgeEntries(pairs, projectName);
|
|
15128
15432
|
if (entries.length > 0) {
|
|
15129
15433
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
@@ -15489,50 +15793,50 @@ ${USAGE5}`;
|
|
|
15489
15793
|
|
|
15490
15794
|
// src/services/diagnose-service.ts
|
|
15491
15795
|
import * as child_process4 from "child_process";
|
|
15492
|
-
import { existsSync as
|
|
15493
|
-
import
|
|
15796
|
+
import { existsSync as existsSync18, readdirSync as readdirSync3, readFileSync as readFileSync10, statSync as statSync6 } from "fs";
|
|
15797
|
+
import path33 from "path";
|
|
15494
15798
|
import { fileURLToPath } from "url";
|
|
15495
15799
|
|
|
15496
15800
|
// src/config/cache-paths.ts
|
|
15497
|
-
import * as
|
|
15498
|
-
import * as
|
|
15801
|
+
import * as os8 from "os";
|
|
15802
|
+
import * as path32 from "path";
|
|
15499
15803
|
function getPluginConfigDir() {
|
|
15500
|
-
return
|
|
15804
|
+
return path32.join(process.env.XDG_CONFIG_HOME || path32.join(os8.homedir(), ".config"), "opencode");
|
|
15501
15805
|
}
|
|
15502
15806
|
function getPluginCachePaths() {
|
|
15503
|
-
const cacheBase = process.env.XDG_CACHE_HOME ||
|
|
15807
|
+
const cacheBase = process.env.XDG_CACHE_HOME || path32.join(os8.homedir(), ".cache");
|
|
15504
15808
|
const configDir = getPluginConfigDir();
|
|
15505
15809
|
const paths = [
|
|
15506
|
-
|
|
15507
|
-
|
|
15508
|
-
|
|
15810
|
+
path32.join(cacheBase, "opencode", "node_modules", "opencode-swarm"),
|
|
15811
|
+
path32.join(cacheBase, "opencode", "packages", "opencode-swarm@latest"),
|
|
15812
|
+
path32.join(configDir, "node_modules", "opencode-swarm")
|
|
15509
15813
|
];
|
|
15510
15814
|
if (process.platform === "darwin") {
|
|
15511
|
-
const libCaches =
|
|
15512
|
-
paths.push(
|
|
15815
|
+
const libCaches = path32.join(os8.homedir(), "Library", "Caches");
|
|
15816
|
+
paths.push(path32.join(libCaches, "opencode", "node_modules", "opencode-swarm"), path32.join(libCaches, "opencode", "packages", "opencode-swarm@latest"));
|
|
15513
15817
|
}
|
|
15514
15818
|
if (process.platform === "win32") {
|
|
15515
|
-
const localAppData = process.env.LOCALAPPDATA ||
|
|
15516
|
-
const appData = process.env.APPDATA ||
|
|
15517
|
-
paths.push(
|
|
15819
|
+
const localAppData = process.env.LOCALAPPDATA || path32.join(os8.homedir(), "AppData", "Local");
|
|
15820
|
+
const appData = process.env.APPDATA || path32.join(os8.homedir(), "AppData", "Roaming");
|
|
15821
|
+
paths.push(path32.join(localAppData, "opencode", "node_modules", "opencode-swarm"), path32.join(localAppData, "opencode", "packages", "opencode-swarm@latest"), path32.join(appData, "opencode", "node_modules", "opencode-swarm"));
|
|
15518
15822
|
}
|
|
15519
15823
|
return paths;
|
|
15520
15824
|
}
|
|
15521
15825
|
function getPluginLockFilePaths() {
|
|
15522
|
-
const cacheBase = process.env.XDG_CACHE_HOME ||
|
|
15826
|
+
const cacheBase = process.env.XDG_CACHE_HOME || path32.join(os8.homedir(), ".cache");
|
|
15523
15827
|
const configDir = getPluginConfigDir();
|
|
15524
15828
|
const paths = [
|
|
15525
|
-
|
|
15526
|
-
|
|
15527
|
-
|
|
15829
|
+
path32.join(cacheBase, "opencode", "bun.lock"),
|
|
15830
|
+
path32.join(cacheBase, "opencode", "bun.lockb"),
|
|
15831
|
+
path32.join(configDir, "package-lock.json")
|
|
15528
15832
|
];
|
|
15529
15833
|
if (process.platform === "darwin") {
|
|
15530
|
-
const libCaches =
|
|
15531
|
-
paths.push(
|
|
15834
|
+
const libCaches = path32.join(os8.homedir(), "Library", "Caches");
|
|
15835
|
+
paths.push(path32.join(libCaches, "opencode", "bun.lock"), path32.join(libCaches, "opencode", "bun.lockb"));
|
|
15532
15836
|
}
|
|
15533
15837
|
if (process.platform === "win32") {
|
|
15534
|
-
const localAppData = process.env.LOCALAPPDATA ||
|
|
15535
|
-
paths.push(
|
|
15838
|
+
const localAppData = process.env.LOCALAPPDATA || path32.join(os8.homedir(), "AppData", "Local");
|
|
15839
|
+
paths.push(path32.join(localAppData, "opencode", "bun.lock"), path32.join(localAppData, "opencode", "bun.lockb"));
|
|
15536
15840
|
}
|
|
15537
15841
|
return paths;
|
|
15538
15842
|
}
|
|
@@ -15542,28 +15846,28 @@ init_capability_probe();
|
|
|
15542
15846
|
init_executor();
|
|
15543
15847
|
|
|
15544
15848
|
// src/services/knowledge-diagnostics.ts
|
|
15545
|
-
import { existsSync as
|
|
15849
|
+
import { existsSync as existsSync17 } from "fs";
|
|
15546
15850
|
import { readFile as readFile10 } from "fs/promises";
|
|
15547
15851
|
|
|
15548
15852
|
// src/services/version-check.ts
|
|
15549
|
-
import { existsSync as
|
|
15853
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync9, readFileSync as readFileSync9, writeFileSync as writeFileSync8 } from "fs";
|
|
15550
15854
|
import { homedir as homedir4 } from "os";
|
|
15551
|
-
import { join as
|
|
15855
|
+
import { join as join27 } from "path";
|
|
15552
15856
|
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
15553
15857
|
function cacheDir() {
|
|
15554
15858
|
const xdg = process.env.XDG_CACHE_HOME;
|
|
15555
|
-
const base = xdg && xdg.length > 0 ? xdg :
|
|
15556
|
-
return
|
|
15859
|
+
const base = xdg && xdg.length > 0 ? xdg : join27(homedir4(), ".cache");
|
|
15860
|
+
return join27(base, "opencode-swarm");
|
|
15557
15861
|
}
|
|
15558
15862
|
function cacheFile() {
|
|
15559
|
-
return
|
|
15863
|
+
return join27(cacheDir(), "version-check.json");
|
|
15560
15864
|
}
|
|
15561
15865
|
function readVersionCache() {
|
|
15562
15866
|
try {
|
|
15563
|
-
const
|
|
15564
|
-
if (!
|
|
15867
|
+
const path33 = cacheFile();
|
|
15868
|
+
if (!existsSync16(path33))
|
|
15565
15869
|
return null;
|
|
15566
|
-
const raw =
|
|
15870
|
+
const raw = readFileSync9(path33, "utf-8");
|
|
15567
15871
|
const parsed = JSON.parse(raw);
|
|
15568
15872
|
if (typeof parsed?.checkedAt !== "number")
|
|
15569
15873
|
return null;
|
|
@@ -15602,7 +15906,7 @@ var SEVEN_DAYS_MS2 = 7 * 24 * 60 * 60 * 1000;
|
|
|
15602
15906
|
var UNACTIONABLE_BACKLOG_WARN = 100;
|
|
15603
15907
|
var INSIGHT_BACKLOG_WARN = 50;
|
|
15604
15908
|
async function readRawLines(filePath) {
|
|
15605
|
-
if (!
|
|
15909
|
+
if (!existsSync17(filePath))
|
|
15606
15910
|
return { entries: [], corrupt: 0 };
|
|
15607
15911
|
const content = await readFile10(filePath, "utf-8");
|
|
15608
15912
|
const entries = [];
|
|
@@ -15727,7 +16031,7 @@ async function computeKnowledgeDebug(directory) {
|
|
|
15727
16031
|
};
|
|
15728
16032
|
}
|
|
15729
16033
|
async function safeJsonlCount(filePath) {
|
|
15730
|
-
if (!filePath || !
|
|
16034
|
+
if (!filePath || !existsSync17(filePath))
|
|
15731
16035
|
return 0;
|
|
15732
16036
|
try {
|
|
15733
16037
|
const content = await readFile10(filePath, "utf-8");
|
|
@@ -16048,7 +16352,7 @@ async function checkConfigBackups(directory) {
|
|
|
16048
16352
|
}
|
|
16049
16353
|
async function checkGitRepository(directory) {
|
|
16050
16354
|
try {
|
|
16051
|
-
if (!
|
|
16355
|
+
if (!existsSync18(directory) || !statSync6(directory).isDirectory()) {
|
|
16052
16356
|
return {
|
|
16053
16357
|
name: "Git Repository",
|
|
16054
16358
|
status: "\u274C",
|
|
@@ -16112,8 +16416,8 @@ async function checkSpecStaleness(directory, plan) {
|
|
|
16112
16416
|
};
|
|
16113
16417
|
}
|
|
16114
16418
|
async function checkConfigParseability(directory) {
|
|
16115
|
-
const configPath =
|
|
16116
|
-
if (!
|
|
16419
|
+
const configPath = path33.join(directory, ".opencode/opencode-swarm.json");
|
|
16420
|
+
if (!existsSync18(configPath)) {
|
|
16117
16421
|
return {
|
|
16118
16422
|
name: "Config Parseability",
|
|
16119
16423
|
status: "\u2705",
|
|
@@ -16121,7 +16425,7 @@ async function checkConfigParseability(directory) {
|
|
|
16121
16425
|
};
|
|
16122
16426
|
}
|
|
16123
16427
|
try {
|
|
16124
|
-
const content =
|
|
16428
|
+
const content = readFileSync10(configPath, "utf-8");
|
|
16125
16429
|
JSON.parse(content);
|
|
16126
16430
|
return {
|
|
16127
16431
|
name: "Config Parseability",
|
|
@@ -16141,7 +16445,7 @@ function resolveGrammarDir(thisDir) {
|
|
|
16141
16445
|
const normalized = thisDir.replace(/\\/g, "/");
|
|
16142
16446
|
const isSource = normalized.endsWith("/src/services");
|
|
16143
16447
|
const isCliBundle = normalized.endsWith("/cli");
|
|
16144
|
-
return isSource || isCliBundle ?
|
|
16448
|
+
return isSource || isCliBundle ? path33.join(thisDir, "..", "lang", "grammars") : path33.join(thisDir, "lang", "grammars");
|
|
16145
16449
|
}
|
|
16146
16450
|
async function checkGrammarWasmFiles() {
|
|
16147
16451
|
const grammarFiles = [
|
|
@@ -16165,14 +16469,14 @@ async function checkGrammarWasmFiles() {
|
|
|
16165
16469
|
"tree-sitter-ini.wasm",
|
|
16166
16470
|
"tree-sitter-regex.wasm"
|
|
16167
16471
|
];
|
|
16168
|
-
const thisDir =
|
|
16472
|
+
const thisDir = path33.dirname(fileURLToPath(import.meta.url));
|
|
16169
16473
|
const grammarDir = resolveGrammarDir(thisDir);
|
|
16170
16474
|
const missing = [];
|
|
16171
|
-
if (!
|
|
16475
|
+
if (!existsSync18(path33.join(grammarDir, "tree-sitter.wasm"))) {
|
|
16172
16476
|
missing.push("tree-sitter.wasm (core runtime)");
|
|
16173
16477
|
}
|
|
16174
16478
|
for (const file of grammarFiles) {
|
|
16175
|
-
if (!
|
|
16479
|
+
if (!existsSync18(path33.join(grammarDir, file))) {
|
|
16176
16480
|
missing.push(file);
|
|
16177
16481
|
}
|
|
16178
16482
|
}
|
|
@@ -16190,8 +16494,8 @@ async function checkGrammarWasmFiles() {
|
|
|
16190
16494
|
};
|
|
16191
16495
|
}
|
|
16192
16496
|
async function checkCheckpointManifest(directory) {
|
|
16193
|
-
const manifestPath =
|
|
16194
|
-
if (!
|
|
16497
|
+
const manifestPath = path33.join(directory, ".swarm/checkpoints.json");
|
|
16498
|
+
if (!existsSync18(manifestPath)) {
|
|
16195
16499
|
return {
|
|
16196
16500
|
name: "Checkpoint Manifest",
|
|
16197
16501
|
status: "\u2705",
|
|
@@ -16199,7 +16503,7 @@ async function checkCheckpointManifest(directory) {
|
|
|
16199
16503
|
};
|
|
16200
16504
|
}
|
|
16201
16505
|
try {
|
|
16202
|
-
const content =
|
|
16506
|
+
const content = readFileSync10(manifestPath, "utf-8");
|
|
16203
16507
|
const parsed = JSON.parse(content);
|
|
16204
16508
|
if (!parsed.checkpoints || !Array.isArray(parsed.checkpoints)) {
|
|
16205
16509
|
return {
|
|
@@ -16242,8 +16546,8 @@ async function checkCheckpointManifest(directory) {
|
|
|
16242
16546
|
}
|
|
16243
16547
|
}
|
|
16244
16548
|
async function checkEventStreamIntegrity(directory) {
|
|
16245
|
-
const eventsPath =
|
|
16246
|
-
if (!
|
|
16549
|
+
const eventsPath = path33.join(directory, ".swarm/events.jsonl");
|
|
16550
|
+
if (!existsSync18(eventsPath)) {
|
|
16247
16551
|
return {
|
|
16248
16552
|
name: "Event Stream",
|
|
16249
16553
|
status: "\u2705",
|
|
@@ -16251,7 +16555,7 @@ async function checkEventStreamIntegrity(directory) {
|
|
|
16251
16555
|
};
|
|
16252
16556
|
}
|
|
16253
16557
|
try {
|
|
16254
|
-
const content =
|
|
16558
|
+
const content = readFileSync10(eventsPath, "utf-8");
|
|
16255
16559
|
const lines = content.split(`
|
|
16256
16560
|
`).filter((line) => line.trim() !== "");
|
|
16257
16561
|
let malformedCount = 0;
|
|
@@ -16283,8 +16587,8 @@ async function checkEventStreamIntegrity(directory) {
|
|
|
16283
16587
|
}
|
|
16284
16588
|
}
|
|
16285
16589
|
async function checkSteeringDirectives(directory) {
|
|
16286
|
-
const eventsPath =
|
|
16287
|
-
if (!
|
|
16590
|
+
const eventsPath = path33.join(directory, ".swarm/events.jsonl");
|
|
16591
|
+
if (!existsSync18(eventsPath)) {
|
|
16288
16592
|
return {
|
|
16289
16593
|
name: "Steering Directives",
|
|
16290
16594
|
status: "\u2705",
|
|
@@ -16292,7 +16596,7 @@ async function checkSteeringDirectives(directory) {
|
|
|
16292
16596
|
};
|
|
16293
16597
|
}
|
|
16294
16598
|
try {
|
|
16295
|
-
const content =
|
|
16599
|
+
const content = readFileSync10(eventsPath, "utf-8");
|
|
16296
16600
|
const lines = content.split(`
|
|
16297
16601
|
`).filter((line) => line.trim() !== "");
|
|
16298
16602
|
const directivesIssued = [];
|
|
@@ -16339,8 +16643,8 @@ async function checkCurator(directory) {
|
|
|
16339
16643
|
detail: "Disabled (enable via curator.enabled)"
|
|
16340
16644
|
};
|
|
16341
16645
|
}
|
|
16342
|
-
const summaryPath =
|
|
16343
|
-
if (!
|
|
16646
|
+
const summaryPath = path33.join(directory, ".swarm/curator-summary.json");
|
|
16647
|
+
if (!existsSync18(summaryPath)) {
|
|
16344
16648
|
return {
|
|
16345
16649
|
name: "Curator",
|
|
16346
16650
|
status: "\u2705",
|
|
@@ -16348,7 +16652,7 @@ async function checkCurator(directory) {
|
|
|
16348
16652
|
};
|
|
16349
16653
|
}
|
|
16350
16654
|
try {
|
|
16351
|
-
const content =
|
|
16655
|
+
const content = readFileSync10(summaryPath, "utf-8");
|
|
16352
16656
|
const parsed = JSON.parse(content);
|
|
16353
16657
|
if (typeof parsed.schema_version !== "number" || parsed.schema_version !== 1) {
|
|
16354
16658
|
return {
|
|
@@ -16541,8 +16845,8 @@ async function getDiagnoseData(directory) {
|
|
|
16541
16845
|
checks.push(await checkCurator(directory));
|
|
16542
16846
|
checks.push(await checkKnowledgeHealth(directory));
|
|
16543
16847
|
try {
|
|
16544
|
-
const evidenceDir =
|
|
16545
|
-
const snapshotFiles =
|
|
16848
|
+
const evidenceDir = path33.join(directory, ".swarm", "evidence");
|
|
16849
|
+
const snapshotFiles = existsSync18(evidenceDir) ? readdirSync3(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
|
|
16546
16850
|
if (snapshotFiles.length > 0) {
|
|
16547
16851
|
const latest = snapshotFiles.sort().pop();
|
|
16548
16852
|
checks.push({
|
|
@@ -16575,13 +16879,13 @@ async function getDiagnoseData(directory) {
|
|
|
16575
16879
|
const cacheRows = [];
|
|
16576
16880
|
for (const cachePath of cachePaths) {
|
|
16577
16881
|
try {
|
|
16578
|
-
if (!
|
|
16882
|
+
if (!existsSync18(cachePath)) {
|
|
16579
16883
|
cacheRows.push(`\u2B1C ${cachePath} \u2014 absent`);
|
|
16580
16884
|
continue;
|
|
16581
16885
|
}
|
|
16582
|
-
const pkgJsonPath =
|
|
16886
|
+
const pkgJsonPath = path33.join(cachePath, "package.json");
|
|
16583
16887
|
try {
|
|
16584
|
-
const raw =
|
|
16888
|
+
const raw = readFileSync10(pkgJsonPath, "utf-8");
|
|
16585
16889
|
const parsed = JSON.parse(raw);
|
|
16586
16890
|
const installedVersion = typeof parsed.version === "string" ? parsed.version : "?";
|
|
16587
16891
|
cacheRows.push(`\u2705 ${cachePath} \u2014 v${installedVersion}`);
|
|
@@ -16800,7 +17104,7 @@ async function handleDoctorCommand(directory, args) {
|
|
|
16800
17104
|
const result = runConfigDoctor(config, directory);
|
|
16801
17105
|
let output;
|
|
16802
17106
|
if (enableAutoFix && result.hasAutoFixableIssues) {
|
|
16803
|
-
const { runConfigDoctorWithFixes } = await import("./config-doctor-
|
|
17107
|
+
const { runConfigDoctorWithFixes } = await import("./config-doctor-9fhfy6p7.js");
|
|
16804
17108
|
const fixResult = await runConfigDoctorWithFixes(directory, config, true);
|
|
16805
17109
|
output = formatDoctorMarkdown(fixResult.result);
|
|
16806
17110
|
} else {
|
|
@@ -16950,10 +17254,10 @@ function decideEpicActivation(tasks, cochangePairs, commitsObserved, options) {
|
|
|
16950
17254
|
|
|
16951
17255
|
// src/turbo/epic/calibration.ts
|
|
16952
17256
|
init_logger();
|
|
16953
|
-
import * as
|
|
16954
|
-
import * as
|
|
17257
|
+
import * as fs15 from "fs";
|
|
17258
|
+
import * as path34 from "path";
|
|
16955
17259
|
var STATE_FILE = "calibration.json";
|
|
16956
|
-
var STATE_REL_DIR =
|
|
17260
|
+
var STATE_REL_DIR = path34.join(".swarm", "epic");
|
|
16957
17261
|
function nowISO() {
|
|
16958
17262
|
return new Date().toISOString();
|
|
16959
17263
|
}
|
|
@@ -16975,13 +17279,13 @@ function markUnreadable(directory, reason) {
|
|
|
16975
17279
|
error(`[epic/calibration] state file unreadable for ${directory}: ${reason} \u2014 failing closed`);
|
|
16976
17280
|
}
|
|
16977
17281
|
function repairCalibrationUnreadable(directory) {
|
|
16978
|
-
const filePath =
|
|
16979
|
-
if (!
|
|
17282
|
+
const filePath = path34.join(directory, STATE_REL_DIR, STATE_FILE);
|
|
17283
|
+
if (!fs15.existsSync(filePath)) {
|
|
16980
17284
|
stateUnreadableMap.delete(directory);
|
|
16981
17285
|
return;
|
|
16982
17286
|
}
|
|
16983
17287
|
try {
|
|
16984
|
-
const raw =
|
|
17288
|
+
const raw = fs15.readFileSync(filePath, "utf-8");
|
|
16985
17289
|
const parsed = JSON.parse(raw);
|
|
16986
17290
|
if (!isValidCalibrationShape(parsed)) {
|
|
16987
17291
|
stateUnreadableMap.set(directory, true);
|
|
@@ -17007,9 +17311,9 @@ function isValidCalibrationShape(candidate) {
|
|
|
17007
17311
|
return true;
|
|
17008
17312
|
}
|
|
17009
17313
|
function ensureSwarmEpicDir(directory) {
|
|
17010
|
-
const dir =
|
|
17011
|
-
if (!
|
|
17012
|
-
|
|
17314
|
+
const dir = path34.resolve(directory, STATE_REL_DIR);
|
|
17315
|
+
if (!fs15.existsSync(dir)) {
|
|
17316
|
+
fs15.mkdirSync(dir, { recursive: true });
|
|
17013
17317
|
}
|
|
17014
17318
|
return dir;
|
|
17015
17319
|
}
|
|
@@ -17019,18 +17323,18 @@ function loadCalibrationState(directory) {
|
|
|
17019
17323
|
if (stateUnreadableMap.get(directory))
|
|
17020
17324
|
return null;
|
|
17021
17325
|
}
|
|
17022
|
-
const filePath =
|
|
17326
|
+
const filePath = path34.join(directory, STATE_REL_DIR, STATE_FILE);
|
|
17023
17327
|
try {
|
|
17024
|
-
if (!
|
|
17328
|
+
if (!fs15.existsSync(filePath)) {
|
|
17025
17329
|
const seed = emptyCalibrationState();
|
|
17026
17330
|
try {
|
|
17027
17331
|
ensureSwarmEpicDir(directory);
|
|
17028
|
-
|
|
17332
|
+
fs15.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
|
|
17029
17333
|
`, "utf-8");
|
|
17030
17334
|
} catch {}
|
|
17031
17335
|
return seed;
|
|
17032
17336
|
}
|
|
17033
|
-
const raw =
|
|
17337
|
+
const raw = fs15.readFileSync(filePath, "utf-8");
|
|
17034
17338
|
const parsed = JSON.parse(raw);
|
|
17035
17339
|
if (!isValidCalibrationShape(parsed)) {
|
|
17036
17340
|
markUnreadable(directory, `malformed shape (version=${parsed?.version}, hotModuleAdditions type=${Array.isArray(parsed?.hotModuleAdditions) ? "array" : typeof parsed?.hotModuleAdditions})`);
|
|
@@ -17045,36 +17349,36 @@ function loadCalibrationState(directory) {
|
|
|
17045
17349
|
|
|
17046
17350
|
// src/turbo/epic/divergence-recorder.ts
|
|
17047
17351
|
init_logger();
|
|
17048
|
-
import * as
|
|
17049
|
-
import * as
|
|
17050
|
-
var EVIDENCE_REL_DIR =
|
|
17352
|
+
import * as fs16 from "fs";
|
|
17353
|
+
import * as path35 from "path";
|
|
17354
|
+
var EVIDENCE_REL_DIR = path35.join(".swarm", "epic");
|
|
17051
17355
|
var EVIDENCE_FILE = "divergence.jsonl";
|
|
17052
17356
|
var MAX_TAIL_BYTES2 = 16 * 1024 * 1024;
|
|
17053
17357
|
function readDivergenceHistory(directory, options) {
|
|
17054
|
-
const filePath =
|
|
17055
|
-
if (!
|
|
17358
|
+
const filePath = path35.join(directory, EVIDENCE_REL_DIR, EVIDENCE_FILE);
|
|
17359
|
+
if (!fs16.existsSync(filePath)) {
|
|
17056
17360
|
return [];
|
|
17057
17361
|
}
|
|
17058
17362
|
const maxBytes = options?.maxBytes ?? MAX_TAIL_BYTES2;
|
|
17059
17363
|
let raw;
|
|
17060
17364
|
let tailTruncated = false;
|
|
17061
17365
|
try {
|
|
17062
|
-
const stat5 =
|
|
17366
|
+
const stat5 = fs16.statSync(filePath);
|
|
17063
17367
|
if (Number.isFinite(maxBytes) && stat5.size > maxBytes) {
|
|
17064
|
-
const fd =
|
|
17368
|
+
const fd = fs16.openSync(filePath, "r");
|
|
17065
17369
|
try {
|
|
17066
17370
|
const buf = Buffer.alloc(maxBytes);
|
|
17067
17371
|
const offset = stat5.size - maxBytes;
|
|
17068
|
-
|
|
17372
|
+
fs16.readSync(fd, buf, 0, maxBytes, offset);
|
|
17069
17373
|
raw = buf.toString("utf-8");
|
|
17070
17374
|
tailTruncated = true;
|
|
17071
17375
|
} finally {
|
|
17072
17376
|
try {
|
|
17073
|
-
|
|
17377
|
+
fs16.closeSync(fd);
|
|
17074
17378
|
} catch {}
|
|
17075
17379
|
}
|
|
17076
17380
|
} else {
|
|
17077
|
-
raw =
|
|
17381
|
+
raw = fs16.readFileSync(filePath, "utf-8");
|
|
17078
17382
|
}
|
|
17079
17383
|
} catch {
|
|
17080
17384
|
return [];
|
|
@@ -17099,16 +17403,16 @@ function readDivergenceHistory(directory, options) {
|
|
|
17099
17403
|
}
|
|
17100
17404
|
|
|
17101
17405
|
// src/turbo/epic/promotion-evidence.ts
|
|
17102
|
-
import * as
|
|
17103
|
-
import * as
|
|
17104
|
-
var EVIDENCE_REL_DIR2 =
|
|
17406
|
+
import * as fs17 from "fs";
|
|
17407
|
+
import * as path36 from "path";
|
|
17408
|
+
var EVIDENCE_REL_DIR2 = path36.join(".swarm", "evidence");
|
|
17105
17409
|
var EVIDENCE_FILE2 = "epic-promotions.jsonl";
|
|
17106
17410
|
function readPromotionEvidence(directory) {
|
|
17107
|
-
const filePath =
|
|
17108
|
-
if (!
|
|
17411
|
+
const filePath = path36.join(directory, EVIDENCE_REL_DIR2, EVIDENCE_FILE2);
|
|
17412
|
+
if (!fs17.existsSync(filePath)) {
|
|
17109
17413
|
return [];
|
|
17110
17414
|
}
|
|
17111
|
-
const raw =
|
|
17415
|
+
const raw = fs17.readFileSync(filePath, "utf-8");
|
|
17112
17416
|
const lines = raw.split(`
|
|
17113
17417
|
`).filter((l) => l.trim().length > 0);
|
|
17114
17418
|
const records = [];
|
|
@@ -17613,7 +17917,7 @@ async function handleEvidenceCommand(directory, args) {
|
|
|
17613
17917
|
return formatTaskEvidenceMarkdown(evidenceData);
|
|
17614
17918
|
}
|
|
17615
17919
|
async function handleEvidenceSummaryCommand(directory) {
|
|
17616
|
-
const { buildEvidenceSummary } = await import("./evidence-summary-service-
|
|
17920
|
+
const { buildEvidenceSummary } = await import("./evidence-summary-service-gvd7mw7v.js");
|
|
17617
17921
|
const artifact = await buildEvidenceSummary(directory);
|
|
17618
17922
|
if (!artifact) {
|
|
17619
17923
|
return "No plan found. Run `/swarm plan` to check plan status.";
|
|
@@ -17677,8 +17981,8 @@ async function handleExportCommand(directory, _args) {
|
|
|
17677
17981
|
}
|
|
17678
17982
|
// src/full-auto/state.ts
|
|
17679
17983
|
var import_proper_lockfile4 = __toESM(require_proper_lockfile(), 1);
|
|
17680
|
-
import * as
|
|
17681
|
-
import * as
|
|
17984
|
+
import * as fs18 from "fs";
|
|
17985
|
+
import * as path37 from "path";
|
|
17682
17986
|
init_logger();
|
|
17683
17987
|
var lockfile4 = import_proper_lockfile4.default;
|
|
17684
17988
|
var STATE_FILE2 = "full-auto-state.json";
|
|
@@ -17686,9 +17990,9 @@ function nowISO2() {
|
|
|
17686
17990
|
return new Date().toISOString();
|
|
17687
17991
|
}
|
|
17688
17992
|
function ensureSwarmDir(directory) {
|
|
17689
|
-
const swarmDir =
|
|
17690
|
-
if (!
|
|
17691
|
-
|
|
17993
|
+
const swarmDir = path37.resolve(directory, ".swarm");
|
|
17994
|
+
if (!fs18.existsSync(swarmDir)) {
|
|
17995
|
+
fs18.mkdirSync(swarmDir, { recursive: true });
|
|
17692
17996
|
}
|
|
17693
17997
|
return swarmDir;
|
|
17694
17998
|
}
|
|
@@ -17746,7 +18050,7 @@ function withStateLock(directory, fn) {
|
|
|
17746
18050
|
let release;
|
|
17747
18051
|
try {
|
|
17748
18052
|
const lockTarget = validateSwarmPath(directory, STATE_FILE2);
|
|
17749
|
-
if (!
|
|
18053
|
+
if (!fs18.existsSync(lockTarget)) {
|
|
17750
18054
|
ensureSwarmDir(directory);
|
|
17751
18055
|
const seed = {
|
|
17752
18056
|
version: 2,
|
|
@@ -17754,7 +18058,7 @@ function withStateLock(directory, fn) {
|
|
|
17754
18058
|
oversightSequence: 0,
|
|
17755
18059
|
sessions: {}
|
|
17756
18060
|
};
|
|
17757
|
-
|
|
18061
|
+
fs18.writeFileSync(lockTarget, `${JSON.stringify(seed, null, 2)}
|
|
17758
18062
|
`, "utf-8");
|
|
17759
18063
|
}
|
|
17760
18064
|
release = lockfile4.lockSync(lockTarget, {
|
|
@@ -17804,7 +18108,7 @@ function readPersisted(directory) {
|
|
|
17804
18108
|
const filePath = validateSwarmPath(directory, STATE_FILE2);
|
|
17805
18109
|
let stats;
|
|
17806
18110
|
try {
|
|
17807
|
-
stats =
|
|
18111
|
+
stats = fs18.statSync(filePath);
|
|
17808
18112
|
} catch {
|
|
17809
18113
|
clearStateUnreadable();
|
|
17810
18114
|
readCache.delete(filePath);
|
|
@@ -17815,7 +18119,7 @@ function readPersisted(directory) {
|
|
|
17815
18119
|
clearStateUnreadable();
|
|
17816
18120
|
return structuredClone(cached.state);
|
|
17817
18121
|
}
|
|
17818
|
-
const raw =
|
|
18122
|
+
const raw = fs18.readFileSync(filePath, "utf-8");
|
|
17819
18123
|
const parsed = JSON.parse(raw);
|
|
17820
18124
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || parsed.version !== 2 || !parsed.sessions || typeof parsed.sessions !== "object" || Array.isArray(parsed.sessions)) {
|
|
17821
18125
|
markStateUnreadable(`malformed shape (version=${parsed?.version}, sessions type=${Array.isArray(parsed?.sessions) ? "array" : typeof parsed?.sessions})`);
|
|
@@ -17840,8 +18144,8 @@ function readPersisted(directory) {
|
|
|
17840
18144
|
error(`[full-auto/state] Failed to read ${STATE_FILE2}: ${reason} \u2014 attempting .bak recovery`);
|
|
17841
18145
|
try {
|
|
17842
18146
|
const bakPath = validateSwarmPath(directory, `${STATE_FILE2}.bak`);
|
|
17843
|
-
if (
|
|
17844
|
-
const raw =
|
|
18147
|
+
if (fs18.existsSync(bakPath)) {
|
|
18148
|
+
const raw = fs18.readFileSync(bakPath, "utf-8");
|
|
17845
18149
|
const parsed = JSON.parse(raw);
|
|
17846
18150
|
if (parsed?.version === 2 && parsed.sessions && !Array.isArray(parsed.sessions)) {
|
|
17847
18151
|
warn(`[full-auto/state] Recovered from ${STATE_FILE2}.bak`);
|
|
@@ -17881,23 +18185,23 @@ function writePersisted(directory, persisted) {
|
|
|
17881
18185
|
throw new Error(`Full-Auto state persistence prepare failed: ${msg}`);
|
|
17882
18186
|
}
|
|
17883
18187
|
try {
|
|
17884
|
-
if (
|
|
17885
|
-
|
|
18188
|
+
if (fs18.existsSync(filePath)) {
|
|
18189
|
+
fs18.copyFileSync(filePath, bakPath);
|
|
17886
18190
|
}
|
|
17887
18191
|
} catch {}
|
|
17888
18192
|
try {
|
|
17889
|
-
|
|
18193
|
+
fs18.writeFileSync(tmpPath, payload, "utf-8");
|
|
17890
18194
|
try {
|
|
17891
|
-
const fd =
|
|
18195
|
+
const fd = fs18.openSync(tmpPath, "r+");
|
|
17892
18196
|
try {
|
|
17893
|
-
|
|
18197
|
+
fs18.fsyncSync(fd);
|
|
17894
18198
|
} finally {
|
|
17895
|
-
|
|
18199
|
+
fs18.closeSync(fd);
|
|
17896
18200
|
}
|
|
17897
18201
|
} catch {}
|
|
17898
|
-
|
|
18202
|
+
fs18.renameSync(tmpPath, filePath);
|
|
17899
18203
|
readCache.delete(filePath);
|
|
17900
|
-
const readback =
|
|
18204
|
+
const readback = fs18.readFileSync(filePath, "utf-8");
|
|
17901
18205
|
const parsed = JSON.parse(readback);
|
|
17902
18206
|
if (parsed?.version !== 2) {
|
|
17903
18207
|
throw new Error("Round-trip readback returned wrong version");
|
|
@@ -18117,7 +18421,7 @@ function buildStatusReport(directory, sessionID, sessionFlag) {
|
|
|
18117
18421
|
|
|
18118
18422
|
// src/commands/handoff.ts
|
|
18119
18423
|
import crypto4 from "crypto";
|
|
18120
|
-
import { renameSync as renameSync9, unlinkSync as
|
|
18424
|
+
import { renameSync as renameSync9, unlinkSync as unlinkSync6 } from "fs";
|
|
18121
18425
|
|
|
18122
18426
|
// src/services/handoff-service.ts
|
|
18123
18427
|
var RTL_OVERRIDE_PATTERN = /[\u202e\u202d\u202c\u200f]/g;
|
|
@@ -18498,7 +18802,7 @@ var _internals27 = {
|
|
|
18498
18802
|
|
|
18499
18803
|
// src/session/snapshot-writer.ts
|
|
18500
18804
|
import { closeSync as closeSync6, fsyncSync as fsyncSync2, mkdirSync as mkdirSync14, openSync as openSync6, renameSync as renameSync8 } from "fs";
|
|
18501
|
-
import * as
|
|
18805
|
+
import * as path38 from "path";
|
|
18502
18806
|
var _writeInFlight = Promise.resolve();
|
|
18503
18807
|
function serializeAgentSession(s) {
|
|
18504
18808
|
const gateLog = {};
|
|
@@ -18605,7 +18909,7 @@ async function writeSnapshot(directory, state) {
|
|
|
18605
18909
|
}
|
|
18606
18910
|
const content = JSON.stringify(snapshot, null, 2);
|
|
18607
18911
|
const resolvedPath = validateSwarmPath(directory, "session/state.json");
|
|
18608
|
-
const dir =
|
|
18912
|
+
const dir = path38.dirname(resolvedPath);
|
|
18609
18913
|
mkdirSync14(dir, { recursive: true });
|
|
18610
18914
|
const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
18611
18915
|
await bunWrite(tempPath, content);
|
|
@@ -18652,7 +18956,7 @@ async function handleHandoffCommand(directory, _args) {
|
|
|
18652
18956
|
renameSync9(tempPath, resolvedPath);
|
|
18653
18957
|
} catch (renameErr) {
|
|
18654
18958
|
try {
|
|
18655
|
-
|
|
18959
|
+
unlinkSync6(tempPath);
|
|
18656
18960
|
} catch {}
|
|
18657
18961
|
throw renameErr;
|
|
18658
18962
|
}
|
|
@@ -18664,7 +18968,7 @@ async function handleHandoffCommand(directory, _args) {
|
|
|
18664
18968
|
renameSync9(promptTempPath, promptPath);
|
|
18665
18969
|
} catch (renameErr) {
|
|
18666
18970
|
try {
|
|
18667
|
-
|
|
18971
|
+
unlinkSync6(promptTempPath);
|
|
18668
18972
|
} catch {}
|
|
18669
18973
|
throw renameErr;
|
|
18670
18974
|
}
|
|
@@ -19108,27 +19412,65 @@ ${USAGE6}`;
|
|
|
19108
19412
|
}
|
|
19109
19413
|
|
|
19110
19414
|
// src/commands/knowledge.ts
|
|
19111
|
-
import { join as
|
|
19415
|
+
import { join as join32 } from "path";
|
|
19112
19416
|
|
|
19113
19417
|
// src/hooks/knowledge-migrator.ts
|
|
19114
19418
|
init_logger();
|
|
19115
19419
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
19116
|
-
import { existsSync as
|
|
19420
|
+
import { existsSync as existsSync23, readFileSync as readFileSync15 } from "fs";
|
|
19117
19421
|
import { mkdir as mkdir9, readFile as readFile11, writeFile as writeFile9 } from "fs/promises";
|
|
19118
|
-
import * as
|
|
19119
|
-
import * as
|
|
19422
|
+
import * as os9 from "os";
|
|
19423
|
+
import * as path39 from "path";
|
|
19120
19424
|
|
|
19121
19425
|
// src/hooks/knowledge-types.ts
|
|
19122
19426
|
var KNOWLEDGE_SCHEMA_VERSION = 2;
|
|
19123
19427
|
|
|
19124
19428
|
// src/hooks/knowledge-migrator.ts
|
|
19125
19429
|
async function migrateKnowledgeToExternal(_directory, _config) {
|
|
19430
|
+
const externalSentinelPath = path39.join(_directory, ".swarm", ".knowledge-external-migrated");
|
|
19431
|
+
const contextPath = path39.join(_directory, ".swarm", "context.md");
|
|
19432
|
+
if (_internals30.existsSync(externalSentinelPath)) {
|
|
19433
|
+
return {
|
|
19434
|
+
migrated: false,
|
|
19435
|
+
entriesMigrated: 0,
|
|
19436
|
+
entriesDropped: 0,
|
|
19437
|
+
entriesTotal: 0,
|
|
19438
|
+
skippedReason: "external-sentinel-exists"
|
|
19439
|
+
};
|
|
19440
|
+
}
|
|
19441
|
+
if (!_internals30.existsSync(contextPath)) {
|
|
19442
|
+
return {
|
|
19443
|
+
migrated: false,
|
|
19444
|
+
entriesMigrated: 0,
|
|
19445
|
+
entriesDropped: 0,
|
|
19446
|
+
entriesTotal: 0,
|
|
19447
|
+
skippedReason: "no-context-file"
|
|
19448
|
+
};
|
|
19449
|
+
}
|
|
19450
|
+
const contextContent = await _internals30.readFile(contextPath, "utf-8");
|
|
19451
|
+
if (contextContent.trim().length === 0) {
|
|
19452
|
+
return {
|
|
19453
|
+
migrated: false,
|
|
19454
|
+
entriesMigrated: 0,
|
|
19455
|
+
entriesDropped: 0,
|
|
19456
|
+
entriesTotal: 0,
|
|
19457
|
+
skippedReason: "empty-context"
|
|
19458
|
+
};
|
|
19459
|
+
}
|
|
19460
|
+
const lines = contextContent.split(`
|
|
19461
|
+
`);
|
|
19462
|
+
let entriesCount = 0;
|
|
19463
|
+
for (const line of lines) {
|
|
19464
|
+
if (line.trimStart().startsWith("- ")) {
|
|
19465
|
+
entriesCount++;
|
|
19466
|
+
}
|
|
19467
|
+
}
|
|
19468
|
+
await _internals30.writeSentinel(externalSentinelPath, entriesCount, entriesCount);
|
|
19126
19469
|
return {
|
|
19127
|
-
migrated:
|
|
19128
|
-
entriesMigrated:
|
|
19470
|
+
migrated: true,
|
|
19471
|
+
entriesMigrated: entriesCount,
|
|
19129
19472
|
entriesDropped: 0,
|
|
19130
|
-
entriesTotal:
|
|
19131
|
-
skippedReason: "no-context-file"
|
|
19473
|
+
entriesTotal: entriesCount
|
|
19132
19474
|
};
|
|
19133
19475
|
}
|
|
19134
19476
|
var _internals30 = {
|
|
@@ -19143,13 +19485,18 @@ var _internals30 = {
|
|
|
19143
19485
|
truncateLesson: truncateLesson2,
|
|
19144
19486
|
inferProjectName,
|
|
19145
19487
|
writeSentinel,
|
|
19146
|
-
resolveLegacyHiveKnowledgePath
|
|
19488
|
+
resolveLegacyHiveKnowledgePath,
|
|
19489
|
+
existsSync: existsSync23,
|
|
19490
|
+
readFileSync: readFileSync15,
|
|
19491
|
+
readFile: readFile11,
|
|
19492
|
+
mkdir: mkdir9,
|
|
19493
|
+
writeFile: writeFile9
|
|
19147
19494
|
};
|
|
19148
19495
|
async function migrateContextToKnowledge(directory, config) {
|
|
19149
|
-
const sentinelPath =
|
|
19150
|
-
const contextPath =
|
|
19496
|
+
const sentinelPath = path39.join(directory, ".swarm", ".knowledge-migrated");
|
|
19497
|
+
const contextPath = path39.join(directory, ".swarm", "context.md");
|
|
19151
19498
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
19152
|
-
if (
|
|
19499
|
+
if (existsSync23(sentinelPath)) {
|
|
19153
19500
|
return {
|
|
19154
19501
|
migrated: false,
|
|
19155
19502
|
entriesMigrated: 0,
|
|
@@ -19158,7 +19505,7 @@ async function migrateContextToKnowledge(directory, config) {
|
|
|
19158
19505
|
skippedReason: "sentinel-exists"
|
|
19159
19506
|
};
|
|
19160
19507
|
}
|
|
19161
|
-
if (!
|
|
19508
|
+
if (!existsSync23(contextPath)) {
|
|
19162
19509
|
return {
|
|
19163
19510
|
migrated: false,
|
|
19164
19511
|
entriesMigrated: 0,
|
|
@@ -19249,8 +19596,8 @@ async function migrateContextToKnowledge(directory, config) {
|
|
|
19249
19596
|
async function migrateHiveKnowledgeLegacy(config) {
|
|
19250
19597
|
const legacyHivePath = _internals30.resolveLegacyHiveKnowledgePath();
|
|
19251
19598
|
const canonicalHivePath = resolveHiveKnowledgePath();
|
|
19252
|
-
const sentinelPath =
|
|
19253
|
-
if (
|
|
19599
|
+
const sentinelPath = path39.join(path39.dirname(canonicalHivePath), ".hive-knowledge-migrated");
|
|
19600
|
+
if (existsSync23(sentinelPath)) {
|
|
19254
19601
|
return {
|
|
19255
19602
|
migrated: false,
|
|
19256
19603
|
entriesMigrated: 0,
|
|
@@ -19259,7 +19606,7 @@ async function migrateHiveKnowledgeLegacy(config) {
|
|
|
19259
19606
|
skippedReason: "sentinel-exists"
|
|
19260
19607
|
};
|
|
19261
19608
|
}
|
|
19262
|
-
if (!
|
|
19609
|
+
if (!existsSync23(legacyHivePath)) {
|
|
19263
19610
|
return {
|
|
19264
19611
|
migrated: false,
|
|
19265
19612
|
entriesMigrated: 0,
|
|
@@ -19460,16 +19807,16 @@ function truncateLesson2(text) {
|
|
|
19460
19807
|
return `${text.slice(0, 277)}...`;
|
|
19461
19808
|
}
|
|
19462
19809
|
function inferProjectName(directory) {
|
|
19463
|
-
const packageJsonPath =
|
|
19464
|
-
if (
|
|
19810
|
+
const packageJsonPath = path39.join(directory, "package.json");
|
|
19811
|
+
if (existsSync23(packageJsonPath)) {
|
|
19465
19812
|
try {
|
|
19466
|
-
const pkg = JSON.parse(
|
|
19813
|
+
const pkg = JSON.parse(readFileSync15(packageJsonPath, "utf-8"));
|
|
19467
19814
|
if (pkg.name && typeof pkg.name === "string") {
|
|
19468
19815
|
return pkg.name;
|
|
19469
19816
|
}
|
|
19470
19817
|
} catch {}
|
|
19471
19818
|
}
|
|
19472
|
-
return
|
|
19819
|
+
return path39.basename(directory);
|
|
19473
19820
|
}
|
|
19474
19821
|
async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
19475
19822
|
const sentinel = {
|
|
@@ -19481,21 +19828,21 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
|
19481
19828
|
schema_version: 1,
|
|
19482
19829
|
migration_tool: "knowledge-migrator.ts"
|
|
19483
19830
|
};
|
|
19484
|
-
await
|
|
19485
|
-
await
|
|
19831
|
+
await _internals30.mkdir(path39.dirname(sentinelPath), { recursive: true });
|
|
19832
|
+
await _internals30.writeFile(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
|
|
19486
19833
|
}
|
|
19487
19834
|
function resolveLegacyHiveKnowledgePath() {
|
|
19488
19835
|
const platform = process.platform;
|
|
19489
|
-
const home = process.env.HOME ||
|
|
19836
|
+
const home = process.env.HOME || os9.homedir();
|
|
19490
19837
|
let dataDir;
|
|
19491
19838
|
if (platform === "win32") {
|
|
19492
|
-
dataDir =
|
|
19839
|
+
dataDir = path39.join(process.env.LOCALAPPDATA || path39.join(home, "AppData", "Local"), "opencode-swarm", "Data");
|
|
19493
19840
|
} else if (platform === "darwin") {
|
|
19494
|
-
dataDir =
|
|
19841
|
+
dataDir = path39.join(home, "Library", "Application Support", "opencode-swarm");
|
|
19495
19842
|
} else {
|
|
19496
|
-
dataDir =
|
|
19843
|
+
dataDir = path39.join(process.env.XDG_DATA_HOME || path39.join(home, ".local", "share"), "opencode-swarm");
|
|
19497
19844
|
}
|
|
19498
|
-
return
|
|
19845
|
+
return path39.join(dataDir, "hive-knowledge.jsonl");
|
|
19499
19846
|
}
|
|
19500
19847
|
|
|
19501
19848
|
// src/commands/knowledge.ts
|
|
@@ -19549,7 +19896,7 @@ async function handleKnowledgeRestoreCommand(directory, args) {
|
|
|
19549
19896
|
return "Invalid entry ID. IDs must be 1-64 characters: letters, digits, hyphens, underscores only.";
|
|
19550
19897
|
}
|
|
19551
19898
|
try {
|
|
19552
|
-
const quarantinePath =
|
|
19899
|
+
const quarantinePath = join32(resolveKnowledgeStoreDir(directory), "knowledge-quarantined.jsonl");
|
|
19553
19900
|
const entries = await readKnowledge(quarantinePath);
|
|
19554
19901
|
const resolved = resolveEntryByPrefix(entries, inputId);
|
|
19555
19902
|
if ("error" in resolved) {
|
|
@@ -19800,15 +20147,15 @@ var _internals31 = {
|
|
|
19800
20147
|
};
|
|
19801
20148
|
|
|
19802
20149
|
// src/commands/link.ts
|
|
19803
|
-
import { existsSync as
|
|
19804
|
-
import * as
|
|
20150
|
+
import { existsSync as existsSync24 } from "fs";
|
|
20151
|
+
import * as path41 from "path";
|
|
19805
20152
|
|
|
19806
20153
|
// src/knowledge/identity.ts
|
|
19807
20154
|
import * as child_process5 from "child_process";
|
|
19808
20155
|
import { createHash as createHash4 } from "crypto";
|
|
19809
|
-
import * as
|
|
20156
|
+
import * as path40 from "path";
|
|
19810
20157
|
function deriveProjectHash(directory) {
|
|
19811
|
-
const absolutePath =
|
|
20158
|
+
const absolutePath = path40.resolve(directory);
|
|
19812
20159
|
let hashInput;
|
|
19813
20160
|
try {
|
|
19814
20161
|
const remoteUrl = child_process5.execSync("git remote get-url origin", {
|
|
@@ -19828,18 +20175,18 @@ function deriveProjectHash(directory) {
|
|
|
19828
20175
|
// src/commands/link.ts
|
|
19829
20176
|
var DEDUP_THRESHOLD = 0.6;
|
|
19830
20177
|
async function mergeLocalKnowledgeIntoLink(localSwarmDir, linkDir) {
|
|
19831
|
-
const localPath =
|
|
19832
|
-
const sharedPath =
|
|
19833
|
-
if (!
|
|
20178
|
+
const localPath = path41.join(localSwarmDir, "knowledge.jsonl");
|
|
20179
|
+
const sharedPath = path41.join(linkDir, "knowledge.jsonl");
|
|
20180
|
+
if (!existsSync24(localPath))
|
|
19834
20181
|
return { merged: 0, skipped: 0 };
|
|
19835
20182
|
let merged = 0;
|
|
19836
20183
|
let skipped = 0;
|
|
19837
|
-
const { readFileSync:
|
|
20184
|
+
const { readFileSync: readFileSync16 } = await import("fs");
|
|
19838
20185
|
let changed = false;
|
|
19839
20186
|
await transactKnowledge(sharedPath, (sharedEntries) => {
|
|
19840
20187
|
const localEntries = [];
|
|
19841
20188
|
try {
|
|
19842
|
-
const content =
|
|
20189
|
+
const content = readFileSync16(localPath, "utf-8");
|
|
19843
20190
|
for (const line of content.split(`
|
|
19844
20191
|
`)) {
|
|
19845
20192
|
if (line.trim()) {
|
|
@@ -19927,7 +20274,7 @@ ${formatStatus(directory)}`;
|
|
|
19927
20274
|
const linkDir = resolveLinkDir(linkId);
|
|
19928
20275
|
let merge;
|
|
19929
20276
|
try {
|
|
19930
|
-
merge = await mergeLocalKnowledgeIntoLink(
|
|
20277
|
+
merge = await mergeLocalKnowledgeIntoLink(path41.join(directory, ".swarm"), linkDir);
|
|
19931
20278
|
} catch (error2) {
|
|
19932
20279
|
return `\u274C Failed to merge local knowledge into the link store: ${error2 instanceof Error ? error2.message : String(error2)}`;
|
|
19933
20280
|
}
|
|
@@ -20071,8 +20418,8 @@ ${USAGE7}`;
|
|
|
20071
20418
|
}
|
|
20072
20419
|
|
|
20073
20420
|
// src/commands/memory.ts
|
|
20074
|
-
import { existsSync as
|
|
20075
|
-
import * as
|
|
20421
|
+
import { existsSync as existsSync27 } from "fs";
|
|
20422
|
+
import * as path48 from "path";
|
|
20076
20423
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
20077
20424
|
|
|
20078
20425
|
// src/memory/config.ts
|
|
@@ -20212,13 +20559,13 @@ class MemoryValidationError extends Error {
|
|
|
20212
20559
|
}
|
|
20213
20560
|
}
|
|
20214
20561
|
// src/memory/evaluation.ts
|
|
20215
|
-
import * as
|
|
20216
|
-
import * as
|
|
20217
|
-
import * as
|
|
20562
|
+
import * as fs19 from "fs/promises";
|
|
20563
|
+
import * as os10 from "os";
|
|
20564
|
+
import * as path46 from "path";
|
|
20218
20565
|
|
|
20219
20566
|
// src/memory/local-jsonl-provider.ts
|
|
20220
20567
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
20221
|
-
import { existsSync as
|
|
20568
|
+
import { existsSync as existsSync25 } from "fs";
|
|
20222
20569
|
import {
|
|
20223
20570
|
appendFile as appendFile3,
|
|
20224
20571
|
mkdir as mkdir10,
|
|
@@ -20226,7 +20573,7 @@ import {
|
|
|
20226
20573
|
rename as rename5,
|
|
20227
20574
|
writeFile as writeFile10
|
|
20228
20575
|
} from "fs/promises";
|
|
20229
|
-
import * as
|
|
20576
|
+
import * as path42 from "path";
|
|
20230
20577
|
|
|
20231
20578
|
// src/memory/schema.ts
|
|
20232
20579
|
import { createHash as createHash5 } from "crypto";
|
|
@@ -21087,7 +21434,7 @@ class LocalJsonlMemoryProvider {
|
|
|
21087
21434
|
pathFor(file) {
|
|
21088
21435
|
const storageDir = this.config.storageDir.replace(/^\.swarm[/\\]?/, "");
|
|
21089
21436
|
const filename = file === "memories" ? "memories.jsonl" : file === "proposals" ? "proposals.jsonl" : "audit.jsonl";
|
|
21090
|
-
return validateSwarmPath(this.rootDirectory,
|
|
21437
|
+
return validateSwarmPath(this.rootDirectory, path42.join(storageDir, filename));
|
|
21091
21438
|
}
|
|
21092
21439
|
async initialize() {
|
|
21093
21440
|
if (this.initialized)
|
|
@@ -21414,7 +21761,7 @@ function validateLoadedProposals(values, config) {
|
|
|
21414
21761
|
return { records, invalidCount };
|
|
21415
21762
|
}
|
|
21416
21763
|
async function readJsonl(filePath) {
|
|
21417
|
-
if (!
|
|
21764
|
+
if (!existsSync25(filePath))
|
|
21418
21765
|
return [];
|
|
21419
21766
|
const content = await readFile12(filePath, "utf-8");
|
|
21420
21767
|
const records = [];
|
|
@@ -21470,12 +21817,12 @@ function parseRecallUsageEvent(event) {
|
|
|
21470
21817
|
}
|
|
21471
21818
|
}
|
|
21472
21819
|
async function appendJsonl(filePath, value) {
|
|
21473
|
-
await mkdir10(
|
|
21820
|
+
await mkdir10(path42.dirname(filePath), { recursive: true });
|
|
21474
21821
|
await appendFile3(filePath, `${JSON.stringify(value)}
|
|
21475
21822
|
`, "utf-8");
|
|
21476
21823
|
}
|
|
21477
21824
|
async function writeJsonlAtomic(filePath, values) {
|
|
21478
|
-
await mkdir10(
|
|
21825
|
+
await mkdir10(path42.dirname(filePath), { recursive: true });
|
|
21479
21826
|
const tmp = `${filePath}.tmp.${randomUUID5()}`;
|
|
21480
21827
|
const content = values.map((value) => JSON.stringify(value)).join(`
|
|
21481
21828
|
`) + (values.length > 0 ? `
|
|
@@ -21486,18 +21833,18 @@ async function writeJsonlAtomic(filePath, values) {
|
|
|
21486
21833
|
|
|
21487
21834
|
// src/memory/provider-pool.ts
|
|
21488
21835
|
import { realpathSync as realpathSync2 } from "fs";
|
|
21489
|
-
import * as
|
|
21836
|
+
import * as path45 from "path";
|
|
21490
21837
|
|
|
21491
21838
|
// src/memory/sqlite-provider.ts
|
|
21492
21839
|
import { randomUUID as randomUUID6 } from "crypto";
|
|
21493
21840
|
import { mkdirSync as mkdirSync15 } from "fs";
|
|
21494
21841
|
import { createRequire as createRequire2 } from "module";
|
|
21495
|
-
import * as
|
|
21842
|
+
import * as path44 from "path";
|
|
21496
21843
|
|
|
21497
21844
|
// src/memory/jsonl-migration.ts
|
|
21498
|
-
import { existsSync as
|
|
21845
|
+
import { existsSync as existsSync26, renameSync as renameSync10, unlinkSync as unlinkSync7 } from "fs";
|
|
21499
21846
|
import { copyFile as copyFile2, mkdir as mkdir11, readFile as readFile13, stat as stat5, writeFile as writeFile11 } from "fs/promises";
|
|
21500
|
-
import * as
|
|
21847
|
+
import * as path43 from "path";
|
|
21501
21848
|
var LEGACY_JSONL_MIGRATION_VERSION = 2;
|
|
21502
21849
|
var LEGACY_JSONL_MIGRATION_NAME = "legacy_jsonl_import_complete";
|
|
21503
21850
|
function resolveMemoryStorageDir(rootDirectory, config = {}) {
|
|
@@ -21513,8 +21860,8 @@ function resolveSqliteDatabasePath(rootDirectory, config = {}) {
|
|
|
21513
21860
|
async function readLegacyJsonl(rootDirectory, config = {}) {
|
|
21514
21861
|
const resolved = resolveConfig(config);
|
|
21515
21862
|
const storageDir = resolveMemoryStorageDir(rootDirectory, resolved);
|
|
21516
|
-
const memoryLoad = await readMemoryJsonl(
|
|
21517
|
-
const proposalLoad = await readProposalJsonl(
|
|
21863
|
+
const memoryLoad = await readMemoryJsonl(path43.join(storageDir, "memories.jsonl"), resolved);
|
|
21864
|
+
const proposalLoad = await readProposalJsonl(path43.join(storageDir, "proposals.jsonl"), resolved);
|
|
21518
21865
|
return {
|
|
21519
21866
|
memories: memoryLoad.records,
|
|
21520
21867
|
proposals: proposalLoad.records,
|
|
@@ -21524,15 +21871,15 @@ async function readLegacyJsonl(rootDirectory, config = {}) {
|
|
|
21524
21871
|
}
|
|
21525
21872
|
async function backupLegacyJsonl(rootDirectory, config = {}) {
|
|
21526
21873
|
const storageDir = resolveMemoryStorageDir(rootDirectory, config);
|
|
21527
|
-
const backupDir =
|
|
21874
|
+
const backupDir = path43.join(storageDir, "backups");
|
|
21528
21875
|
await mkdir11(backupDir, { recursive: true });
|
|
21529
21876
|
const results = [];
|
|
21530
21877
|
for (const filename of ["memories.jsonl", "proposals.jsonl"]) {
|
|
21531
|
-
const source =
|
|
21532
|
-
if (!
|
|
21878
|
+
const source = path43.join(storageDir, filename);
|
|
21879
|
+
if (!existsSync26(source))
|
|
21533
21880
|
continue;
|
|
21534
|
-
const backup =
|
|
21535
|
-
if (
|
|
21881
|
+
const backup = path43.join(backupDir, `${filename}.pre-sqlite-migration`);
|
|
21882
|
+
if (existsSync26(backup)) {
|
|
21536
21883
|
results.push({ source, backup, created: false });
|
|
21537
21884
|
continue;
|
|
21538
21885
|
}
|
|
@@ -21542,51 +21889,51 @@ async function backupLegacyJsonl(rootDirectory, config = {}) {
|
|
|
21542
21889
|
return results;
|
|
21543
21890
|
}
|
|
21544
21891
|
async function writeJsonlExport(rootDirectory, config, memories, proposals) {
|
|
21545
|
-
const exportDir =
|
|
21892
|
+
const exportDir = path43.join(resolveMemoryStorageDir(rootDirectory, config), "export");
|
|
21546
21893
|
await mkdir11(exportDir, { recursive: true });
|
|
21547
|
-
const memoriesPath =
|
|
21548
|
-
const proposalsPath =
|
|
21549
|
-
const memoriesTempPath =
|
|
21894
|
+
const memoriesPath = path43.join(exportDir, "memories.jsonl");
|
|
21895
|
+
const proposalsPath = path43.join(exportDir, "proposals.jsonl");
|
|
21896
|
+
const memoriesTempPath = path43.join(path43.dirname(memoriesPath), `${path43.basename(memoriesPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
|
|
21550
21897
|
try {
|
|
21551
21898
|
await writeFile11(memoriesTempPath, toJsonl(memories), "utf-8");
|
|
21552
21899
|
renameSync10(memoriesTempPath, memoriesPath);
|
|
21553
21900
|
} catch (err) {
|
|
21554
21901
|
try {
|
|
21555
|
-
|
|
21902
|
+
unlinkSync7(memoriesTempPath);
|
|
21556
21903
|
} catch {}
|
|
21557
21904
|
throw err;
|
|
21558
21905
|
}
|
|
21559
|
-
const proposalsTempPath =
|
|
21906
|
+
const proposalsTempPath = path43.join(path43.dirname(proposalsPath), `${path43.basename(proposalsPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
|
|
21560
21907
|
try {
|
|
21561
21908
|
await writeFile11(proposalsTempPath, toJsonl(proposals), "utf-8");
|
|
21562
21909
|
renameSync10(proposalsTempPath, proposalsPath);
|
|
21563
21910
|
} catch (err) {
|
|
21564
21911
|
try {
|
|
21565
|
-
|
|
21912
|
+
unlinkSync7(proposalsTempPath);
|
|
21566
21913
|
} catch {}
|
|
21567
21914
|
throw err;
|
|
21568
21915
|
}
|
|
21569
21916
|
return { directory: exportDir, memoriesPath, proposalsPath };
|
|
21570
21917
|
}
|
|
21571
21918
|
async function writeMigrationReport(rootDirectory, report, config = {}) {
|
|
21572
|
-
const reportPath =
|
|
21573
|
-
await mkdir11(
|
|
21574
|
-
const reportTempPath =
|
|
21919
|
+
const reportPath = path43.join(resolveMemoryStorageDir(rootDirectory, config), "migration-report.json");
|
|
21920
|
+
await mkdir11(path43.dirname(reportPath), { recursive: true });
|
|
21921
|
+
const reportTempPath = path43.join(path43.dirname(reportPath), `${path43.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
|
|
21575
21922
|
try {
|
|
21576
21923
|
await writeFile11(reportTempPath, `${JSON.stringify(report, null, 2)}
|
|
21577
21924
|
`, "utf-8");
|
|
21578
21925
|
renameSync10(reportTempPath, reportPath);
|
|
21579
21926
|
} catch (err) {
|
|
21580
21927
|
try {
|
|
21581
|
-
|
|
21928
|
+
unlinkSync7(reportTempPath);
|
|
21582
21929
|
} catch {}
|
|
21583
21930
|
throw err;
|
|
21584
21931
|
}
|
|
21585
21932
|
return reportPath;
|
|
21586
21933
|
}
|
|
21587
21934
|
async function readMigrationReport(rootDirectory, config = {}) {
|
|
21588
|
-
const reportPath =
|
|
21589
|
-
if (!
|
|
21935
|
+
const reportPath = path43.join(resolveMemoryStorageDir(rootDirectory, config), "migration-report.json");
|
|
21936
|
+
if (!existsSync26(reportPath))
|
|
21590
21937
|
return null;
|
|
21591
21938
|
try {
|
|
21592
21939
|
return JSON.parse(await readFile13(reportPath, "utf-8"));
|
|
@@ -21598,15 +21945,15 @@ async function getLegacyJsonlFileStatus(rootDirectory, config = {}) {
|
|
|
21598
21945
|
const storageDir = resolveMemoryStorageDir(rootDirectory, config);
|
|
21599
21946
|
const statuses = [];
|
|
21600
21947
|
for (const file of ["memories.jsonl", "proposals.jsonl"]) {
|
|
21601
|
-
const filePath =
|
|
21948
|
+
const filePath = path43.join(storageDir, file);
|
|
21602
21949
|
let sizeBytes = 0;
|
|
21603
|
-
if (
|
|
21950
|
+
if (existsSync26(filePath)) {
|
|
21604
21951
|
sizeBytes = (await stat5(filePath)).size;
|
|
21605
21952
|
}
|
|
21606
21953
|
statuses.push({
|
|
21607
21954
|
file,
|
|
21608
21955
|
path: filePath,
|
|
21609
|
-
exists:
|
|
21956
|
+
exists: existsSync26(filePath),
|
|
21610
21957
|
sizeBytes
|
|
21611
21958
|
});
|
|
21612
21959
|
}
|
|
@@ -21687,7 +22034,7 @@ async function readProposalJsonl(filePath, config) {
|
|
|
21687
22034
|
return { records, invalidRows, totalRows: rows.totalRows };
|
|
21688
22035
|
}
|
|
21689
22036
|
async function readJsonlRows(filePath) {
|
|
21690
|
-
if (!
|
|
22037
|
+
if (!existsSync26(filePath)) {
|
|
21691
22038
|
return { rows: [], invalidRows: [], totalRows: 0 };
|
|
21692
22039
|
}
|
|
21693
22040
|
const content = await readFile13(filePath, "utf-8");
|
|
@@ -21906,7 +22253,7 @@ class SQLiteMemoryProvider {
|
|
|
21906
22253
|
}
|
|
21907
22254
|
async doInitialize() {
|
|
21908
22255
|
const dbPath = this.databasePath();
|
|
21909
|
-
mkdirSync15(
|
|
22256
|
+
mkdirSync15(path44.dirname(dbPath), { recursive: true });
|
|
21910
22257
|
const Db = loadDatabaseCtor2();
|
|
21911
22258
|
this.db = new Db(dbPath);
|
|
21912
22259
|
this.db.run("PRAGMA journal_mode = WAL;");
|
|
@@ -22935,7 +23282,7 @@ function resolvePoolKey(directory) {
|
|
|
22935
23282
|
try {
|
|
22936
23283
|
return realpathSync2(directory);
|
|
22937
23284
|
} catch {
|
|
22938
|
-
return
|
|
23285
|
+
return path45.resolve(directory);
|
|
22939
23286
|
}
|
|
22940
23287
|
}
|
|
22941
23288
|
|
|
@@ -23007,7 +23354,7 @@ var DEFAULT_MODES = [
|
|
|
23007
23354
|
];
|
|
23008
23355
|
var DEFAULT_TIMESTAMP = "2026-05-26T12:00:00.000Z";
|
|
23009
23356
|
async function evaluateMemoryRecallFixtures(options) {
|
|
23010
|
-
const fixtureDirectory =
|
|
23357
|
+
const fixtureDirectory = path46.resolve(options.fixtureDirectory);
|
|
23011
23358
|
const providers = options.providers ?? DEFAULT_PROVIDERS;
|
|
23012
23359
|
const modes = options.modes ?? DEFAULT_MODES;
|
|
23013
23360
|
const generatedAt = new Date().toISOString();
|
|
@@ -23016,7 +23363,7 @@ async function evaluateMemoryRecallFixtures(options) {
|
|
|
23016
23363
|
for (const fixture of fixtures) {
|
|
23017
23364
|
const materialized = materializeFixture(fixture);
|
|
23018
23365
|
for (const providerName of providers) {
|
|
23019
|
-
const tempRoot = await
|
|
23366
|
+
const tempRoot = await fs19.realpath(await fs19.mkdtemp(path46.join(os10.tmpdir(), "swarm-memory-eval-")));
|
|
23020
23367
|
const provider = createEvaluationProvider(providerName, tempRoot);
|
|
23021
23368
|
try {
|
|
23022
23369
|
await provider.initialize?.();
|
|
@@ -23040,7 +23387,7 @@ async function evaluateMemoryRecallFixtures(options) {
|
|
|
23040
23387
|
} finally {
|
|
23041
23388
|
await provider.close?.();
|
|
23042
23389
|
if (!options.keepTempRoots) {
|
|
23043
|
-
await
|
|
23390
|
+
await fs19.rm(tempRoot, { recursive: true, force: true });
|
|
23044
23391
|
}
|
|
23045
23392
|
}
|
|
23046
23393
|
}
|
|
@@ -23056,11 +23403,11 @@ async function evaluateMemoryRecallFixtures(options) {
|
|
|
23056
23403
|
};
|
|
23057
23404
|
}
|
|
23058
23405
|
async function loadRecallEvaluationFixtures(fixtureDirectory) {
|
|
23059
|
-
const entries = await
|
|
23406
|
+
const entries = await fs19.readdir(fixtureDirectory, { withFileTypes: true });
|
|
23060
23407
|
const files = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort((a, b) => a.localeCompare(b));
|
|
23061
23408
|
const fixtures = [];
|
|
23062
23409
|
for (const file of files) {
|
|
23063
|
-
const raw = await
|
|
23410
|
+
const raw = await fs19.readFile(path46.join(fixtureDirectory, file), "utf-8");
|
|
23064
23411
|
fixtures.push(validateFixture(JSON.parse(raw), file));
|
|
23065
23412
|
}
|
|
23066
23413
|
return fixtures;
|
|
@@ -23337,8 +23684,8 @@ var CuratorOutputMemoryDecisionSchema = exports_external.object({
|
|
|
23337
23684
|
}).passthrough();
|
|
23338
23685
|
// src/memory/consolidation-log.ts
|
|
23339
23686
|
import { appendFile as appendFile4, mkdir as mkdir12, readFile as readFile15 } from "fs/promises";
|
|
23340
|
-
import * as
|
|
23341
|
-
var LOG_RELATIVE_PATH =
|
|
23687
|
+
import * as path47 from "path";
|
|
23688
|
+
var LOG_RELATIVE_PATH = path47.join("memory", "consolidation-log.jsonl");
|
|
23342
23689
|
async function readConsolidationLog(directory) {
|
|
23343
23690
|
const filePath = validateSwarmPath(directory, LOG_RELATIVE_PATH);
|
|
23344
23691
|
let raw;
|
|
@@ -23361,7 +23708,7 @@ async function readConsolidationLog(directory) {
|
|
|
23361
23708
|
}
|
|
23362
23709
|
|
|
23363
23710
|
// src/commands/memory.ts
|
|
23364
|
-
var PACKAGE_ROOT =
|
|
23711
|
+
var PACKAGE_ROOT = path48.resolve(resolvePackageRootFromModule(fileURLToPath2(import.meta.url)));
|
|
23365
23712
|
async function handleMemoryCommand(_directory, _args) {
|
|
23366
23713
|
return [
|
|
23367
23714
|
"## Swarm Memory",
|
|
@@ -23419,7 +23766,7 @@ async function handleMemoryStatusCommand(directory, _args) {
|
|
|
23419
23766
|
`- Provider: \`${config.provider}\``,
|
|
23420
23767
|
`- Storage: \`${storageDir}\``,
|
|
23421
23768
|
`- SQLite path: \`${sqlitePath}\``,
|
|
23422
|
-
`- SQLite database exists: \`${
|
|
23769
|
+
`- SQLite database exists: \`${existsSync27(sqlitePath)}\``,
|
|
23423
23770
|
`- Automatic destructive cleanup: \`disabled\``,
|
|
23424
23771
|
"",
|
|
23425
23772
|
"### Legacy JSONL"
|
|
@@ -23659,7 +24006,7 @@ function resolveCommandMemoryConfig(directory) {
|
|
|
23659
24006
|
}
|
|
23660
24007
|
function parseEvaluateArgs(directory, args) {
|
|
23661
24008
|
let json = false;
|
|
23662
|
-
let fixtureDirectory =
|
|
24009
|
+
let fixtureDirectory = path48.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall");
|
|
23663
24010
|
for (let i = 0;i < args.length; i++) {
|
|
23664
24011
|
const arg = args[i];
|
|
23665
24012
|
if (arg === "--json") {
|
|
@@ -23673,10 +24020,10 @@ function parseEvaluateArgs(directory, args) {
|
|
|
23673
24020
|
error: "Usage: /swarm memory evaluate [--json] [--fixtures <directory>]"
|
|
23674
24021
|
};
|
|
23675
24022
|
}
|
|
23676
|
-
const resolvedFixtures =
|
|
23677
|
-
const canonical =
|
|
23678
|
-
const allowedRootA =
|
|
23679
|
-
const allowedRootB =
|
|
24023
|
+
const resolvedFixtures = path48.resolve(directory, next);
|
|
24024
|
+
const canonical = path48.normalize(resolvedFixtures) + path48.sep;
|
|
24025
|
+
const allowedRootA = path48.normalize(directory) + path48.sep;
|
|
24026
|
+
const allowedRootB = path48.normalize(path48.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall")) + path48.sep;
|
|
23680
24027
|
if (!canonical.startsWith(allowedRootA) && !canonical.startsWith(allowedRootB)) {
|
|
23681
24028
|
return {
|
|
23682
24029
|
error: "--fixtures <directory> must resolve under the project directory or the bundled tests/fixtures/memory-recall directory"
|
|
@@ -23715,15 +24062,15 @@ function parseMaintenanceArgs(args, options) {
|
|
|
23715
24062
|
return { limit, confirm };
|
|
23716
24063
|
}
|
|
23717
24064
|
function resolvePackageRootFromModule(modulePath) {
|
|
23718
|
-
const moduleDir =
|
|
23719
|
-
const leaf =
|
|
24065
|
+
const moduleDir = path48.dirname(modulePath);
|
|
24066
|
+
const leaf = path48.basename(moduleDir);
|
|
23720
24067
|
if (leaf === "commands" || leaf === "cli") {
|
|
23721
|
-
return
|
|
24068
|
+
return path48.resolve(moduleDir, "..", "..");
|
|
23722
24069
|
}
|
|
23723
24070
|
if (leaf === "dist") {
|
|
23724
|
-
return
|
|
24071
|
+
return path48.resolve(moduleDir, "..");
|
|
23725
24072
|
}
|
|
23726
|
-
return
|
|
24073
|
+
return path48.resolve(moduleDir, "..");
|
|
23727
24074
|
}
|
|
23728
24075
|
function formatMigrationResult(label, report) {
|
|
23729
24076
|
if (!report) {
|
|
@@ -24417,12 +24764,12 @@ var _internals36 = {
|
|
|
24417
24764
|
};
|
|
24418
24765
|
|
|
24419
24766
|
// src/services/preflight-service.ts
|
|
24420
|
-
import * as
|
|
24421
|
-
import * as
|
|
24767
|
+
import * as fs26 from "fs";
|
|
24768
|
+
import * as path55 from "path";
|
|
24422
24769
|
|
|
24423
24770
|
// src/tools/lint.ts
|
|
24424
|
-
import * as
|
|
24425
|
-
import * as
|
|
24771
|
+
import * as fs20 from "fs";
|
|
24772
|
+
import * as path49 from "path";
|
|
24426
24773
|
|
|
24427
24774
|
// src/utils/path-security.ts
|
|
24428
24775
|
function containsPathTraversal(str) {
|
|
@@ -24478,9 +24825,9 @@ function validateArgs(args) {
|
|
|
24478
24825
|
}
|
|
24479
24826
|
function getLinterCommand(linter, mode, projectDir) {
|
|
24480
24827
|
const isWindows = process.platform === "win32";
|
|
24481
|
-
const binDir =
|
|
24482
|
-
const biomeBin = isWindows ?
|
|
24483
|
-
const eslintBin = isWindows ?
|
|
24828
|
+
const binDir = path49.join(projectDir, "node_modules", ".bin");
|
|
24829
|
+
const biomeBin = isWindows ? path49.join(binDir, "biome.EXE") : path49.join(binDir, "biome");
|
|
24830
|
+
const eslintBin = isWindows ? path49.join(binDir, "eslint.cmd") : path49.join(binDir, "eslint");
|
|
24484
24831
|
switch (linter) {
|
|
24485
24832
|
case "biome":
|
|
24486
24833
|
if (mode === "fix") {
|
|
@@ -24496,7 +24843,7 @@ function getLinterCommand(linter, mode, projectDir) {
|
|
|
24496
24843
|
}
|
|
24497
24844
|
function getAdditionalLinterCommand(linter, mode, cwd) {
|
|
24498
24845
|
const gradlewName = process.platform === "win32" ? "gradlew.bat" : "gradlew";
|
|
24499
|
-
const gradlew =
|
|
24846
|
+
const gradlew = fs20.existsSync(path49.join(cwd, gradlewName)) ? path49.join(cwd, gradlewName) : null;
|
|
24500
24847
|
switch (linter) {
|
|
24501
24848
|
case "ruff":
|
|
24502
24849
|
return mode === "fix" ? ["ruff", "check", "--fix", "."] : ["ruff", "check", "."];
|
|
@@ -24530,12 +24877,12 @@ function getAdditionalLinterCommand(linter, mode, cwd) {
|
|
|
24530
24877
|
}
|
|
24531
24878
|
}
|
|
24532
24879
|
function detectRuff(cwd) {
|
|
24533
|
-
if (
|
|
24880
|
+
if (fs20.existsSync(path49.join(cwd, "ruff.toml")))
|
|
24534
24881
|
return isCommandAvailable("ruff");
|
|
24535
24882
|
try {
|
|
24536
|
-
const pyproject =
|
|
24537
|
-
if (
|
|
24538
|
-
const content =
|
|
24883
|
+
const pyproject = path49.join(cwd, "pyproject.toml");
|
|
24884
|
+
if (fs20.existsSync(pyproject)) {
|
|
24885
|
+
const content = fs20.readFileSync(pyproject, "utf-8");
|
|
24539
24886
|
if (content.includes("[tool.ruff]"))
|
|
24540
24887
|
return isCommandAvailable("ruff");
|
|
24541
24888
|
}
|
|
@@ -24543,21 +24890,21 @@ function detectRuff(cwd) {
|
|
|
24543
24890
|
return false;
|
|
24544
24891
|
}
|
|
24545
24892
|
function detectClippy(cwd) {
|
|
24546
|
-
return
|
|
24893
|
+
return fs20.existsSync(path49.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
|
|
24547
24894
|
}
|
|
24548
24895
|
function detectGolangciLint(cwd) {
|
|
24549
|
-
return
|
|
24896
|
+
return fs20.existsSync(path49.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
|
|
24550
24897
|
}
|
|
24551
24898
|
function detectCheckstyle(cwd) {
|
|
24552
|
-
const hasMaven =
|
|
24553
|
-
const hasGradle =
|
|
24554
|
-
const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (
|
|
24899
|
+
const hasMaven = fs20.existsSync(path49.join(cwd, "pom.xml"));
|
|
24900
|
+
const hasGradle = fs20.existsSync(path49.join(cwd, "build.gradle")) || fs20.existsSync(path49.join(cwd, "build.gradle.kts"));
|
|
24901
|
+
const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs20.existsSync(path49.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
|
|
24555
24902
|
return (hasMaven || hasGradle) && hasBinary;
|
|
24556
24903
|
}
|
|
24557
24904
|
function detectKtlint(cwd) {
|
|
24558
|
-
const hasKotlin =
|
|
24905
|
+
const hasKotlin = fs20.existsSync(path49.join(cwd, "build.gradle.kts")) || fs20.existsSync(path49.join(cwd, "build.gradle")) || (() => {
|
|
24559
24906
|
try {
|
|
24560
|
-
return
|
|
24907
|
+
return fs20.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
|
|
24561
24908
|
} catch {
|
|
24562
24909
|
return false;
|
|
24563
24910
|
}
|
|
@@ -24566,7 +24913,7 @@ function detectKtlint(cwd) {
|
|
|
24566
24913
|
}
|
|
24567
24914
|
function detectDotnetFormat(cwd) {
|
|
24568
24915
|
try {
|
|
24569
|
-
const files =
|
|
24916
|
+
const files = fs20.readdirSync(cwd);
|
|
24570
24917
|
const hasCsproj = files.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"));
|
|
24571
24918
|
return hasCsproj && isCommandAvailable("dotnet");
|
|
24572
24919
|
} catch {
|
|
@@ -24574,14 +24921,14 @@ function detectDotnetFormat(cwd) {
|
|
|
24574
24921
|
}
|
|
24575
24922
|
}
|
|
24576
24923
|
function detectCppcheck(cwd) {
|
|
24577
|
-
if (
|
|
24924
|
+
if (fs20.existsSync(path49.join(cwd, "CMakeLists.txt"))) {
|
|
24578
24925
|
return isCommandAvailable("cppcheck");
|
|
24579
24926
|
}
|
|
24580
24927
|
try {
|
|
24581
|
-
const dirsToCheck = [cwd,
|
|
24928
|
+
const dirsToCheck = [cwd, path49.join(cwd, "src")];
|
|
24582
24929
|
const hasCpp = dirsToCheck.some((dir) => {
|
|
24583
24930
|
try {
|
|
24584
|
-
return
|
|
24931
|
+
return fs20.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
|
|
24585
24932
|
} catch {
|
|
24586
24933
|
return false;
|
|
24587
24934
|
}
|
|
@@ -24592,13 +24939,13 @@ function detectCppcheck(cwd) {
|
|
|
24592
24939
|
}
|
|
24593
24940
|
}
|
|
24594
24941
|
function detectSwiftlint(cwd) {
|
|
24595
|
-
return
|
|
24942
|
+
return fs20.existsSync(path49.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
|
|
24596
24943
|
}
|
|
24597
24944
|
function detectDartAnalyze(cwd) {
|
|
24598
|
-
return
|
|
24945
|
+
return fs20.existsSync(path49.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
|
|
24599
24946
|
}
|
|
24600
24947
|
function detectRubocop(cwd) {
|
|
24601
|
-
return (
|
|
24948
|
+
return (fs20.existsSync(path49.join(cwd, "Gemfile")) || fs20.existsSync(path49.join(cwd, "gems.rb")) || fs20.existsSync(path49.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
|
|
24602
24949
|
}
|
|
24603
24950
|
function detectAdditionalLinter(cwd) {
|
|
24604
24951
|
if (detectRuff(cwd))
|
|
@@ -24626,10 +24973,10 @@ function detectAdditionalLinter(cwd) {
|
|
|
24626
24973
|
function findBinInAncestors(startDir, binName) {
|
|
24627
24974
|
let dir = startDir;
|
|
24628
24975
|
while (true) {
|
|
24629
|
-
const candidate =
|
|
24630
|
-
if (
|
|
24976
|
+
const candidate = path49.join(dir, "node_modules", ".bin", binName);
|
|
24977
|
+
if (fs20.existsSync(candidate))
|
|
24631
24978
|
return candidate;
|
|
24632
|
-
const parent =
|
|
24979
|
+
const parent = path49.dirname(dir);
|
|
24633
24980
|
if (parent === dir)
|
|
24634
24981
|
break;
|
|
24635
24982
|
dir = parent;
|
|
@@ -24638,11 +24985,11 @@ function findBinInAncestors(startDir, binName) {
|
|
|
24638
24985
|
}
|
|
24639
24986
|
function findBinInEnvPath(binName) {
|
|
24640
24987
|
const searchPath = process.env.PATH ?? "";
|
|
24641
|
-
for (const dir of searchPath.split(
|
|
24988
|
+
for (const dir of searchPath.split(path49.delimiter)) {
|
|
24642
24989
|
if (!dir)
|
|
24643
24990
|
continue;
|
|
24644
|
-
const candidate =
|
|
24645
|
-
if (
|
|
24991
|
+
const candidate = path49.join(dir, binName);
|
|
24992
|
+
if (fs20.existsSync(candidate))
|
|
24646
24993
|
return candidate;
|
|
24647
24994
|
}
|
|
24648
24995
|
return null;
|
|
@@ -24650,17 +24997,17 @@ function findBinInEnvPath(binName) {
|
|
|
24650
24997
|
async function detectAvailableLinter(directory) {
|
|
24651
24998
|
if (!directory)
|
|
24652
24999
|
return null;
|
|
24653
|
-
if (!
|
|
25000
|
+
if (!fs20.existsSync(directory))
|
|
24654
25001
|
return null;
|
|
24655
25002
|
const projectDir = directory;
|
|
24656
25003
|
const isWindows = process.platform === "win32";
|
|
24657
|
-
const biomeBin = isWindows ?
|
|
24658
|
-
const eslintBin = isWindows ?
|
|
25004
|
+
const biomeBin = isWindows ? path49.join(projectDir, "node_modules", ".bin", "biome.EXE") : path49.join(projectDir, "node_modules", ".bin", "biome");
|
|
25005
|
+
const eslintBin = isWindows ? path49.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path49.join(projectDir, "node_modules", ".bin", "eslint");
|
|
24659
25006
|
const localResult = await _detectAvailableLinter(projectDir, biomeBin, eslintBin);
|
|
24660
25007
|
if (localResult)
|
|
24661
25008
|
return localResult;
|
|
24662
|
-
const biomeAncestor = findBinInAncestors(
|
|
24663
|
-
const eslintAncestor = findBinInAncestors(
|
|
25009
|
+
const biomeAncestor = findBinInAncestors(path49.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
|
|
25010
|
+
const eslintAncestor = findBinInAncestors(path49.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
|
|
24664
25011
|
if (biomeAncestor || eslintAncestor) {
|
|
24665
25012
|
return _detectAvailableLinter(projectDir, biomeAncestor ?? biomeBin, eslintAncestor ?? eslintBin);
|
|
24666
25013
|
}
|
|
@@ -24683,7 +25030,7 @@ async function _detectAvailableLinter(_projectDir, biomeBin, eslintBin) {
|
|
|
24683
25030
|
const result = await Promise.race([biomeExit, timeout]);
|
|
24684
25031
|
if (result === "timeout") {
|
|
24685
25032
|
biomeProc.kill();
|
|
24686
|
-
} else if (biomeProc.exitCode === 0 &&
|
|
25033
|
+
} else if (biomeProc.exitCode === 0 && fs20.existsSync(biomeBin)) {
|
|
24687
25034
|
return "biome";
|
|
24688
25035
|
}
|
|
24689
25036
|
} catch {}
|
|
@@ -24697,7 +25044,7 @@ async function _detectAvailableLinter(_projectDir, biomeBin, eslintBin) {
|
|
|
24697
25044
|
const result = await Promise.race([eslintExit, timeout]);
|
|
24698
25045
|
if (result === "timeout") {
|
|
24699
25046
|
eslintProc.kill();
|
|
24700
|
-
} else if (eslintProc.exitCode === 0 &&
|
|
25047
|
+
} else if (eslintProc.exitCode === 0 && fs20.existsSync(eslintBin)) {
|
|
24701
25048
|
return "eslint";
|
|
24702
25049
|
}
|
|
24703
25050
|
} catch {}
|
|
@@ -24873,8 +25220,8 @@ var _internals37 = {
|
|
|
24873
25220
|
};
|
|
24874
25221
|
|
|
24875
25222
|
// src/tools/secretscan.ts
|
|
24876
|
-
import * as
|
|
24877
|
-
import * as
|
|
25223
|
+
import * as fs21 from "fs";
|
|
25224
|
+
import * as path50 from "path";
|
|
24878
25225
|
var MAX_FILE_PATH_LENGTH = 500;
|
|
24879
25226
|
var MAX_FILE_SIZE_BYTES = 512 * 1024;
|
|
24880
25227
|
var MAX_FILES_SCANNED = 1000;
|
|
@@ -25101,11 +25448,11 @@ function isGlobOrPathPattern(pattern) {
|
|
|
25101
25448
|
return pattern.includes("/") || pattern.includes("\\") || /[*?[\]{}]/.test(pattern);
|
|
25102
25449
|
}
|
|
25103
25450
|
function loadSecretScanIgnore(scanDir) {
|
|
25104
|
-
const ignorePath =
|
|
25451
|
+
const ignorePath = path50.join(scanDir, ".secretscanignore");
|
|
25105
25452
|
try {
|
|
25106
|
-
if (!
|
|
25453
|
+
if (!fs21.existsSync(ignorePath))
|
|
25107
25454
|
return [];
|
|
25108
|
-
const content =
|
|
25455
|
+
const content = fs21.readFileSync(ignorePath, "utf8");
|
|
25109
25456
|
const patterns = [];
|
|
25110
25457
|
for (const rawLine of content.split(/\r?\n/)) {
|
|
25111
25458
|
const line = rawLine.trim();
|
|
@@ -25124,7 +25471,7 @@ function isExcluded(entry, relPath, exactNames, globPatterns) {
|
|
|
25124
25471
|
if (exactNames.has(entry))
|
|
25125
25472
|
return true;
|
|
25126
25473
|
for (const pattern of globPatterns) {
|
|
25127
|
-
if (
|
|
25474
|
+
if (path50.matchesGlob(relPath, pattern))
|
|
25128
25475
|
return true;
|
|
25129
25476
|
}
|
|
25130
25477
|
return false;
|
|
@@ -25145,7 +25492,7 @@ function validateDirectoryInput(dir) {
|
|
|
25145
25492
|
return null;
|
|
25146
25493
|
}
|
|
25147
25494
|
function isBinaryFile(filePath, buffer) {
|
|
25148
|
-
const ext =
|
|
25495
|
+
const ext = path50.extname(filePath).toLowerCase();
|
|
25149
25496
|
if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
|
|
25150
25497
|
return true;
|
|
25151
25498
|
}
|
|
@@ -25220,11 +25567,11 @@ function createRedactedContext(line, findings) {
|
|
|
25220
25567
|
result += line.slice(lastEnd);
|
|
25221
25568
|
return result;
|
|
25222
25569
|
}
|
|
25223
|
-
var O_NOFOLLOW = process.platform !== "win32" ?
|
|
25570
|
+
var O_NOFOLLOW = process.platform !== "win32" ? fs21.constants.O_NOFOLLOW : undefined;
|
|
25224
25571
|
function scanFileForSecrets(filePath) {
|
|
25225
25572
|
const findings = [];
|
|
25226
25573
|
try {
|
|
25227
|
-
const lstat2 =
|
|
25574
|
+
const lstat2 = fs21.lstatSync(filePath);
|
|
25228
25575
|
if (lstat2.isSymbolicLink()) {
|
|
25229
25576
|
return findings;
|
|
25230
25577
|
}
|
|
@@ -25233,14 +25580,14 @@ function scanFileForSecrets(filePath) {
|
|
|
25233
25580
|
}
|
|
25234
25581
|
let buffer;
|
|
25235
25582
|
if (O_NOFOLLOW !== undefined) {
|
|
25236
|
-
const fd =
|
|
25583
|
+
const fd = fs21.openSync(filePath, "r", O_NOFOLLOW);
|
|
25237
25584
|
try {
|
|
25238
|
-
buffer =
|
|
25585
|
+
buffer = fs21.readFileSync(fd);
|
|
25239
25586
|
} finally {
|
|
25240
|
-
|
|
25587
|
+
fs21.closeSync(fd);
|
|
25241
25588
|
}
|
|
25242
25589
|
} else {
|
|
25243
|
-
buffer =
|
|
25590
|
+
buffer = fs21.readFileSync(filePath);
|
|
25244
25591
|
}
|
|
25245
25592
|
if (isBinaryFile(filePath, buffer)) {
|
|
25246
25593
|
return findings;
|
|
@@ -25282,9 +25629,9 @@ function isSymlinkLoop(realPath, visited) {
|
|
|
25282
25629
|
return false;
|
|
25283
25630
|
}
|
|
25284
25631
|
function isPathWithinScope(realPath, scanDir) {
|
|
25285
|
-
const resolvedScanDir =
|
|
25286
|
-
const resolvedRealPath =
|
|
25287
|
-
return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir +
|
|
25632
|
+
const resolvedScanDir = path50.resolve(scanDir);
|
|
25633
|
+
const resolvedRealPath = path50.resolve(realPath);
|
|
25634
|
+
return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path50.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
|
|
25288
25635
|
}
|
|
25289
25636
|
function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, stats = {
|
|
25290
25637
|
skippedDirs: 0,
|
|
@@ -25295,7 +25642,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
25295
25642
|
const files = [];
|
|
25296
25643
|
let entries;
|
|
25297
25644
|
try {
|
|
25298
|
-
entries =
|
|
25645
|
+
entries = fs21.readdirSync(dir);
|
|
25299
25646
|
} catch {
|
|
25300
25647
|
stats.fileErrors++;
|
|
25301
25648
|
return files;
|
|
@@ -25310,15 +25657,15 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
25310
25657
|
return a.localeCompare(b);
|
|
25311
25658
|
});
|
|
25312
25659
|
for (const entry of entries) {
|
|
25313
|
-
const fullPath =
|
|
25314
|
-
const relPath =
|
|
25660
|
+
const fullPath = path50.join(dir, entry);
|
|
25661
|
+
const relPath = path50.relative(scanDir, fullPath).replace(/\\/g, "/");
|
|
25315
25662
|
if (isExcluded(entry, relPath, excludeExact, excludeGlobs)) {
|
|
25316
25663
|
stats.skippedDirs++;
|
|
25317
25664
|
continue;
|
|
25318
25665
|
}
|
|
25319
25666
|
let lstat2;
|
|
25320
25667
|
try {
|
|
25321
|
-
lstat2 =
|
|
25668
|
+
lstat2 = fs21.lstatSync(fullPath);
|
|
25322
25669
|
} catch {
|
|
25323
25670
|
stats.fileErrors++;
|
|
25324
25671
|
continue;
|
|
@@ -25330,7 +25677,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
25330
25677
|
if (lstat2.isDirectory()) {
|
|
25331
25678
|
let realPath;
|
|
25332
25679
|
try {
|
|
25333
|
-
realPath =
|
|
25680
|
+
realPath = fs21.realpathSync(fullPath);
|
|
25334
25681
|
} catch {
|
|
25335
25682
|
stats.fileErrors++;
|
|
25336
25683
|
continue;
|
|
@@ -25346,7 +25693,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
25346
25693
|
const subFiles = findScannableFiles(fullPath, excludeExact, excludeGlobs, scanDir, visited, stats);
|
|
25347
25694
|
files.push(...subFiles);
|
|
25348
25695
|
} else if (lstat2.isFile()) {
|
|
25349
|
-
const ext =
|
|
25696
|
+
const ext = path50.extname(fullPath).toLowerCase();
|
|
25350
25697
|
if (!DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
|
|
25351
25698
|
files.push(fullPath);
|
|
25352
25699
|
} else {
|
|
@@ -25412,15 +25759,15 @@ var secretscan = createSwarmTool({
|
|
|
25412
25759
|
}
|
|
25413
25760
|
}
|
|
25414
25761
|
try {
|
|
25415
|
-
const _scanDirRaw =
|
|
25762
|
+
const _scanDirRaw = path50.resolve(directory);
|
|
25416
25763
|
const scanDir = (() => {
|
|
25417
25764
|
try {
|
|
25418
|
-
return
|
|
25765
|
+
return fs21.realpathSync(_scanDirRaw);
|
|
25419
25766
|
} catch {
|
|
25420
25767
|
return _scanDirRaw;
|
|
25421
25768
|
}
|
|
25422
25769
|
})();
|
|
25423
|
-
if (!
|
|
25770
|
+
if (!fs21.existsSync(scanDir)) {
|
|
25424
25771
|
const errorResult = {
|
|
25425
25772
|
error: "directory not found",
|
|
25426
25773
|
scan_dir: directory,
|
|
@@ -25431,7 +25778,7 @@ var secretscan = createSwarmTool({
|
|
|
25431
25778
|
};
|
|
25432
25779
|
return JSON.stringify(errorResult, null, 2);
|
|
25433
25780
|
}
|
|
25434
|
-
const dirStat =
|
|
25781
|
+
const dirStat = fs21.statSync(scanDir);
|
|
25435
25782
|
if (!dirStat.isDirectory()) {
|
|
25436
25783
|
const errorResult = {
|
|
25437
25784
|
error: "target must be a directory, not a file",
|
|
@@ -25482,7 +25829,7 @@ var secretscan = createSwarmTool({
|
|
|
25482
25829
|
break;
|
|
25483
25830
|
const fileFindings = scanFileForSecrets(filePath);
|
|
25484
25831
|
try {
|
|
25485
|
-
const stat6 =
|
|
25832
|
+
const stat6 = fs21.statSync(filePath);
|
|
25486
25833
|
if (stat6.size > MAX_FILE_SIZE_BYTES) {
|
|
25487
25834
|
skippedFiles++;
|
|
25488
25835
|
continue;
|
|
@@ -25574,12 +25921,12 @@ var _internals38 = {
|
|
|
25574
25921
|
};
|
|
25575
25922
|
|
|
25576
25923
|
// src/tools/test-runner.ts
|
|
25577
|
-
import * as
|
|
25578
|
-
import * as
|
|
25924
|
+
import * as fs25 from "fs";
|
|
25925
|
+
import * as path54 from "path";
|
|
25579
25926
|
|
|
25580
25927
|
// src/test-impact/analyzer.ts
|
|
25581
|
-
import
|
|
25582
|
-
import
|
|
25928
|
+
import fs22 from "fs";
|
|
25929
|
+
import path51 from "path";
|
|
25583
25930
|
var IMPORT_REGEX_ES = /import\s+[\s\S]*?\s+from\s+['"]([^'"]+)['"]/g;
|
|
25584
25931
|
var IMPORT_REGEX_REQUIRE = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
25585
25932
|
var IMPORT_REGEX_REEXPORT = /export\s+(?:\{[^}]*\}|\*)\s+from\s+['"]([^'"]+)['"]/g;
|
|
@@ -25606,7 +25953,7 @@ function sharedTrailingSegments(a, b) {
|
|
|
25606
25953
|
function isCacheStale(impactMap, generatedAtMs) {
|
|
25607
25954
|
for (const sourcePath of Object.keys(impactMap)) {
|
|
25608
25955
|
try {
|
|
25609
|
-
const stat6 =
|
|
25956
|
+
const stat6 = fs22.statSync(sourcePath);
|
|
25610
25957
|
if (stat6.mtimeMs > generatedAtMs) {
|
|
25611
25958
|
return true;
|
|
25612
25959
|
}
|
|
@@ -25620,15 +25967,15 @@ function resolveRelativeImport(fromDir, importPath) {
|
|
|
25620
25967
|
if (!importPath.startsWith(".")) {
|
|
25621
25968
|
return null;
|
|
25622
25969
|
}
|
|
25623
|
-
const resolved =
|
|
25624
|
-
if (
|
|
25625
|
-
if (
|
|
25970
|
+
const resolved = path51.resolve(fromDir, importPath);
|
|
25971
|
+
if (path51.extname(resolved)) {
|
|
25972
|
+
if (fs22.existsSync(resolved) && fs22.statSync(resolved).isFile()) {
|
|
25626
25973
|
return normalizePath2(resolved);
|
|
25627
25974
|
}
|
|
25628
25975
|
} else {
|
|
25629
25976
|
for (const ext of EXTENSIONS_TO_TRY) {
|
|
25630
25977
|
const withExt = resolved + ext;
|
|
25631
|
-
if (
|
|
25978
|
+
if (fs22.existsSync(withExt) && fs22.statSync(withExt).isFile()) {
|
|
25632
25979
|
return normalizePath2(withExt);
|
|
25633
25980
|
}
|
|
25634
25981
|
}
|
|
@@ -25641,30 +25988,30 @@ function resolvePythonImport(fromDir, module) {
|
|
|
25641
25988
|
const leadingDots = module.match(/^\.+/)?.[0].length ?? 0;
|
|
25642
25989
|
let baseDir = fromDir;
|
|
25643
25990
|
for (let i = 1;i < leadingDots; i++) {
|
|
25644
|
-
baseDir =
|
|
25991
|
+
baseDir = path51.dirname(baseDir);
|
|
25645
25992
|
}
|
|
25646
25993
|
const rest = module.slice(leadingDots);
|
|
25647
25994
|
if (rest.length === 0) {
|
|
25648
|
-
const initPath =
|
|
25649
|
-
if (
|
|
25995
|
+
const initPath = path51.join(baseDir, "__init__.py");
|
|
25996
|
+
if (fs22.existsSync(initPath) && fs22.statSync(initPath).isFile()) {
|
|
25650
25997
|
return normalizePath2(initPath);
|
|
25651
25998
|
}
|
|
25652
25999
|
return null;
|
|
25653
26000
|
}
|
|
25654
|
-
const subpath = rest.replace(/\./g,
|
|
26001
|
+
const subpath = rest.replace(/\./g, path51.sep);
|
|
25655
26002
|
const candidates = [
|
|
25656
|
-
`${
|
|
25657
|
-
|
|
26003
|
+
`${path51.join(baseDir, subpath)}.py`,
|
|
26004
|
+
path51.join(baseDir, subpath, "__init__.py")
|
|
25658
26005
|
];
|
|
25659
26006
|
for (const c of candidates) {
|
|
25660
|
-
if (
|
|
26007
|
+
if (fs22.existsSync(c) && fs22.statSync(c).isFile())
|
|
25661
26008
|
return normalizePath2(c);
|
|
25662
26009
|
}
|
|
25663
26010
|
return null;
|
|
25664
26011
|
}
|
|
25665
26012
|
var goModuleCache = new Map;
|
|
25666
26013
|
function findGoModule(fromDir) {
|
|
25667
|
-
const resolved =
|
|
26014
|
+
const resolved = path51.resolve(fromDir);
|
|
25668
26015
|
let cur = resolved;
|
|
25669
26016
|
const walked = [];
|
|
25670
26017
|
for (let i = 0;i < 16; i++) {
|
|
@@ -25676,8 +26023,8 @@ function findGoModule(fromDir) {
|
|
|
25676
26023
|
}
|
|
25677
26024
|
walked.push(cur);
|
|
25678
26025
|
try {
|
|
25679
|
-
const goMod =
|
|
25680
|
-
const content =
|
|
26026
|
+
const goMod = path51.join(cur, "go.mod");
|
|
26027
|
+
const content = fs22.readFileSync(goMod, "utf-8");
|
|
25681
26028
|
const moduleMatch = content.match(/^\s*module\s+"?([^"\s/]+(?:\/[^"\s]+)*)"?/m);
|
|
25682
26029
|
if (moduleMatch) {
|
|
25683
26030
|
const result = { moduleRoot: cur, modulePath: moduleMatch[1] };
|
|
@@ -25687,10 +26034,10 @@ function findGoModule(fromDir) {
|
|
|
25687
26034
|
}
|
|
25688
26035
|
} catch {}
|
|
25689
26036
|
try {
|
|
25690
|
-
|
|
26037
|
+
fs22.accessSync(path51.join(cur, ".git"));
|
|
25691
26038
|
break;
|
|
25692
26039
|
} catch {}
|
|
25693
|
-
const parent =
|
|
26040
|
+
const parent = path51.dirname(cur);
|
|
25694
26041
|
if (parent === cur)
|
|
25695
26042
|
break;
|
|
25696
26043
|
cur = parent;
|
|
@@ -25702,20 +26049,20 @@ function findGoModule(fromDir) {
|
|
|
25702
26049
|
function resolveGoImport(fromDir, importPath) {
|
|
25703
26050
|
let dir = null;
|
|
25704
26051
|
if (importPath.startsWith(".")) {
|
|
25705
|
-
dir =
|
|
26052
|
+
dir = path51.resolve(fromDir, importPath);
|
|
25706
26053
|
} else {
|
|
25707
26054
|
const mod = findGoModule(fromDir);
|
|
25708
26055
|
if (mod && (importPath === mod.modulePath || importPath.startsWith(`${mod.modulePath}/`))) {
|
|
25709
26056
|
const subpath = importPath.slice(mod.modulePath.length);
|
|
25710
|
-
dir =
|
|
26057
|
+
dir = path51.join(mod.moduleRoot, subpath);
|
|
25711
26058
|
}
|
|
25712
26059
|
}
|
|
25713
26060
|
if (dir === null)
|
|
25714
26061
|
return [];
|
|
25715
|
-
if (!
|
|
26062
|
+
if (!fs22.existsSync(dir) || !fs22.statSync(dir).isDirectory())
|
|
25716
26063
|
return [];
|
|
25717
26064
|
try {
|
|
25718
|
-
return
|
|
26065
|
+
return fs22.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath2(path51.join(dir, f)));
|
|
25719
26066
|
} catch {
|
|
25720
26067
|
return [];
|
|
25721
26068
|
}
|
|
@@ -25735,13 +26082,13 @@ function findTestFilesSync(cwd) {
|
|
|
25735
26082
|
function walk(dir, visitedInodes) {
|
|
25736
26083
|
let entries;
|
|
25737
26084
|
try {
|
|
25738
|
-
entries =
|
|
26085
|
+
entries = fs22.readdirSync(dir, { withFileTypes: true });
|
|
25739
26086
|
} catch {
|
|
25740
26087
|
return;
|
|
25741
26088
|
}
|
|
25742
26089
|
let dirInode;
|
|
25743
26090
|
try {
|
|
25744
|
-
dirInode =
|
|
26091
|
+
dirInode = fs22.statSync(dir).ino;
|
|
25745
26092
|
} catch {
|
|
25746
26093
|
return;
|
|
25747
26094
|
}
|
|
@@ -25754,15 +26101,15 @@ function findTestFilesSync(cwd) {
|
|
|
25754
26101
|
for (const entry of entries) {
|
|
25755
26102
|
if (entry.isDirectory()) {
|
|
25756
26103
|
if (!skipDirs.has(entry.name)) {
|
|
25757
|
-
walk(
|
|
26104
|
+
walk(path51.join(dir, entry.name), visitedInodes);
|
|
25758
26105
|
}
|
|
25759
26106
|
} else if (entry.isFile()) {
|
|
25760
26107
|
const name = entry.name;
|
|
25761
26108
|
const isTsTest = /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(name) || dir.includes("__tests__") && /\.(ts|tsx|js|jsx)$/.test(name);
|
|
25762
|
-
const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${
|
|
26109
|
+
const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${path51.sep}tests${path51.sep}`) && name.endsWith(".py");
|
|
25763
26110
|
const isGoTest = /.+_test\.go$/.test(name);
|
|
25764
26111
|
if (isTsTest || isPyTest || isGoTest) {
|
|
25765
|
-
testFiles.push(normalizePath2(
|
|
26112
|
+
testFiles.push(normalizePath2(path51.join(dir, entry.name)));
|
|
25766
26113
|
}
|
|
25767
26114
|
}
|
|
25768
26115
|
}
|
|
@@ -25787,8 +26134,8 @@ function extractImports(content) {
|
|
|
25787
26134
|
];
|
|
25788
26135
|
}
|
|
25789
26136
|
function addImpactEdgesForTestFile(testFile, content, impactMap) {
|
|
25790
|
-
const ext =
|
|
25791
|
-
const testDir =
|
|
26137
|
+
const ext = path51.extname(testFile).toLowerCase();
|
|
26138
|
+
const testDir = path51.dirname(testFile);
|
|
25792
26139
|
function addEdge(source) {
|
|
25793
26140
|
if (!impactMap[source])
|
|
25794
26141
|
impactMap[source] = [];
|
|
@@ -25830,7 +26177,7 @@ async function buildImpactMapInternal(cwd) {
|
|
|
25830
26177
|
for (const testFile of testFiles) {
|
|
25831
26178
|
let content;
|
|
25832
26179
|
try {
|
|
25833
|
-
content =
|
|
26180
|
+
content = fs22.readFileSync(testFile, "utf-8");
|
|
25834
26181
|
} catch {
|
|
25835
26182
|
continue;
|
|
25836
26183
|
}
|
|
@@ -25861,10 +26208,10 @@ async function buildImpactMap(cwd) {
|
|
|
25861
26208
|
return impactMap;
|
|
25862
26209
|
}
|
|
25863
26210
|
async function loadImpactMap(cwd, options) {
|
|
25864
|
-
const cachePath =
|
|
25865
|
-
if (
|
|
26211
|
+
const cachePath = path51.join(cwd, ".swarm", "cache", "impact-map.json");
|
|
26212
|
+
if (fs22.existsSync(cachePath)) {
|
|
25866
26213
|
try {
|
|
25867
|
-
const content =
|
|
26214
|
+
const content = fs22.readFileSync(cachePath, "utf-8");
|
|
25868
26215
|
const data = JSON.parse(content);
|
|
25869
26216
|
if (data.map !== null && typeof data.map === "object" && !Array.isArray(data.map)) {
|
|
25870
26217
|
const map = data.map;
|
|
@@ -25894,21 +26241,21 @@ async function loadImpactMap(cwd, options) {
|
|
|
25894
26241
|
return _internals39.buildImpactMap(cwd);
|
|
25895
26242
|
}
|
|
25896
26243
|
async function saveImpactMap(cwd, impactMap) {
|
|
25897
|
-
if (!
|
|
26244
|
+
if (!path51.isAbsolute(cwd)) {
|
|
25898
26245
|
throw new Error(`saveImpactMap requires an absolute project root path, got: "${cwd}"`);
|
|
25899
26246
|
}
|
|
25900
26247
|
_internals39.validateProjectRoot(cwd);
|
|
25901
|
-
const cacheDir2 =
|
|
25902
|
-
const cachePath =
|
|
25903
|
-
if (!
|
|
25904
|
-
|
|
26248
|
+
const cacheDir2 = path51.join(cwd, ".swarm", "cache");
|
|
26249
|
+
const cachePath = path51.join(cacheDir2, "impact-map.json");
|
|
26250
|
+
if (!fs22.existsSync(cacheDir2)) {
|
|
26251
|
+
fs22.mkdirSync(cacheDir2, { recursive: true });
|
|
25905
26252
|
}
|
|
25906
26253
|
const data = {
|
|
25907
26254
|
generatedAt: new Date().toISOString(),
|
|
25908
26255
|
fileCount: Object.keys(impactMap).length,
|
|
25909
26256
|
map: impactMap
|
|
25910
26257
|
};
|
|
25911
|
-
|
|
26258
|
+
fs22.writeFileSync(cachePath, JSON.stringify(data, null, 2), "utf-8");
|
|
25912
26259
|
}
|
|
25913
26260
|
async function analyzeImpact(changedFiles, cwd, budget) {
|
|
25914
26261
|
if (!Array.isArray(changedFiles)) {
|
|
@@ -25931,7 +26278,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
|
|
|
25931
26278
|
budgetExceeded = true;
|
|
25932
26279
|
break;
|
|
25933
26280
|
}
|
|
25934
|
-
const normalizedChanged = normalizePath2(
|
|
26281
|
+
const normalizedChanged = normalizePath2(path51.resolve(changedFile));
|
|
25935
26282
|
const tests = impactMap[normalizedChanged];
|
|
25936
26283
|
if (tests && tests.length > 0) {
|
|
25937
26284
|
for (const test of tests) {
|
|
@@ -25945,13 +26292,13 @@ async function analyzeImpact(changedFiles, cwd, budget) {
|
|
|
25945
26292
|
if (budgetExceeded)
|
|
25946
26293
|
break;
|
|
25947
26294
|
} else {
|
|
25948
|
-
const changedDir = normalizePath2(
|
|
25949
|
-
const changedInputDir = normalizePath2(
|
|
26295
|
+
const changedDir = normalizePath2(path51.dirname(normalizedChanged));
|
|
26296
|
+
const changedInputDir = normalizePath2(path51.dirname(changedFile));
|
|
25950
26297
|
const suffixMatches = Object.entries(impactMap).filter(([sourcePath]) => {
|
|
25951
26298
|
return sourcePath.endsWith(changedFile) || changedFile.endsWith(sourcePath) || sourcePath.endsWith(normalizedChanged) || normalizedChanged.endsWith(sourcePath);
|
|
25952
26299
|
}).sort(([sourceA], [sourceB]) => {
|
|
25953
|
-
const sourceDirA = normalizePath2(
|
|
25954
|
-
const sourceDirB = normalizePath2(
|
|
26300
|
+
const sourceDirA = normalizePath2(path51.dirname(sourceA));
|
|
26301
|
+
const sourceDirB = normalizePath2(path51.dirname(sourceB));
|
|
25955
26302
|
const exactA = sourceDirA === changedDir || changedInputDir !== "." && (sourceDirA === changedInputDir || sourceDirA.endsWith(`/${changedInputDir}`));
|
|
25956
26303
|
const exactB = sourceDirB === changedDir || changedInputDir !== "." && (sourceDirB === changedInputDir || sourceDirB.endsWith(`/${changedInputDir}`));
|
|
25957
26304
|
if (exactA !== exactB)
|
|
@@ -26277,8 +26624,8 @@ function detectFlakyTests(allHistory) {
|
|
|
26277
26624
|
}
|
|
26278
26625
|
|
|
26279
26626
|
// src/test-impact/history-store.ts
|
|
26280
|
-
import
|
|
26281
|
-
import
|
|
26627
|
+
import fs23 from "fs";
|
|
26628
|
+
import path52 from "path";
|
|
26282
26629
|
var MAX_HISTORY_PER_TEST = 20;
|
|
26283
26630
|
var MAX_ERROR_LENGTH = 500;
|
|
26284
26631
|
var MAX_STACK_LENGTH = 200;
|
|
@@ -26290,10 +26637,10 @@ function getHistoryPath(workingDir) {
|
|
|
26290
26637
|
if (!workingDir) {
|
|
26291
26638
|
throw new Error("getHistoryPath requires a working directory \u2014 project root must be provided by the caller");
|
|
26292
26639
|
}
|
|
26293
|
-
if (!
|
|
26640
|
+
if (!path52.isAbsolute(workingDir)) {
|
|
26294
26641
|
throw new Error(`getHistoryPath requires an absolute project root path, got: "${workingDir}"`);
|
|
26295
26642
|
}
|
|
26296
|
-
return
|
|
26643
|
+
return path52.join(workingDir, ".swarm", "cache", "test-history.jsonl");
|
|
26297
26644
|
}
|
|
26298
26645
|
function sanitizeErrorMessage(errorMessage) {
|
|
26299
26646
|
if (errorMessage === undefined) {
|
|
@@ -26385,10 +26732,10 @@ function batchAppendTestRuns(records, workingDir) {
|
|
|
26385
26732
|
}
|
|
26386
26733
|
}
|
|
26387
26734
|
const historyPath = getHistoryPath(workingDir);
|
|
26388
|
-
const historyDir =
|
|
26735
|
+
const historyDir = path52.dirname(historyPath);
|
|
26389
26736
|
_internals40.validateProjectRoot(workingDir);
|
|
26390
|
-
if (!
|
|
26391
|
-
|
|
26737
|
+
if (!fs23.existsSync(historyDir)) {
|
|
26738
|
+
fs23.mkdirSync(historyDir, { recursive: true });
|
|
26392
26739
|
}
|
|
26393
26740
|
withHistoryWriteLock(historyPath, () => {
|
|
26394
26741
|
const existingRecords = readAllRecords(historyPath);
|
|
@@ -26422,13 +26769,13 @@ function batchAppendTestRuns(records, workingDir) {
|
|
|
26422
26769
|
`)}
|
|
26423
26770
|
`;
|
|
26424
26771
|
const tempPath = `${historyPath}.tmp`;
|
|
26425
|
-
|
|
26426
|
-
|
|
26772
|
+
fs23.writeFileSync(tempPath, content, "utf-8");
|
|
26773
|
+
fs23.renameSync(tempPath, historyPath);
|
|
26427
26774
|
} catch (err) {
|
|
26428
26775
|
try {
|
|
26429
26776
|
const tempPath = `${historyPath}.tmp`;
|
|
26430
|
-
if (
|
|
26431
|
-
|
|
26777
|
+
if (fs23.existsSync(tempPath)) {
|
|
26778
|
+
fs23.unlinkSync(tempPath);
|
|
26432
26779
|
}
|
|
26433
26780
|
} catch {}
|
|
26434
26781
|
throw new Error(`Failed to write test history: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -26440,7 +26787,7 @@ function withHistoryWriteLock(historyPath, fn) {
|
|
|
26440
26787
|
const deadline = Date.now() + HISTORY_WRITE_LOCK_TIMEOUT_MS;
|
|
26441
26788
|
while (true) {
|
|
26442
26789
|
try {
|
|
26443
|
-
|
|
26790
|
+
fs23.mkdirSync(lockPath);
|
|
26444
26791
|
break;
|
|
26445
26792
|
} catch (error2) {
|
|
26446
26793
|
const code = error2 instanceof Error && "code" in error2 ? error2.code : undefined;
|
|
@@ -26451,9 +26798,9 @@ function withHistoryWriteLock(historyPath, fn) {
|
|
|
26451
26798
|
throw new Error(`Timed out waiting for test history lock: ${historyPath}`);
|
|
26452
26799
|
}
|
|
26453
26800
|
try {
|
|
26454
|
-
const lockStat =
|
|
26801
|
+
const lockStat = fs23.statSync(lockPath);
|
|
26455
26802
|
if (Date.now() - lockStat.mtimeMs >= HISTORY_WRITE_LOCK_STALE_MS) {
|
|
26456
|
-
|
|
26803
|
+
fs23.rmSync(lockPath, { recursive: true, force: true });
|
|
26457
26804
|
continue;
|
|
26458
26805
|
}
|
|
26459
26806
|
} catch {}
|
|
@@ -26468,7 +26815,7 @@ function withHistoryWriteLock(historyPath, fn) {
|
|
|
26468
26815
|
return fn();
|
|
26469
26816
|
} finally {
|
|
26470
26817
|
try {
|
|
26471
|
-
|
|
26818
|
+
fs23.rmSync(lockPath, { recursive: true, force: true });
|
|
26472
26819
|
} catch {}
|
|
26473
26820
|
}
|
|
26474
26821
|
function sleepSync(ms) {
|
|
@@ -26477,11 +26824,11 @@ function withHistoryWriteLock(historyPath, fn) {
|
|
|
26477
26824
|
}
|
|
26478
26825
|
}
|
|
26479
26826
|
function readAllRecords(historyPath) {
|
|
26480
|
-
if (!
|
|
26827
|
+
if (!fs23.existsSync(historyPath)) {
|
|
26481
26828
|
return [];
|
|
26482
26829
|
}
|
|
26483
26830
|
try {
|
|
26484
|
-
const content =
|
|
26831
|
+
const content = fs23.readFileSync(historyPath, "utf-8");
|
|
26485
26832
|
const lines = content.split(`
|
|
26486
26833
|
`);
|
|
26487
26834
|
const records = [];
|
|
@@ -26514,8 +26861,8 @@ var _internals40 = {
|
|
|
26514
26861
|
};
|
|
26515
26862
|
|
|
26516
26863
|
// src/tools/resolve-working-directory.ts
|
|
26517
|
-
import * as
|
|
26518
|
-
import * as
|
|
26864
|
+
import * as fs24 from "fs";
|
|
26865
|
+
import * as path53 from "path";
|
|
26519
26866
|
function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
26520
26867
|
if (workingDirectory == null || workingDirectory === "") {
|
|
26521
26868
|
if (typeof fallbackDirectory !== "string" || fallbackDirectory === "") {
|
|
@@ -26547,18 +26894,18 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
26547
26894
|
};
|
|
26548
26895
|
}
|
|
26549
26896
|
}
|
|
26550
|
-
const rawPathParts = workingDirectory.split(
|
|
26897
|
+
const rawPathParts = workingDirectory.split(path53.sep);
|
|
26551
26898
|
if (rawPathParts.includes("..")) {
|
|
26552
26899
|
return {
|
|
26553
26900
|
success: false,
|
|
26554
26901
|
message: "Invalid working_directory: path traversal sequences (..) are not allowed"
|
|
26555
26902
|
};
|
|
26556
26903
|
}
|
|
26557
|
-
const normalizedDir =
|
|
26558
|
-
const resolvedDir =
|
|
26904
|
+
const normalizedDir = path53.normalize(workingDirectory);
|
|
26905
|
+
const resolvedDir = path53.resolve(normalizedDir);
|
|
26559
26906
|
let statResult;
|
|
26560
26907
|
try {
|
|
26561
|
-
statResult =
|
|
26908
|
+
statResult = fs24.statSync(resolvedDir);
|
|
26562
26909
|
} catch {
|
|
26563
26910
|
return {
|
|
26564
26911
|
success: false,
|
|
@@ -26574,16 +26921,16 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
|
|
|
26574
26921
|
if (typeof fallbackDirectory !== "string" || fallbackDirectory === "") {
|
|
26575
26922
|
return { success: true, directory: resolvedDir };
|
|
26576
26923
|
}
|
|
26577
|
-
const resolvedFallback =
|
|
26924
|
+
const resolvedFallback = path53.resolve(fallbackDirectory);
|
|
26578
26925
|
let fallbackExists = false;
|
|
26579
26926
|
try {
|
|
26580
|
-
|
|
26927
|
+
fs24.statSync(resolvedFallback);
|
|
26581
26928
|
fallbackExists = true;
|
|
26582
26929
|
} catch {
|
|
26583
26930
|
fallbackExists = false;
|
|
26584
26931
|
}
|
|
26585
26932
|
if (fallbackExists) {
|
|
26586
|
-
const isSubdirectory = resolvedDir.startsWith(resolvedFallback +
|
|
26933
|
+
const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path53.sep);
|
|
26587
26934
|
if (isSubdirectory) {
|
|
26588
26935
|
return {
|
|
26589
26936
|
success: false,
|
|
@@ -26606,7 +26953,7 @@ async function estimateFanOut(sourceFiles, cwd) {
|
|
|
26606
26953
|
const impactMap = await loadImpactMap(cwd, { skipRebuild: true });
|
|
26607
26954
|
const uniqueTestFiles = new Set;
|
|
26608
26955
|
for (const sourceFile of sourceFiles) {
|
|
26609
|
-
const resolvedPath =
|
|
26956
|
+
const resolvedPath = path54.resolve(cwd, sourceFile);
|
|
26610
26957
|
const normalizedPath = resolvedPath.replace(/\\/g, "/");
|
|
26611
26958
|
const testFiles = impactMap[normalizedPath];
|
|
26612
26959
|
if (testFiles) {
|
|
@@ -26691,19 +27038,19 @@ function hasDevDependency(devDeps, ...patterns) {
|
|
|
26691
27038
|
return hasPackageJsonDependency(devDeps, ...patterns);
|
|
26692
27039
|
}
|
|
26693
27040
|
function detectGoTest(cwd) {
|
|
26694
|
-
return
|
|
27041
|
+
return fs25.existsSync(path54.join(cwd, "go.mod")) && isCommandAvailable("go");
|
|
26695
27042
|
}
|
|
26696
27043
|
function detectJavaMaven(cwd) {
|
|
26697
|
-
return
|
|
27044
|
+
return fs25.existsSync(path54.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
|
|
26698
27045
|
}
|
|
26699
27046
|
function detectGradle(cwd) {
|
|
26700
|
-
const hasBuildFile =
|
|
26701
|
-
const hasGradlew =
|
|
27047
|
+
const hasBuildFile = fs25.existsSync(path54.join(cwd, "build.gradle")) || fs25.existsSync(path54.join(cwd, "build.gradle.kts"));
|
|
27048
|
+
const hasGradlew = fs25.existsSync(path54.join(cwd, "gradlew")) || fs25.existsSync(path54.join(cwd, "gradlew.bat"));
|
|
26702
27049
|
return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
|
|
26703
27050
|
}
|
|
26704
27051
|
function detectDotnetTest(cwd) {
|
|
26705
27052
|
try {
|
|
26706
|
-
const files =
|
|
27053
|
+
const files = fs25.readdirSync(cwd);
|
|
26707
27054
|
const hasCsproj = files.some((f) => f.endsWith(".csproj"));
|
|
26708
27055
|
return hasCsproj && isCommandAvailable("dotnet");
|
|
26709
27056
|
} catch {
|
|
@@ -26711,25 +27058,25 @@ function detectDotnetTest(cwd) {
|
|
|
26711
27058
|
}
|
|
26712
27059
|
}
|
|
26713
27060
|
function detectCTest(cwd) {
|
|
26714
|
-
const hasSource =
|
|
26715
|
-
const hasBuildCache =
|
|
27061
|
+
const hasSource = fs25.existsSync(path54.join(cwd, "CMakeLists.txt"));
|
|
27062
|
+
const hasBuildCache = fs25.existsSync(path54.join(cwd, "CMakeCache.txt")) || fs25.existsSync(path54.join(cwd, "build", "CMakeCache.txt"));
|
|
26716
27063
|
return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
|
|
26717
27064
|
}
|
|
26718
27065
|
function detectSwiftTest(cwd) {
|
|
26719
|
-
return
|
|
27066
|
+
return fs25.existsSync(path54.join(cwd, "Package.swift")) && isCommandAvailable("swift");
|
|
26720
27067
|
}
|
|
26721
27068
|
function detectDartTest(cwd) {
|
|
26722
|
-
return
|
|
27069
|
+
return fs25.existsSync(path54.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
|
|
26723
27070
|
}
|
|
26724
27071
|
function detectRSpec(cwd) {
|
|
26725
|
-
const hasRSpecFile =
|
|
26726
|
-
const hasGemfile =
|
|
26727
|
-
const hasSpecDir =
|
|
27072
|
+
const hasRSpecFile = fs25.existsSync(path54.join(cwd, ".rspec"));
|
|
27073
|
+
const hasGemfile = fs25.existsSync(path54.join(cwd, "Gemfile"));
|
|
27074
|
+
const hasSpecDir = fs25.existsSync(path54.join(cwd, "spec"));
|
|
26728
27075
|
const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
|
|
26729
27076
|
return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
|
|
26730
27077
|
}
|
|
26731
27078
|
function detectMinitest(cwd) {
|
|
26732
|
-
return
|
|
27079
|
+
return fs25.existsSync(path54.join(cwd, "test")) && (fs25.existsSync(path54.join(cwd, "Gemfile")) || fs25.existsSync(path54.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
|
|
26733
27080
|
}
|
|
26734
27081
|
var DISPATCH_FRAMEWORK_MAP = {
|
|
26735
27082
|
bun: "bun",
|
|
@@ -26814,9 +27161,9 @@ async function parseTestOutputViaDispatch(framework, output, baseDir) {
|
|
|
26814
27161
|
async function detectTestFramework(cwd) {
|
|
26815
27162
|
const baseDir = cwd;
|
|
26816
27163
|
try {
|
|
26817
|
-
const packageJsonPath =
|
|
26818
|
-
if (
|
|
26819
|
-
const content =
|
|
27164
|
+
const packageJsonPath = path54.join(baseDir, "package.json");
|
|
27165
|
+
if (fs25.existsSync(packageJsonPath)) {
|
|
27166
|
+
const content = fs25.readFileSync(packageJsonPath, "utf-8");
|
|
26820
27167
|
const pkg = JSON.parse(content);
|
|
26821
27168
|
const _deps = pkg.dependencies || {};
|
|
26822
27169
|
const devDeps = pkg.devDependencies || {};
|
|
@@ -26835,38 +27182,38 @@ async function detectTestFramework(cwd) {
|
|
|
26835
27182
|
return "jest";
|
|
26836
27183
|
if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
|
|
26837
27184
|
return "mocha";
|
|
26838
|
-
if (
|
|
27185
|
+
if (fs25.existsSync(path54.join(baseDir, "bun.lockb")) || fs25.existsSync(path54.join(baseDir, "bun.lock"))) {
|
|
26839
27186
|
if (scripts.test?.includes("bun"))
|
|
26840
27187
|
return "bun";
|
|
26841
27188
|
}
|
|
26842
27189
|
}
|
|
26843
27190
|
} catch {}
|
|
26844
27191
|
try {
|
|
26845
|
-
const pyprojectTomlPath =
|
|
26846
|
-
const setupCfgPath =
|
|
26847
|
-
const requirementsTxtPath =
|
|
26848
|
-
if (
|
|
26849
|
-
const content =
|
|
27192
|
+
const pyprojectTomlPath = path54.join(baseDir, "pyproject.toml");
|
|
27193
|
+
const setupCfgPath = path54.join(baseDir, "setup.cfg");
|
|
27194
|
+
const requirementsTxtPath = path54.join(baseDir, "requirements.txt");
|
|
27195
|
+
if (fs25.existsSync(pyprojectTomlPath)) {
|
|
27196
|
+
const content = fs25.readFileSync(pyprojectTomlPath, "utf-8");
|
|
26850
27197
|
if (content.includes("[tool.pytest"))
|
|
26851
27198
|
return "pytest";
|
|
26852
27199
|
if (content.includes("pytest"))
|
|
26853
27200
|
return "pytest";
|
|
26854
27201
|
}
|
|
26855
|
-
if (
|
|
26856
|
-
const content =
|
|
27202
|
+
if (fs25.existsSync(setupCfgPath)) {
|
|
27203
|
+
const content = fs25.readFileSync(setupCfgPath, "utf-8");
|
|
26857
27204
|
if (content.includes("[pytest]"))
|
|
26858
27205
|
return "pytest";
|
|
26859
27206
|
}
|
|
26860
|
-
if (
|
|
26861
|
-
const content =
|
|
27207
|
+
if (fs25.existsSync(requirementsTxtPath)) {
|
|
27208
|
+
const content = fs25.readFileSync(requirementsTxtPath, "utf-8");
|
|
26862
27209
|
if (content.includes("pytest"))
|
|
26863
27210
|
return "pytest";
|
|
26864
27211
|
}
|
|
26865
27212
|
} catch {}
|
|
26866
27213
|
try {
|
|
26867
|
-
const cargoTomlPath =
|
|
26868
|
-
if (
|
|
26869
|
-
const content =
|
|
27214
|
+
const cargoTomlPath = path54.join(baseDir, "Cargo.toml");
|
|
27215
|
+
if (fs25.existsSync(cargoTomlPath)) {
|
|
27216
|
+
const content = fs25.readFileSync(cargoTomlPath, "utf-8");
|
|
26870
27217
|
if (content.includes("[dev-dependencies]")) {
|
|
26871
27218
|
if (content.includes("tokio") || content.includes("mockall") || content.includes("pretty_assertions")) {
|
|
26872
27219
|
return "cargo";
|
|
@@ -26875,10 +27222,10 @@ async function detectTestFramework(cwd) {
|
|
|
26875
27222
|
}
|
|
26876
27223
|
} catch {}
|
|
26877
27224
|
try {
|
|
26878
|
-
const pesterConfigPath =
|
|
26879
|
-
const pesterConfigJsonPath =
|
|
26880
|
-
const pesterPs1Path =
|
|
26881
|
-
if (
|
|
27225
|
+
const pesterConfigPath = path54.join(baseDir, "pester.config.ps1");
|
|
27226
|
+
const pesterConfigJsonPath = path54.join(baseDir, "pester.config.ps1.json");
|
|
27227
|
+
const pesterPs1Path = path54.join(baseDir, "tests.ps1");
|
|
27228
|
+
if (fs25.existsSync(pesterConfigPath) || fs25.existsSync(pesterConfigJsonPath) || fs25.existsSync(pesterPs1Path)) {
|
|
26882
27229
|
return "pester";
|
|
26883
27230
|
}
|
|
26884
27231
|
} catch {}
|
|
@@ -26920,12 +27267,12 @@ function isTestDirectoryPath(normalizedPath) {
|
|
|
26920
27267
|
return normalizedPath.split("/").some((segment) => TEST_DIRECTORY_NAMES.includes(segment));
|
|
26921
27268
|
}
|
|
26922
27269
|
function resolveWorkspacePath(file, workingDir) {
|
|
26923
|
-
return
|
|
27270
|
+
return path54.isAbsolute(file) ? path54.resolve(file) : path54.resolve(workingDir, file);
|
|
26924
27271
|
}
|
|
26925
27272
|
function toWorkspaceOutputPath(absolutePath, workingDir, preferRelative) {
|
|
26926
27273
|
if (!preferRelative)
|
|
26927
27274
|
return absolutePath;
|
|
26928
|
-
return
|
|
27275
|
+
return path54.relative(workingDir, absolutePath);
|
|
26929
27276
|
}
|
|
26930
27277
|
function dedupePush(target, value) {
|
|
26931
27278
|
if (!target.includes(value)) {
|
|
@@ -26962,18 +27309,18 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
|
|
|
26962
27309
|
}
|
|
26963
27310
|
}
|
|
26964
27311
|
function getRepoLevelCandidateDirectories(workingDir, relativePath, ext) {
|
|
26965
|
-
const relativeDir =
|
|
27312
|
+
const relativeDir = path54.dirname(relativePath);
|
|
26966
27313
|
const nestedRelativeDir = relativeDir === "." ? "" : relativeDir;
|
|
26967
27314
|
const directories = TEST_DIRECTORY_NAMES.flatMap((dirName) => {
|
|
26968
|
-
const rootDir =
|
|
26969
|
-
return nestedRelativeDir ? [rootDir,
|
|
27315
|
+
const rootDir = path54.join(workingDir, dirName);
|
|
27316
|
+
return nestedRelativeDir ? [rootDir, path54.join(rootDir, nestedRelativeDir)] : [rootDir];
|
|
26970
27317
|
});
|
|
26971
27318
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
26972
27319
|
if (ext === ".java" && normalizedRelativePath.startsWith("src/main/java/")) {
|
|
26973
|
-
directories.push(
|
|
27320
|
+
directories.push(path54.join(workingDir, "src/test/java", path54.dirname(normalizedRelativePath.slice("src/main/java/".length))));
|
|
26974
27321
|
}
|
|
26975
27322
|
if ((ext === ".kt" || ext === ".java") && normalizedRelativePath.startsWith("src/main/kotlin/")) {
|
|
26976
|
-
directories.push(
|
|
27323
|
+
directories.push(path54.join(workingDir, "src/test/kotlin", path54.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
|
|
26977
27324
|
}
|
|
26978
27325
|
return [...new Set(directories)];
|
|
26979
27326
|
}
|
|
@@ -26981,19 +27328,19 @@ function hasCompoundTestExtension(filename) {
|
|
|
26981
27328
|
const lower = filename.toLowerCase();
|
|
26982
27329
|
return COMPOUND_TEST_EXTENSIONS.some((ext) => lower.endsWith(ext));
|
|
26983
27330
|
}
|
|
26984
|
-
function isLanguageSpecificTestFile(
|
|
26985
|
-
const lower =
|
|
27331
|
+
function isLanguageSpecificTestFile(basename10) {
|
|
27332
|
+
const lower = basename10.toLowerCase();
|
|
26986
27333
|
if (lower.endsWith("_test.go"))
|
|
26987
27334
|
return true;
|
|
26988
27335
|
if (lower.endsWith(".py") && (lower.startsWith("test_") || lower.endsWith("_test.py")))
|
|
26989
27336
|
return true;
|
|
26990
27337
|
if (lower.endsWith("_spec.rb"))
|
|
26991
27338
|
return true;
|
|
26992
|
-
if (lower.endsWith(".java") && (/^Test[A-Z]/.test(
|
|
27339
|
+
if (lower.endsWith(".java") && (/^Test[A-Z]/.test(basename10) || basename10.endsWith("Test.java") || basename10.endsWith("Tests.java") || lower.endsWith("it.java")))
|
|
26993
27340
|
return true;
|
|
26994
27341
|
if (lower.endsWith(".cs") && (lower.endsWith("test.cs") || lower.endsWith("tests.cs")))
|
|
26995
27342
|
return true;
|
|
26996
|
-
if (lower.endsWith(".kt") && (/^Test[A-Z]/.test(
|
|
27343
|
+
if (lower.endsWith(".kt") && (/^Test[A-Z]/.test(basename10) || lower.endsWith("test.kt") || lower.endsWith("tests.kt")))
|
|
26997
27344
|
return true;
|
|
26998
27345
|
if (lower.endsWith(".tests.ps1"))
|
|
26999
27346
|
return true;
|
|
@@ -27001,23 +27348,23 @@ function isLanguageSpecificTestFile(basename9) {
|
|
|
27001
27348
|
}
|
|
27002
27349
|
function isConventionTestFilePath(filePath) {
|
|
27003
27350
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
27004
|
-
const
|
|
27005
|
-
return hasCompoundTestExtension(
|
|
27351
|
+
const basename10 = path54.basename(filePath);
|
|
27352
|
+
return hasCompoundTestExtension(basename10) || basename10.includes(".spec.") || basename10.includes(".test.") || isLanguageSpecificTestFile(basename10) || isTestDirectoryPath(normalizedPath);
|
|
27006
27353
|
}
|
|
27007
27354
|
function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
27008
27355
|
const testFiles = [];
|
|
27009
27356
|
for (const file of sourceFiles) {
|
|
27010
27357
|
const absoluteFile = resolveWorkspacePath(file, workingDir);
|
|
27011
|
-
const relativeFile =
|
|
27012
|
-
const
|
|
27013
|
-
const dirname25 =
|
|
27014
|
-
const preferRelativeOutput = !
|
|
27358
|
+
const relativeFile = path54.relative(workingDir, absoluteFile);
|
|
27359
|
+
const basename10 = path54.basename(absoluteFile);
|
|
27360
|
+
const dirname25 = path54.dirname(absoluteFile);
|
|
27361
|
+
const preferRelativeOutput = !path54.isAbsolute(file);
|
|
27015
27362
|
if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file)) {
|
|
27016
27363
|
dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
|
|
27017
27364
|
continue;
|
|
27018
27365
|
}
|
|
27019
|
-
const nameWithoutExt =
|
|
27020
|
-
const ext =
|
|
27366
|
+
const nameWithoutExt = basename10.replace(/\.[^.]+$/, "");
|
|
27367
|
+
const ext = path54.extname(basename10);
|
|
27021
27368
|
const genericTestNames = [
|
|
27022
27369
|
`${nameWithoutExt}.spec${ext}`,
|
|
27023
27370
|
`${nameWithoutExt}.test${ext}`
|
|
@@ -27026,20 +27373,20 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
|
27026
27373
|
const colocatedCandidates = [
|
|
27027
27374
|
...genericTestNames,
|
|
27028
27375
|
...languageSpecificTestNames
|
|
27029
|
-
].map((candidateName) =>
|
|
27376
|
+
].map((candidateName) => path54.join(dirname25, candidateName));
|
|
27030
27377
|
const testDirectoryNames = [
|
|
27031
|
-
|
|
27378
|
+
basename10,
|
|
27032
27379
|
...genericTestNames,
|
|
27033
27380
|
...languageSpecificTestNames
|
|
27034
27381
|
];
|
|
27035
27382
|
const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
|
|
27036
27383
|
const possibleTestFiles = [
|
|
27037
27384
|
...colocatedCandidates,
|
|
27038
|
-
...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) =>
|
|
27039
|
-
...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) =>
|
|
27385
|
+
...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path54.join(dirname25, dirName, candidateName))),
|
|
27386
|
+
...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path54.join(candidateDir, candidateName)))
|
|
27040
27387
|
];
|
|
27041
27388
|
for (const testFile of possibleTestFiles) {
|
|
27042
|
-
if (
|
|
27389
|
+
if (fs25.existsSync(testFile)) {
|
|
27043
27390
|
dedupePush(testFiles, toWorkspaceOutputPath(testFile, workingDir, preferRelativeOutput));
|
|
27044
27391
|
}
|
|
27045
27392
|
}
|
|
@@ -27056,8 +27403,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
27056
27403
|
for (const testFile of candidateTestFiles) {
|
|
27057
27404
|
try {
|
|
27058
27405
|
const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
|
|
27059
|
-
const content =
|
|
27060
|
-
const testDir =
|
|
27406
|
+
const content = fs25.readFileSync(absoluteTestFile, "utf-8");
|
|
27407
|
+
const testDir = path54.dirname(absoluteTestFile);
|
|
27061
27408
|
const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
|
|
27062
27409
|
let match;
|
|
27063
27410
|
match = importRegex.exec(content);
|
|
@@ -27065,8 +27412,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
27065
27412
|
const importPath = match[1];
|
|
27066
27413
|
let resolvedImport;
|
|
27067
27414
|
if (importPath.startsWith(".")) {
|
|
27068
|
-
resolvedImport =
|
|
27069
|
-
const existingExt =
|
|
27415
|
+
resolvedImport = path54.resolve(testDir, importPath);
|
|
27416
|
+
const existingExt = path54.extname(resolvedImport);
|
|
27070
27417
|
if (!existingExt) {
|
|
27071
27418
|
for (const extToTry of [
|
|
27072
27419
|
".ts",
|
|
@@ -27077,7 +27424,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
27077
27424
|
".cjs"
|
|
27078
27425
|
]) {
|
|
27079
27426
|
const withExt = resolvedImport + extToTry;
|
|
27080
|
-
if (absoluteSourceFiles.includes(withExt) ||
|
|
27427
|
+
if (absoluteSourceFiles.includes(withExt) || fs25.existsSync(withExt)) {
|
|
27081
27428
|
resolvedImport = withExt;
|
|
27082
27429
|
break;
|
|
27083
27430
|
}
|
|
@@ -27086,12 +27433,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
27086
27433
|
} else {
|
|
27087
27434
|
continue;
|
|
27088
27435
|
}
|
|
27089
|
-
const importBasename =
|
|
27090
|
-
const importDir =
|
|
27436
|
+
const importBasename = path54.basename(resolvedImport, path54.extname(resolvedImport));
|
|
27437
|
+
const importDir = path54.dirname(resolvedImport);
|
|
27091
27438
|
for (const sourceFile of absoluteSourceFiles) {
|
|
27092
|
-
const sourceDir =
|
|
27093
|
-
const sourceBasename =
|
|
27094
|
-
const isRelatedDir = importDir === sourceDir || importDir ===
|
|
27439
|
+
const sourceDir = path54.dirname(sourceFile);
|
|
27440
|
+
const sourceBasename = path54.basename(sourceFile, path54.extname(sourceFile));
|
|
27441
|
+
const isRelatedDir = importDir === sourceDir || importDir === path54.join(sourceDir, "__tests__") || importDir === path54.join(sourceDir, "tests") || importDir === path54.join(sourceDir, "test") || importDir === path54.join(sourceDir, "spec");
|
|
27095
27442
|
if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
|
|
27096
27443
|
dedupePush(testFiles, testFile);
|
|
27097
27444
|
break;
|
|
@@ -27104,8 +27451,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
27104
27451
|
while (match !== null) {
|
|
27105
27452
|
const importPath = match[1];
|
|
27106
27453
|
if (importPath.startsWith(".")) {
|
|
27107
|
-
let resolvedImport =
|
|
27108
|
-
const existingExt =
|
|
27454
|
+
let resolvedImport = path54.resolve(testDir, importPath);
|
|
27455
|
+
const existingExt = path54.extname(resolvedImport);
|
|
27109
27456
|
if (!existingExt) {
|
|
27110
27457
|
for (const extToTry of [
|
|
27111
27458
|
".ts",
|
|
@@ -27116,18 +27463,18 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
|
|
|
27116
27463
|
".cjs"
|
|
27117
27464
|
]) {
|
|
27118
27465
|
const withExt = resolvedImport + extToTry;
|
|
27119
|
-
if (absoluteSourceFiles.includes(withExt) ||
|
|
27466
|
+
if (absoluteSourceFiles.includes(withExt) || fs25.existsSync(withExt)) {
|
|
27120
27467
|
resolvedImport = withExt;
|
|
27121
27468
|
break;
|
|
27122
27469
|
}
|
|
27123
27470
|
}
|
|
27124
27471
|
}
|
|
27125
|
-
const importDir =
|
|
27126
|
-
const importBasename =
|
|
27472
|
+
const importDir = path54.dirname(resolvedImport);
|
|
27473
|
+
const importBasename = path54.basename(resolvedImport, path54.extname(resolvedImport));
|
|
27127
27474
|
for (const sourceFile of absoluteSourceFiles) {
|
|
27128
|
-
const sourceDir =
|
|
27129
|
-
const sourceBasename =
|
|
27130
|
-
const isRelatedDir = importDir === sourceDir || importDir ===
|
|
27475
|
+
const sourceDir = path54.dirname(sourceFile);
|
|
27476
|
+
const sourceBasename = path54.basename(sourceFile, path54.extname(sourceFile));
|
|
27477
|
+
const isRelatedDir = importDir === sourceDir || importDir === path54.join(sourceDir, "__tests__") || importDir === path54.join(sourceDir, "tests") || importDir === path54.join(sourceDir, "test") || importDir === path54.join(sourceDir, "spec");
|
|
27131
27478
|
if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
|
|
27132
27479
|
dedupePush(testFiles, testFile);
|
|
27133
27480
|
break;
|
|
@@ -27247,8 +27594,8 @@ function buildTestCommand(framework, scope, files, coverage, baseDir, bail) {
|
|
|
27247
27594
|
return ["mvn", "test"];
|
|
27248
27595
|
case "gradle": {
|
|
27249
27596
|
const isWindows = process.platform === "win32";
|
|
27250
|
-
const hasGradlewBat =
|
|
27251
|
-
const hasGradlew =
|
|
27597
|
+
const hasGradlewBat = fs25.existsSync(path54.join(baseDir, "gradlew.bat"));
|
|
27598
|
+
const hasGradlew = fs25.existsSync(path54.join(baseDir, "gradlew"));
|
|
27252
27599
|
if (hasGradlewBat && isWindows)
|
|
27253
27600
|
return ["gradlew.bat", "test"];
|
|
27254
27601
|
if (hasGradlew)
|
|
@@ -27265,7 +27612,7 @@ function buildTestCommand(framework, scope, files, coverage, baseDir, bail) {
|
|
|
27265
27612
|
"cmake-build-release",
|
|
27266
27613
|
"out"
|
|
27267
27614
|
];
|
|
27268
|
-
const actualBuildDir = buildDirCandidates.find((d) =>
|
|
27615
|
+
const actualBuildDir = buildDirCandidates.find((d) => fs25.existsSync(path54.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
|
|
27269
27616
|
return ["ctest", "--test-dir", actualBuildDir];
|
|
27270
27617
|
}
|
|
27271
27618
|
case "swift-test":
|
|
@@ -27699,13 +28046,13 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail
|
|
|
27699
28046
|
};
|
|
27700
28047
|
}
|
|
27701
28048
|
const startTime = Date.now();
|
|
27702
|
-
const vitestJsonOutputPath = framework === "vitest" ?
|
|
28049
|
+
const vitestJsonOutputPath = framework === "vitest" ? path54.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
|
|
27703
28050
|
try {
|
|
27704
28051
|
if (vitestJsonOutputPath) {
|
|
27705
28052
|
try {
|
|
27706
|
-
|
|
27707
|
-
if (
|
|
27708
|
-
|
|
28053
|
+
fs25.mkdirSync(path54.dirname(vitestJsonOutputPath), { recursive: true });
|
|
28054
|
+
if (fs25.existsSync(vitestJsonOutputPath)) {
|
|
28055
|
+
fs25.unlinkSync(vitestJsonOutputPath);
|
|
27709
28056
|
}
|
|
27710
28057
|
} catch {}
|
|
27711
28058
|
}
|
|
@@ -27731,8 +28078,8 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail
|
|
|
27731
28078
|
}
|
|
27732
28079
|
if (vitestJsonOutputPath) {
|
|
27733
28080
|
try {
|
|
27734
|
-
if (
|
|
27735
|
-
const vitestJsonOutput =
|
|
28081
|
+
if (fs25.existsSync(vitestJsonOutputPath)) {
|
|
28082
|
+
const vitestJsonOutput = fs25.readFileSync(vitestJsonOutputPath, "utf-8");
|
|
27736
28083
|
if (vitestJsonOutput.trim().length > 0) {
|
|
27737
28084
|
output += (output ? `
|
|
27738
28085
|
` : "") + vitestJsonOutput;
|
|
@@ -27871,10 +28218,10 @@ var SKIP_DIRECTORIES = new Set([
|
|
|
27871
28218
|
]);
|
|
27872
28219
|
function normalizeHistoryTestFile(testFile, workingDir) {
|
|
27873
28220
|
const normalized = testFile.replace(/\\/g, "/");
|
|
27874
|
-
if (!
|
|
28221
|
+
if (!path54.isAbsolute(testFile))
|
|
27875
28222
|
return normalized;
|
|
27876
|
-
const relative8 =
|
|
27877
|
-
if (relative8.startsWith("..") ||
|
|
28223
|
+
const relative8 = path54.relative(workingDir, testFile);
|
|
28224
|
+
if (relative8.startsWith("..") || path54.isAbsolute(relative8)) {
|
|
27878
28225
|
return normalized;
|
|
27879
28226
|
}
|
|
27880
28227
|
return relative8.replace(/\\/g, "/");
|
|
@@ -28113,7 +28460,7 @@ var test_runner = createSwarmTool({
|
|
|
28113
28460
|
const sourceFiles = args.files.filter((file) => {
|
|
28114
28461
|
if (directTestFiles.includes(file))
|
|
28115
28462
|
return false;
|
|
28116
|
-
const ext =
|
|
28463
|
+
const ext = path54.extname(file).toLowerCase();
|
|
28117
28464
|
return SOURCE_EXTENSIONS.has(ext);
|
|
28118
28465
|
});
|
|
28119
28466
|
const invalidFiles = args.files.filter((file) => !directTestFiles.includes(file) && !sourceFiles.includes(file));
|
|
@@ -28159,7 +28506,7 @@ var test_runner = createSwarmTool({
|
|
|
28159
28506
|
if (isConventionTestFilePath(f)) {
|
|
28160
28507
|
return false;
|
|
28161
28508
|
}
|
|
28162
|
-
const ext =
|
|
28509
|
+
const ext = path54.extname(f).toLowerCase();
|
|
28163
28510
|
return SOURCE_EXTENSIONS.has(ext);
|
|
28164
28511
|
});
|
|
28165
28512
|
if (sourceFiles.length === 0) {
|
|
@@ -28209,7 +28556,7 @@ var test_runner = createSwarmTool({
|
|
|
28209
28556
|
if (isConventionTestFilePath(f)) {
|
|
28210
28557
|
return false;
|
|
28211
28558
|
}
|
|
28212
|
-
const ext =
|
|
28559
|
+
const ext = path54.extname(f).toLowerCase();
|
|
28213
28560
|
return SOURCE_EXTENSIONS.has(ext);
|
|
28214
28561
|
});
|
|
28215
28562
|
if (sourceFiles.length === 0) {
|
|
@@ -28261,8 +28608,8 @@ var test_runner = createSwarmTool({
|
|
|
28261
28608
|
}
|
|
28262
28609
|
if (impactResult.impactedTests.length > 0) {
|
|
28263
28610
|
testFiles = impactResult.impactedTests.map((absPath) => {
|
|
28264
|
-
const relativePath =
|
|
28265
|
-
return
|
|
28611
|
+
const relativePath = path54.relative(workingDir, absPath);
|
|
28612
|
+
return path54.isAbsolute(relativePath) ? absPath : relativePath;
|
|
28266
28613
|
});
|
|
28267
28614
|
} else {
|
|
28268
28615
|
graphFallbackReason = "no impacted tests found via impact analysis, falling back to graph";
|
|
@@ -28357,8 +28704,8 @@ function validateDirectoryPath(dir) {
|
|
|
28357
28704
|
if (dir.includes("..")) {
|
|
28358
28705
|
throw new Error("Directory path must not contain path traversal sequences");
|
|
28359
28706
|
}
|
|
28360
|
-
const normalized =
|
|
28361
|
-
const absolutePath =
|
|
28707
|
+
const normalized = path55.normalize(dir);
|
|
28708
|
+
const absolutePath = path55.isAbsolute(normalized) ? normalized : path55.resolve(normalized);
|
|
28362
28709
|
return absolutePath;
|
|
28363
28710
|
}
|
|
28364
28711
|
function validateTimeout(timeoutMs, defaultValue) {
|
|
@@ -28381,9 +28728,9 @@ function validateTimeout(timeoutMs, defaultValue) {
|
|
|
28381
28728
|
}
|
|
28382
28729
|
function getPackageVersion(dir) {
|
|
28383
28730
|
try {
|
|
28384
|
-
const packagePath =
|
|
28385
|
-
if (
|
|
28386
|
-
const content =
|
|
28731
|
+
const packagePath = path55.join(dir, "package.json");
|
|
28732
|
+
if (fs26.existsSync(packagePath)) {
|
|
28733
|
+
const content = fs26.readFileSync(packagePath, "utf-8");
|
|
28387
28734
|
const pkg = JSON.parse(content);
|
|
28388
28735
|
return pkg.version ?? null;
|
|
28389
28736
|
}
|
|
@@ -28392,9 +28739,9 @@ function getPackageVersion(dir) {
|
|
|
28392
28739
|
}
|
|
28393
28740
|
function getChangelogVersion(dir) {
|
|
28394
28741
|
try {
|
|
28395
|
-
const changelogPath =
|
|
28396
|
-
if (
|
|
28397
|
-
const content =
|
|
28742
|
+
const changelogPath = path55.join(dir, "CHANGELOG.md");
|
|
28743
|
+
if (fs26.existsSync(changelogPath)) {
|
|
28744
|
+
const content = fs26.readFileSync(changelogPath, "utf-8");
|
|
28398
28745
|
const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
|
|
28399
28746
|
if (match) {
|
|
28400
28747
|
return match[1];
|
|
@@ -28406,10 +28753,10 @@ function getChangelogVersion(dir) {
|
|
|
28406
28753
|
function getVersionFileVersion(dir) {
|
|
28407
28754
|
const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
|
|
28408
28755
|
for (const file of possibleFiles) {
|
|
28409
|
-
const filePath =
|
|
28410
|
-
if (
|
|
28756
|
+
const filePath = path55.join(dir, file);
|
|
28757
|
+
if (fs26.existsSync(filePath)) {
|
|
28411
28758
|
try {
|
|
28412
|
-
const content =
|
|
28759
|
+
const content = fs26.readFileSync(filePath, "utf-8").trim();
|
|
28413
28760
|
const match = content.match(/(\d+\.\d+\.\d+)/);
|
|
28414
28761
|
if (match) {
|
|
28415
28762
|
return match[1];
|
|
@@ -29143,8 +29490,8 @@ async function handleQaGatesCommand(directory, args, sessionID) {
|
|
|
29143
29490
|
}
|
|
29144
29491
|
|
|
29145
29492
|
// src/commands/reset.ts
|
|
29146
|
-
import * as
|
|
29147
|
-
import * as
|
|
29493
|
+
import * as fs27 from "fs";
|
|
29494
|
+
import * as path56 from "path";
|
|
29148
29495
|
|
|
29149
29496
|
// src/background/circuit-breaker.ts
|
|
29150
29497
|
class CircuitBreaker {
|
|
@@ -29851,8 +30198,8 @@ async function handleResetCommand(directory, args) {
|
|
|
29851
30198
|
for (const filename of filesToReset) {
|
|
29852
30199
|
try {
|
|
29853
30200
|
const resolvedPath = validateSwarmPath(directory, filename);
|
|
29854
|
-
if (
|
|
29855
|
-
|
|
30201
|
+
if (fs27.existsSync(resolvedPath)) {
|
|
30202
|
+
fs27.unlinkSync(resolvedPath);
|
|
29856
30203
|
results.push(`- \u2705 Deleted ${filename}`);
|
|
29857
30204
|
} else {
|
|
29858
30205
|
results.push(`- \u23ED\uFE0F ${filename} not found (skipped)`);
|
|
@@ -29863,9 +30210,9 @@ async function handleResetCommand(directory, args) {
|
|
|
29863
30210
|
}
|
|
29864
30211
|
for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
|
|
29865
30212
|
try {
|
|
29866
|
-
const rootPath =
|
|
29867
|
-
if (
|
|
29868
|
-
|
|
30213
|
+
const rootPath = path56.join(directory, filename);
|
|
30214
|
+
if (fs27.existsSync(rootPath)) {
|
|
30215
|
+
fs27.unlinkSync(rootPath);
|
|
29869
30216
|
results.push(`- \u2705 Deleted ${filename} (root)`);
|
|
29870
30217
|
}
|
|
29871
30218
|
} catch (err) {
|
|
@@ -29880,8 +30227,8 @@ async function handleResetCommand(directory, args) {
|
|
|
29880
30227
|
}
|
|
29881
30228
|
try {
|
|
29882
30229
|
const summariesPath = validateSwarmPath(directory, "summaries");
|
|
29883
|
-
if (
|
|
29884
|
-
|
|
30230
|
+
if (fs27.existsSync(summariesPath)) {
|
|
30231
|
+
fs27.rmSync(summariesPath, { recursive: true, force: true });
|
|
29885
30232
|
results.push("- \u2705 Deleted summaries/ directory");
|
|
29886
30233
|
} else {
|
|
29887
30234
|
results.push("- \u23ED\uFE0F summaries/ not found (skipped)");
|
|
@@ -29900,8 +30247,8 @@ async function handleResetCommand(directory, args) {
|
|
|
29900
30247
|
}
|
|
29901
30248
|
|
|
29902
30249
|
// src/commands/reset-session.ts
|
|
29903
|
-
import * as
|
|
29904
|
-
import * as
|
|
30250
|
+
import * as fs29 from "fs";
|
|
30251
|
+
import * as path58 from "path";
|
|
29905
30252
|
|
|
29906
30253
|
// src/hooks/trajectory-logger.ts
|
|
29907
30254
|
var callStartTimes = new Map;
|
|
@@ -30307,17 +30654,17 @@ function detectPatterns(trajectory, config, lastProcessedStep = 0) {
|
|
|
30307
30654
|
};
|
|
30308
30655
|
}
|
|
30309
30656
|
// src/prm/replay.ts
|
|
30310
|
-
import { promises as
|
|
30311
|
-
import
|
|
30657
|
+
import { promises as fs28 } from "fs";
|
|
30658
|
+
import path57 from "path";
|
|
30312
30659
|
function isPathSafe(targetPath, basePath) {
|
|
30313
|
-
const resolvedTarget =
|
|
30314
|
-
const resolvedBase =
|
|
30315
|
-
const rel =
|
|
30316
|
-
return !rel.startsWith("..") && !
|
|
30660
|
+
const resolvedTarget = path57.resolve(targetPath);
|
|
30661
|
+
const resolvedBase = path57.resolve(basePath);
|
|
30662
|
+
const rel = path57.relative(resolvedBase, resolvedTarget);
|
|
30663
|
+
return !rel.startsWith("..") && !path57.isAbsolute(rel);
|
|
30317
30664
|
}
|
|
30318
30665
|
function isWithinReplaysDir(targetPath) {
|
|
30319
|
-
const resolved =
|
|
30320
|
-
const parts = resolved.split(
|
|
30666
|
+
const resolved = path57.resolve(targetPath);
|
|
30667
|
+
const parts = resolved.split(path57.sep);
|
|
30321
30668
|
for (let i = 0;i < parts.length - 1; i++) {
|
|
30322
30669
|
if (parts[i] === ".swarm" && parts[i + 1] === "replays") {
|
|
30323
30670
|
return true;
|
|
@@ -30330,15 +30677,15 @@ function sanitizeFilename(input) {
|
|
|
30330
30677
|
}
|
|
30331
30678
|
async function startReplayRecording(sessionID, directory) {
|
|
30332
30679
|
try {
|
|
30333
|
-
const replayDir =
|
|
30680
|
+
const replayDir = path57.join(directory, ".swarm", "replays");
|
|
30334
30681
|
const safeSessionID = sanitizeFilename(sessionID);
|
|
30335
30682
|
const filename = `${safeSessionID}-${Date.now()}.jsonl`;
|
|
30336
|
-
const filepath =
|
|
30683
|
+
const filepath = path57.join(replayDir, filename);
|
|
30337
30684
|
if (!isPathSafe(filepath, replayDir)) {
|
|
30338
30685
|
console.warn(`[replay] Invalid path detected - path traversal attempt blocked for session ${sessionID}`);
|
|
30339
30686
|
return null;
|
|
30340
30687
|
}
|
|
30341
|
-
await
|
|
30688
|
+
await fs28.mkdir(replayDir, { recursive: true });
|
|
30342
30689
|
return filepath;
|
|
30343
30690
|
} catch (err) {
|
|
30344
30691
|
console.warn(`[replay] Failed to start recording for session ${sessionID}: ${err}`);
|
|
@@ -30358,7 +30705,7 @@ async function recordReplayEntry(artifactPath, sessionID, entry) {
|
|
|
30358
30705
|
};
|
|
30359
30706
|
const line = `${JSON.stringify(fullEntry)}
|
|
30360
30707
|
`;
|
|
30361
|
-
await
|
|
30708
|
+
await fs28.appendFile(artifactPath, line, "utf-8");
|
|
30362
30709
|
} catch (err) {
|
|
30363
30710
|
console.warn(`[replay] Failed to record entry: ${err}`);
|
|
30364
30711
|
}
|
|
@@ -30402,8 +30749,8 @@ async function handleResetSessionCommand(directory, _args) {
|
|
|
30402
30749
|
const results = [];
|
|
30403
30750
|
try {
|
|
30404
30751
|
const statePath = validateSwarmPath(directory, "session/state.json");
|
|
30405
|
-
if (
|
|
30406
|
-
|
|
30752
|
+
if (fs29.existsSync(statePath)) {
|
|
30753
|
+
fs29.unlinkSync(statePath);
|
|
30407
30754
|
results.push("\u2705 Deleted .swarm/session/state.json");
|
|
30408
30755
|
} else {
|
|
30409
30756
|
results.push("\u23ED\uFE0F state.json not found (already clean)");
|
|
@@ -30411,11 +30758,11 @@ async function handleResetSessionCommand(directory, _args) {
|
|
|
30411
30758
|
} catch {
|
|
30412
30759
|
results.push("\u274C Failed to delete state.json");
|
|
30413
30760
|
}
|
|
30414
|
-
const sessionDir =
|
|
30761
|
+
const sessionDir = path58.dirname(validateSwarmPath(directory, "session/state.json"));
|
|
30415
30762
|
let sessionFiles = [];
|
|
30416
|
-
if (
|
|
30763
|
+
if (fs29.existsSync(sessionDir)) {
|
|
30417
30764
|
try {
|
|
30418
|
-
sessionFiles =
|
|
30765
|
+
sessionFiles = fs29.readdirSync(sessionDir);
|
|
30419
30766
|
} catch (err) {
|
|
30420
30767
|
results.push(`\u274C Failed to read session directory: ${errorMessage(err)}`);
|
|
30421
30768
|
}
|
|
@@ -30423,13 +30770,13 @@ async function handleResetSessionCommand(directory, _args) {
|
|
|
30423
30770
|
for (const file of sessionFiles) {
|
|
30424
30771
|
if (file === "state.json")
|
|
30425
30772
|
continue;
|
|
30426
|
-
const filePath =
|
|
30773
|
+
const filePath = path58.join(sessionDir, file);
|
|
30427
30774
|
try {
|
|
30428
|
-
if (!
|
|
30775
|
+
if (!fs29.existsSync(filePath))
|
|
30429
30776
|
continue;
|
|
30430
|
-
if (!
|
|
30777
|
+
if (!fs29.lstatSync(filePath).isFile())
|
|
30431
30778
|
continue;
|
|
30432
|
-
|
|
30779
|
+
fs29.unlinkSync(filePath);
|
|
30433
30780
|
results.push(`\u2713 Deleted ${file}`);
|
|
30434
30781
|
} catch (err) {
|
|
30435
30782
|
results.push(`\u274C Failed to delete ${file}: ${errorMessage(err)}`);
|
|
@@ -30458,7 +30805,7 @@ async function handleResetSessionCommand(directory, _args) {
|
|
|
30458
30805
|
}
|
|
30459
30806
|
|
|
30460
30807
|
// src/summaries/manager.ts
|
|
30461
|
-
import * as
|
|
30808
|
+
import * as path59 from "path";
|
|
30462
30809
|
var SUMMARY_ID_REGEX = /^S\d+$/;
|
|
30463
30810
|
function sanitizeSummaryId(id) {
|
|
30464
30811
|
if (!id || id.length === 0) {
|
|
@@ -30482,7 +30829,7 @@ function sanitizeSummaryId(id) {
|
|
|
30482
30829
|
}
|
|
30483
30830
|
async function loadFullOutput(directory, id) {
|
|
30484
30831
|
const sanitizedId = sanitizeSummaryId(id);
|
|
30485
|
-
const relativePath =
|
|
30832
|
+
const relativePath = path59.join("summaries", `${sanitizedId}.json`);
|
|
30486
30833
|
validateSwarmPath(directory, relativePath);
|
|
30487
30834
|
const content = await readSwarmFileAsync(directory, relativePath);
|
|
30488
30835
|
if (content === null) {
|
|
@@ -30534,18 +30881,18 @@ ${error2 instanceof Error ? error2.message : String(error2)}`;
|
|
|
30534
30881
|
}
|
|
30535
30882
|
|
|
30536
30883
|
// src/commands/rollback.ts
|
|
30537
|
-
import * as
|
|
30538
|
-
import * as
|
|
30884
|
+
import * as fs30 from "fs";
|
|
30885
|
+
import * as path60 from "path";
|
|
30539
30886
|
async function handleRollbackCommand(directory, args) {
|
|
30540
30887
|
const phaseArg = args[0];
|
|
30541
30888
|
if (!phaseArg) {
|
|
30542
30889
|
const manifestPath2 = validateSwarmPath(directory, "checkpoints/manifest.json");
|
|
30543
|
-
if (!
|
|
30890
|
+
if (!fs30.existsSync(manifestPath2)) {
|
|
30544
30891
|
return "No checkpoints found. Use `/swarm checkpoint` to create checkpoints.";
|
|
30545
30892
|
}
|
|
30546
30893
|
let manifest2;
|
|
30547
30894
|
try {
|
|
30548
|
-
manifest2 = JSON.parse(
|
|
30895
|
+
manifest2 = JSON.parse(fs30.readFileSync(manifestPath2, "utf-8"));
|
|
30549
30896
|
} catch {
|
|
30550
30897
|
return "Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.";
|
|
30551
30898
|
}
|
|
@@ -30567,12 +30914,12 @@ async function handleRollbackCommand(directory, args) {
|
|
|
30567
30914
|
return "Error: Phase number must be a positive integer.";
|
|
30568
30915
|
}
|
|
30569
30916
|
const manifestPath = validateSwarmPath(directory, "checkpoints/manifest.json");
|
|
30570
|
-
if (!
|
|
30917
|
+
if (!fs30.existsSync(manifestPath)) {
|
|
30571
30918
|
return `Error: No checkpoints found. Cannot rollback to phase ${targetPhase}.`;
|
|
30572
30919
|
}
|
|
30573
30920
|
let manifest;
|
|
30574
30921
|
try {
|
|
30575
|
-
manifest = JSON.parse(
|
|
30922
|
+
manifest = JSON.parse(fs30.readFileSync(manifestPath, "utf-8"));
|
|
30576
30923
|
} catch {
|
|
30577
30924
|
return `Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.`;
|
|
30578
30925
|
}
|
|
@@ -30582,10 +30929,10 @@ async function handleRollbackCommand(directory, args) {
|
|
|
30582
30929
|
return `Error: Checkpoint for phase ${targetPhase} not found. Available phases: ${available}`;
|
|
30583
30930
|
}
|
|
30584
30931
|
const checkpointDir = validateSwarmPath(directory, `checkpoints/phase-${targetPhase}`);
|
|
30585
|
-
if (!
|
|
30932
|
+
if (!fs30.existsSync(checkpointDir)) {
|
|
30586
30933
|
return `Error: Checkpoint directory for phase ${targetPhase} does not exist.`;
|
|
30587
30934
|
}
|
|
30588
|
-
const checkpointFiles =
|
|
30935
|
+
const checkpointFiles = fs30.readdirSync(checkpointDir);
|
|
30589
30936
|
if (checkpointFiles.length === 0) {
|
|
30590
30937
|
return `Error: Checkpoint for phase ${targetPhase} is empty. Cannot rollback.`;
|
|
30591
30938
|
}
|
|
@@ -30601,10 +30948,10 @@ async function handleRollbackCommand(directory, args) {
|
|
|
30601
30948
|
if (EXCLUDE_FILES.has(file) || file.startsWith("plan-ledger.archived-")) {
|
|
30602
30949
|
continue;
|
|
30603
30950
|
}
|
|
30604
|
-
const src =
|
|
30605
|
-
const dest =
|
|
30951
|
+
const src = path60.join(checkpointDir, file);
|
|
30952
|
+
const dest = path60.join(swarmDir, file);
|
|
30606
30953
|
try {
|
|
30607
|
-
|
|
30954
|
+
fs30.cpSync(src, dest, { recursive: true, force: true });
|
|
30608
30955
|
successes.push(file);
|
|
30609
30956
|
} catch (error2) {
|
|
30610
30957
|
failures.push({ file, error: error2.message });
|
|
@@ -30621,11 +30968,11 @@ async function handleRollbackCommand(directory, args) {
|
|
|
30621
30968
|
].join(`
|
|
30622
30969
|
`);
|
|
30623
30970
|
}
|
|
30624
|
-
const existingLedgerPath =
|
|
30971
|
+
const existingLedgerPath = path60.join(swarmDir, "plan-ledger.jsonl");
|
|
30625
30972
|
let ledgerDeletionFailed = false;
|
|
30626
|
-
if (
|
|
30973
|
+
if (fs30.existsSync(existingLedgerPath)) {
|
|
30627
30974
|
try {
|
|
30628
|
-
|
|
30975
|
+
fs30.unlinkSync(existingLedgerPath);
|
|
30629
30976
|
} catch (err) {
|
|
30630
30977
|
ledgerDeletionFailed = true;
|
|
30631
30978
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
@@ -30634,9 +30981,9 @@ async function handleRollbackCommand(directory, args) {
|
|
|
30634
30981
|
}
|
|
30635
30982
|
if (!ledgerDeletionFailed) {
|
|
30636
30983
|
try {
|
|
30637
|
-
const planJsonPath =
|
|
30638
|
-
if (
|
|
30639
|
-
const planRaw =
|
|
30984
|
+
const planJsonPath = path60.join(swarmDir, "plan.json");
|
|
30985
|
+
if (fs30.existsSync(planJsonPath)) {
|
|
30986
|
+
const planRaw = fs30.readFileSync(planJsonPath, "utf-8");
|
|
30640
30987
|
const plan = PlanSchema.parse(JSON.parse(planRaw));
|
|
30641
30988
|
const planId = derivePlanId(plan);
|
|
30642
30989
|
const planHash = computePlanHash(plan);
|
|
@@ -30664,7 +31011,7 @@ async function handleRollbackCommand(directory, args) {
|
|
|
30664
31011
|
timestamp: new Date().toISOString()
|
|
30665
31012
|
};
|
|
30666
31013
|
try {
|
|
30667
|
-
|
|
31014
|
+
fs30.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
|
|
30668
31015
|
`);
|
|
30669
31016
|
} catch (error2) {
|
|
30670
31017
|
console.error("Failed to write rollback event:", error2 instanceof Error ? error2.message : String(error2));
|
|
@@ -30846,7 +31193,7 @@ async function handleSddCommand(_directory, _args) {
|
|
|
30846
31193
|
}
|
|
30847
31194
|
|
|
30848
31195
|
// src/commands/simulate.ts
|
|
30849
|
-
import { renameSync as renameSync11, unlinkSync as
|
|
31196
|
+
import { renameSync as renameSync11, unlinkSync as unlinkSync12 } from "fs";
|
|
30850
31197
|
async function handleSimulateCommand(directory, args) {
|
|
30851
31198
|
const thresholdIndex = args.indexOf("--threshold");
|
|
30852
31199
|
const minCommitsIndex = args.indexOf("--min-commits");
|
|
@@ -30894,17 +31241,17 @@ Ensure this is a git repository with commit history.`;
|
|
|
30894
31241
|
const report = reportLines.filter(Boolean).join(`
|
|
30895
31242
|
`);
|
|
30896
31243
|
try {
|
|
30897
|
-
const
|
|
30898
|
-
const
|
|
30899
|
-
const reportPath =
|
|
30900
|
-
await
|
|
30901
|
-
const reportTempPath =
|
|
31244
|
+
const fs31 = await import("fs/promises");
|
|
31245
|
+
const path61 = await import("path");
|
|
31246
|
+
const reportPath = path61.join(directory, ".swarm", "simulate-report.md");
|
|
31247
|
+
await fs31.mkdir(path61.dirname(reportPath), { recursive: true });
|
|
31248
|
+
const reportTempPath = path61.join(path61.dirname(reportPath), `${path61.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
|
|
30902
31249
|
try {
|
|
30903
|
-
await
|
|
31250
|
+
await fs31.writeFile(reportTempPath, report, "utf-8");
|
|
30904
31251
|
renameSync11(reportTempPath, reportPath);
|
|
30905
31252
|
} catch (err) {
|
|
30906
31253
|
try {
|
|
30907
|
-
|
|
31254
|
+
unlinkSync12(reportTempPath);
|
|
30908
31255
|
} catch {}
|
|
30909
31256
|
throw err;
|
|
30910
31257
|
}
|
|
@@ -30927,20 +31274,20 @@ async function handleSpecifyCommand(_directory, args) {
|
|
|
30927
31274
|
// src/services/status-service.ts
|
|
30928
31275
|
import * as fsSync3 from "fs";
|
|
30929
31276
|
import { readFile as readFile16 } from "fs/promises";
|
|
30930
|
-
import * as
|
|
31277
|
+
import * as path62 from "path";
|
|
30931
31278
|
|
|
30932
31279
|
// src/turbo/lean/state.ts
|
|
30933
31280
|
init_logger();
|
|
30934
|
-
import * as
|
|
30935
|
-
import * as
|
|
31281
|
+
import * as fs31 from "fs";
|
|
31282
|
+
import * as path61 from "path";
|
|
30936
31283
|
var STATE_FILE3 = "turbo-state.json";
|
|
30937
31284
|
function nowISO3() {
|
|
30938
31285
|
return new Date().toISOString();
|
|
30939
31286
|
}
|
|
30940
31287
|
function ensureSwarmDir2(directory) {
|
|
30941
|
-
const swarmDir =
|
|
30942
|
-
if (!
|
|
30943
|
-
|
|
31288
|
+
const swarmDir = path61.resolve(directory, ".swarm");
|
|
31289
|
+
if (!fs31.existsSync(swarmDir)) {
|
|
31290
|
+
fs31.mkdirSync(swarmDir, { recursive: true });
|
|
30944
31291
|
}
|
|
30945
31292
|
return swarmDir;
|
|
30946
31293
|
}
|
|
@@ -30983,17 +31330,17 @@ function markStateUnreadable2(directory, reason) {
|
|
|
30983
31330
|
}
|
|
30984
31331
|
function readPersisted2(directory) {
|
|
30985
31332
|
try {
|
|
30986
|
-
const filePath =
|
|
30987
|
-
if (!
|
|
31333
|
+
const filePath = path61.join(directory, ".swarm", STATE_FILE3);
|
|
31334
|
+
if (!fs31.existsSync(filePath)) {
|
|
30988
31335
|
const seed = emptyPersisted2();
|
|
30989
31336
|
try {
|
|
30990
31337
|
ensureSwarmDir2(directory);
|
|
30991
|
-
|
|
31338
|
+
fs31.writeFileSync(filePath, `${JSON.stringify(seed, null, 2)}
|
|
30992
31339
|
`, "utf-8");
|
|
30993
31340
|
} catch {}
|
|
30994
31341
|
return seed;
|
|
30995
31342
|
}
|
|
30996
|
-
const raw =
|
|
31343
|
+
const raw = fs31.readFileSync(filePath, "utf-8");
|
|
30997
31344
|
const parsed = JSON.parse(raw);
|
|
30998
31345
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || parsed.version !== 1 || !parsed.sessions || typeof parsed.sessions !== "object" || Array.isArray(parsed.sessions)) {
|
|
30999
31346
|
markStateUnreadable2(directory, `malformed shape (version=${parsed?.version}, sessions type=${Array.isArray(parsed?.sessions) ? "array" : typeof parsed?.sessions})`);
|
|
@@ -31019,7 +31366,7 @@ function writePersisted2(directory, persisted) {
|
|
|
31019
31366
|
let payload;
|
|
31020
31367
|
try {
|
|
31021
31368
|
ensureSwarmDir2(directory);
|
|
31022
|
-
filePath =
|
|
31369
|
+
filePath = path61.join(directory, ".swarm", STATE_FILE3);
|
|
31023
31370
|
tmpPath = `${filePath}.tmp.${Date.now()}`;
|
|
31024
31371
|
persisted.updatedAt = nowISO3();
|
|
31025
31372
|
payload = `${JSON.stringify(persisted, null, 2)}
|
|
@@ -31030,14 +31377,14 @@ function writePersisted2(directory, persisted) {
|
|
|
31030
31377
|
throw new Error(`Lean Turbo state persistence prepare failed: ${msg}`);
|
|
31031
31378
|
}
|
|
31032
31379
|
try {
|
|
31033
|
-
|
|
31034
|
-
|
|
31380
|
+
fs31.writeFileSync(tmpPath, payload, "utf-8");
|
|
31381
|
+
fs31.renameSync(tmpPath, filePath);
|
|
31035
31382
|
} catch (error2) {
|
|
31036
31383
|
const msg = error2 instanceof Error ? error2.message : String(error2);
|
|
31037
31384
|
error(`[turbo/lean/state] Failed to persist ${STATE_FILE3} atomically: ${msg}`);
|
|
31038
31385
|
try {
|
|
31039
|
-
if (
|
|
31040
|
-
|
|
31386
|
+
if (fs31.existsSync(tmpPath)) {
|
|
31387
|
+
fs31.unlinkSync(tmpPath);
|
|
31041
31388
|
}
|
|
31042
31389
|
} catch {}
|
|
31043
31390
|
throw new Error(`Lean Turbo state persistence failed: ${msg}`);
|
|
@@ -31137,7 +31484,7 @@ var _internals43 = {
|
|
|
31137
31484
|
};
|
|
31138
31485
|
function readSpecStalenessSnapshot(directory) {
|
|
31139
31486
|
try {
|
|
31140
|
-
const p =
|
|
31487
|
+
const p = path62.join(directory, ".swarm", "spec-staleness.json");
|
|
31141
31488
|
if (!fsSync3.existsSync(p))
|
|
31142
31489
|
return { stale: false };
|
|
31143
31490
|
const raw = fsSync3.readFileSync(p, "utf-8");
|
|
@@ -31669,13 +32016,13 @@ function buildStatusMessage2(session, directory, sessionID) {
|
|
|
31669
32016
|
}
|
|
31670
32017
|
|
|
31671
32018
|
// src/commands/unlink.ts
|
|
31672
|
-
import { existsSync as
|
|
31673
|
-
import * as
|
|
32019
|
+
import { existsSync as existsSync37 } from "fs";
|
|
32020
|
+
import * as path63 from "path";
|
|
31674
32021
|
var DEDUP_THRESHOLD2 = 0.6;
|
|
31675
32022
|
async function copySharedKnowledgeToLocal(linkDir, localSwarmDir) {
|
|
31676
|
-
const sharedPath =
|
|
31677
|
-
const localPath =
|
|
31678
|
-
if (!
|
|
32023
|
+
const sharedPath = path63.join(linkDir, "knowledge.jsonl");
|
|
32024
|
+
const localPath = path63.join(localSwarmDir, "knowledge.jsonl");
|
|
32025
|
+
if (!existsSync37(sharedPath))
|
|
31679
32026
|
return 0;
|
|
31680
32027
|
const sharedEntries = await readKnowledge(sharedPath);
|
|
31681
32028
|
if (sharedEntries.length === 0)
|
|
@@ -31709,7 +32056,7 @@ async function handleUnlinkCommand(directory, args) {
|
|
|
31709
32056
|
let copied = 0;
|
|
31710
32057
|
if (copyBack) {
|
|
31711
32058
|
try {
|
|
31712
|
-
copied = await copySharedKnowledgeToLocal(linkDir,
|
|
32059
|
+
copied = await copySharedKnowledgeToLocal(linkDir, path63.join(directory, ".swarm"));
|
|
31713
32060
|
} catch (error2) {
|
|
31714
32061
|
return `\u274C Failed to copy shared knowledge back to local: ${error2 instanceof Error ? error2.message : String(error2)}`;
|
|
31715
32062
|
}
|
|
@@ -31864,7 +32211,7 @@ function buildDetailedHelp(commandName, entry) {
|
|
|
31864
32211
|
async function handleHelpCommand(ctx) {
|
|
31865
32212
|
const targetCommand = ctx.args.join(" ");
|
|
31866
32213
|
if (!targetCommand) {
|
|
31867
|
-
const { buildHelpText } = await import("./index-
|
|
32214
|
+
const { buildHelpText } = await import("./index-xy3gw0rw.js");
|
|
31868
32215
|
return buildHelpText();
|
|
31869
32216
|
}
|
|
31870
32217
|
const tokens = targetCommand.split(/\s+/);
|
|
@@ -31873,7 +32220,7 @@ async function handleHelpCommand(ctx) {
|
|
|
31873
32220
|
return _internals45.buildDetailedHelp(resolved.key, resolved.entry);
|
|
31874
32221
|
}
|
|
31875
32222
|
const similar = _internals45.findSimilarCommands(targetCommand);
|
|
31876
|
-
const { buildHelpText: fullHelp } = await import("./index-
|
|
32223
|
+
const { buildHelpText: fullHelp } = await import("./index-xy3gw0rw.js");
|
|
31877
32224
|
if (similar.length > 0) {
|
|
31878
32225
|
return `Command '/swarm ${targetCommand}' not found.
|
|
31879
32226
|
|
|
@@ -32006,7 +32353,7 @@ var COMMAND_REGISTRY = {
|
|
|
32006
32353
|
},
|
|
32007
32354
|
"guardrail explain": {
|
|
32008
32355
|
handler: async (ctx) => {
|
|
32009
|
-
const { handleGuardrailExplain } = await import("./guardrail-explain-
|
|
32356
|
+
const { handleGuardrailExplain } = await import("./guardrail-explain-6g1japmf.js");
|
|
32010
32357
|
return handleGuardrailExplain(ctx.directory, ctx.args);
|
|
32011
32358
|
},
|
|
32012
32359
|
description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
|
|
@@ -32016,7 +32363,7 @@ var COMMAND_REGISTRY = {
|
|
|
32016
32363
|
},
|
|
32017
32364
|
"guardrail-log": {
|
|
32018
32365
|
handler: async (ctx) => {
|
|
32019
|
-
const { handleGuardrailLog } = await import("./guardrail-log-
|
|
32366
|
+
const { handleGuardrailLog } = await import("./guardrail-log-ya49kpwn.js");
|
|
32020
32367
|
return handleGuardrailLog(ctx.directory, ctx.args);
|
|
32021
32368
|
},
|
|
32022
32369
|
description: "Read the guardrail decision log (use --blocks-only for blocks)",
|
|
@@ -32041,8 +32388,15 @@ var COMMAND_REGISTRY = {
|
|
|
32041
32388
|
},
|
|
32042
32389
|
benchmark: {
|
|
32043
32390
|
handler: (ctx) => handleBenchmarkCommand(ctx.directory, ctx.args),
|
|
32044
|
-
description: "Show performance metrics [--cumulative] [--ci-gate]",
|
|
32045
|
-
args: "--cumulative, --ci-gate",
|
|
32391
|
+
description: "Show performance metrics [--cumulative] [--ci-gate] [--max-cost-usd <n>]",
|
|
32392
|
+
args: "--cumulative, --ci-gate, --max-cost-usd <n>",
|
|
32393
|
+
category: "diagnostics",
|
|
32394
|
+
toolPolicy: "agent"
|
|
32395
|
+
},
|
|
32396
|
+
costs: {
|
|
32397
|
+
handler: (ctx) => handleCostsCommand(ctx.directory, ctx.args),
|
|
32398
|
+
description: "Show per-agent and per-task token/cost telemetry [--json]",
|
|
32399
|
+
args: "--json",
|
|
32046
32400
|
category: "diagnostics",
|
|
32047
32401
|
toolPolicy: "agent"
|
|
32048
32402
|
},
|
|
@@ -32777,24 +33131,24 @@ function validateAliases() {
|
|
|
32777
33131
|
}
|
|
32778
33132
|
aliasTargets.get(target).push(name);
|
|
32779
33133
|
const visited = new Set;
|
|
32780
|
-
const
|
|
33134
|
+
const path64 = [];
|
|
32781
33135
|
let current = target;
|
|
32782
33136
|
while (current) {
|
|
32783
33137
|
const currentEntry = COMMAND_REGISTRY[current];
|
|
32784
33138
|
if (!currentEntry)
|
|
32785
33139
|
break;
|
|
32786
33140
|
if (visited.has(current)) {
|
|
32787
|
-
const cycleStart =
|
|
33141
|
+
const cycleStart = path64.indexOf(current);
|
|
32788
33142
|
const fullChain = [
|
|
32789
33143
|
name,
|
|
32790
|
-
...
|
|
33144
|
+
...path64.slice(0, cycleStart > 0 ? cycleStart : path64.length),
|
|
32791
33145
|
current
|
|
32792
33146
|
].join(" \u2192 ");
|
|
32793
33147
|
errors.push(`Circular alias detected: ${fullChain}`);
|
|
32794
33148
|
break;
|
|
32795
33149
|
}
|
|
32796
33150
|
visited.add(current);
|
|
32797
|
-
|
|
33151
|
+
path64.push(current);
|
|
32798
33152
|
current = currentEntry.aliasOf || "";
|
|
32799
33153
|
}
|
|
32800
33154
|
}
|
|
@@ -32960,4 +33314,4 @@ ${text}`;
|
|
|
32960
33314
|
};
|
|
32961
33315
|
}
|
|
32962
33316
|
|
|
32963
|
-
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, handleClarifyCommand, handleCloseCommand, handleCodebaseReviewCommand, handleConcurrencyCommand, handleConfigCommand, handleConsolidateCommand, handleCouncilCommand, handleCurateCommand, handleDarkMatterCommand, handleDeepDiveCommand, handleDeepResearchCommand, getPluginConfigDir, getPluginCachePaths, getPluginLockFilePaths, handleDiagnoseCommand, handleDoctorCommand, handleEvidenceCommand, handleEvidenceSummaryCommand, handleExportCommand, handleFullAutoCommand, handleHandoffCommand, handleHistoryCommand, handleKnowledgeQuarantineCommand, handleKnowledgeRestoreCommand, handleKnowledgeMigrateCommand, handleKnowledgeListCommand, handleKnowledgeUnactionableCommand, handleKnowledgeRetryHardeningCommand, handleLearningCommand, handleLinkCommand, handleMemoryCommand, handleMemoryStatusCommand, 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, _internals45 as _internals, resolveCommand };
|
|
33317
|
+
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, handleClarifyCommand, handleCloseCommand, handleCodebaseReviewCommand, handleConcurrencyCommand, handleConfigCommand, handleConsolidateCommand, handleCostsCommand, handleCouncilCommand, handleCurateCommand, handleDarkMatterCommand, handleDeepDiveCommand, handleDeepResearchCommand, getPluginConfigDir, getPluginCachePaths, getPluginLockFilePaths, handleDiagnoseCommand, handleDoctorCommand, handleEvidenceCommand, handleEvidenceSummaryCommand, handleExportCommand, handleFullAutoCommand, handleHandoffCommand, handleHistoryCommand, handleKnowledgeQuarantineCommand, handleKnowledgeRestoreCommand, handleKnowledgeMigrateCommand, handleKnowledgeListCommand, handleKnowledgeUnactionableCommand, handleKnowledgeRetryHardeningCommand, handleLearningCommand, handleLinkCommand, handleMemoryCommand, handleMemoryStatusCommand, 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, _internals45 as _internals, resolveCommand };
|