openfox 1.6.91 → 1.6.92
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{auto-compaction-I4YS2BN4.js → auto-compaction-7AGIGW6F.js} +6 -6
- package/dist/{chat-handler-O4FNSVPI.js → chat-handler-UPAEF6HR.js} +9 -9
- package/dist/{chunk-UQSL65WB.js → chunk-2BS6LMIU.js} +398 -470
- package/dist/{chunk-HKCUSLQ5.js → chunk-2TKN2X2A.js} +3 -3
- package/dist/{chunk-SSGVISQU.js → chunk-7KO2BQFQ.js} +8 -7
- package/dist/{chunk-II4UCFTE.js → chunk-7QG6LY5Q.js} +3 -3
- package/dist/{chunk-CL2ZPJAG.js → chunk-ARJIHQ3S.js} +225 -138
- package/dist/{chunk-H5T34J3H.js → chunk-BHZL3N2F.js} +3 -3
- package/dist/{chunk-MOQLMPTA.js → chunk-CHICEUV6.js} +3 -3
- package/dist/{chunk-STUSQVXQ.js → chunk-RJIPM7CO.js} +2 -2
- package/dist/{chunk-B5AP3RSV.js → chunk-RW25DL5R.js} +3 -3
- package/dist/{chunk-A3YOBYWJ.js → chunk-WBQNIWAQ.js} +5 -5
- package/dist/{chunk-DF5BZBP6.js → chunk-XGJ7HDQ7.js} +2 -2
- package/dist/{chunk-6P5WQP6Y.js → chunk-YTPPQK55.js} +2 -2
- package/dist/cli/dev.js +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/{config-GEDIDCBM.js → config-7XJQNOKX.js} +5 -5
- package/dist/{events-AQKDXJFK.js → events-K6AYMXFT.js} +3 -3
- package/dist/{orchestrator-LLOIG2CR.js → orchestrator-M4WINFF3.js} +7 -7
- package/dist/package.json +1 -1
- package/dist/{processor-XL5NULQN.js → processor-D4XQ5QMB.js} +5 -5
- package/dist/{protocol--8PKNwb_.d.ts → protocol-XRiJzlOK.d.ts} +1 -1
- package/dist/{provider-EV3KBC7Y.js → provider-UO5PAZQQ.js} +7 -7
- package/dist/{runtime-config-CBJJJGBD.js → runtime-config-CYHDAC7W.js} +2 -2
- package/dist/{serve-UWKYNKAO.js → serve-Z5FNJUDT.js} +11 -11
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +9 -9
- package/dist/shared/index.d.ts +2 -2
- package/dist/{tools-ZBAAAOUH.js → tools-NFFQWH6M.js} +6 -6
- package/dist/{vision-fallback-4TAGWGVS.js → vision-fallback-GZZWU7CR.js} +2 -2
- package/dist/web/assets/{index-CGEQK8Pf.css → index-CM0cLwa6.css} +1 -1
- package/dist/web/assets/index-SkaCnTiV.js +176 -0
- package/dist/web/index.html +2 -2
- package/dist/web/sw.js +1 -1
- package/package.json +1 -1
- package/dist/web/assets/index-Cb7XVDFv.js +0 -158
- /package/dist/web/{workbox-8c29f6e4.js → workbox-7fc22fbe.js} +0 -0
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SETTINGS_KEYS,
|
|
3
3
|
deleteSetting,
|
|
4
|
-
getSetting
|
|
5
|
-
setSetting
|
|
4
|
+
getSetting
|
|
6
5
|
} from "./chunk-PQCFNTFJ.js";
|
|
7
6
|
import {
|
|
8
7
|
getProject
|
|
@@ -28,11 +27,11 @@ import {
|
|
|
28
27
|
getBackendCapabilities,
|
|
29
28
|
getModelProfile,
|
|
30
29
|
streamWithSegments
|
|
31
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-RJIPM7CO.js";
|
|
32
31
|
import {
|
|
33
32
|
getCurrentContextWindowId,
|
|
34
33
|
getEventStore
|
|
35
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-YTPPQK55.js";
|
|
36
35
|
import {
|
|
37
36
|
buildContextMessagesFromEventHistory,
|
|
38
37
|
foldContextState,
|
|
@@ -59,7 +58,7 @@ import {
|
|
|
59
58
|
} from "./chunk-CQGTEGKL.js";
|
|
60
59
|
import {
|
|
61
60
|
getRuntimeConfig
|
|
62
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-RW25DL5R.js";
|
|
63
62
|
import {
|
|
64
63
|
logger
|
|
65
64
|
} from "./chunk-K44MW7JJ.js";
|
|
@@ -1058,28 +1057,105 @@ Error: ${toolResult.error}` : `Error: ${toolResult.error}`;
|
|
|
1058
1057
|
}
|
|
1059
1058
|
|
|
1060
1059
|
// src/server/agents/registry.ts
|
|
1061
|
-
import { readdir, readFile as
|
|
1062
|
-
import { join as
|
|
1063
|
-
import { constants as
|
|
1060
|
+
import { readdir as readdir2, readFile as readFile3, writeFile as writeFile2, mkdir as mkdir2, access as access3, unlink as unlink2 } from "fs/promises";
|
|
1061
|
+
import { join as join3, dirname as dirname2 } from "path";
|
|
1062
|
+
import { constants as constants3 } from "fs";
|
|
1064
1063
|
import { fileURLToPath } from "url";
|
|
1064
|
+
import matter2 from "gray-matter";
|
|
1065
|
+
|
|
1066
|
+
// src/server/shared/item-loader.ts
|
|
1067
|
+
import { readdir, readFile as readFile2, access as access2, writeFile, mkdir, unlink } from "fs/promises";
|
|
1068
|
+
import { join as join2 } from "path";
|
|
1069
|
+
import { constants as constants2 } from "fs";
|
|
1065
1070
|
import matter from "gray-matter";
|
|
1071
|
+
async function pathExists(path) {
|
|
1072
|
+
try {
|
|
1073
|
+
await access2(path, constants2.R_OK);
|
|
1074
|
+
return true;
|
|
1075
|
+
} catch {
|
|
1076
|
+
return false;
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
async function getDefaultIds(dir, extension) {
|
|
1080
|
+
try {
|
|
1081
|
+
const files = (await readdir(dir)).filter((f) => f.endsWith(extension));
|
|
1082
|
+
return files.map((f) => f.replace(extension, ""));
|
|
1083
|
+
} catch {
|
|
1084
|
+
return [];
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
async function loadItemsFromDir(dir, options) {
|
|
1088
|
+
if (!await pathExists(dir)) {
|
|
1089
|
+
return [];
|
|
1090
|
+
}
|
|
1091
|
+
let files;
|
|
1092
|
+
try {
|
|
1093
|
+
files = (await readdir(dir)).filter((f) => f.endsWith(options.extension));
|
|
1094
|
+
} catch {
|
|
1095
|
+
return [];
|
|
1096
|
+
}
|
|
1097
|
+
const items = [];
|
|
1098
|
+
for (const file of files) {
|
|
1099
|
+
try {
|
|
1100
|
+
const raw = await readFile2(join2(dir, file), "utf-8");
|
|
1101
|
+
const { data, content } = matter(raw);
|
|
1102
|
+
if (data.id && content.trim()) {
|
|
1103
|
+
items.push({
|
|
1104
|
+
metadata: data,
|
|
1105
|
+
prompt: content.trim()
|
|
1106
|
+
});
|
|
1107
|
+
} else {
|
|
1108
|
+
logger.warn(`Skipping invalid ${options.logName} file`, { file });
|
|
1109
|
+
}
|
|
1110
|
+
} catch (err) {
|
|
1111
|
+
logger.warn(`Failed to parse ${options.logName} file`, {
|
|
1112
|
+
file,
|
|
1113
|
+
error: err instanceof Error ? err.message : String(err)
|
|
1114
|
+
});
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
return items;
|
|
1118
|
+
}
|
|
1119
|
+
async function saveItemToDir(dir, item, ext, serialize) {
|
|
1120
|
+
if (!await pathExists(dir)) {
|
|
1121
|
+
await mkdir(dir, { recursive: true });
|
|
1122
|
+
}
|
|
1123
|
+
const meta = item.metadata;
|
|
1124
|
+
const filePath = join2(dir, `${meta.id}${ext}`);
|
|
1125
|
+
await writeFile(filePath, serialize(item), "utf-8");
|
|
1126
|
+
}
|
|
1127
|
+
var jsonSerializer = (item) => JSON.stringify(item, null, 2) + "\n";
|
|
1128
|
+
async function deleteItemFromDir(dir, id, ext) {
|
|
1129
|
+
const filePath = join2(dir, `${id}${ext}`);
|
|
1130
|
+
try {
|
|
1131
|
+
await unlink(filePath);
|
|
1132
|
+
return { success: true };
|
|
1133
|
+
} catch {
|
|
1134
|
+
return { success: false };
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
// src/server/agents/registry.ts
|
|
1066
1139
|
var __bundleDir = dirname2(fileURLToPath(import.meta.url));
|
|
1067
|
-
var DEFAULTS_DIR =
|
|
1068
|
-
var DEFAULTS_DIR_ALT =
|
|
1140
|
+
var DEFAULTS_DIR = join3(__bundleDir, "defaults");
|
|
1141
|
+
var DEFAULTS_DIR_ALT = join3(__bundleDir, "agent-defaults");
|
|
1069
1142
|
var AGENT_EXTENSION = ".agent.md";
|
|
1070
1143
|
function getAgentsDir(configDir) {
|
|
1071
|
-
return
|
|
1144
|
+
return join3(configDir, "agents");
|
|
1072
1145
|
}
|
|
1073
|
-
|
|
1146
|
+
function getProjectAgentsDir(projectDir) {
|
|
1147
|
+
return join3(projectDir, ".openfox", "agents");
|
|
1148
|
+
}
|
|
1149
|
+
async function pathExists2(path) {
|
|
1074
1150
|
try {
|
|
1075
|
-
await
|
|
1151
|
+
await access3(path, constants3.R_OK);
|
|
1076
1152
|
return true;
|
|
1077
1153
|
} catch {
|
|
1078
1154
|
return false;
|
|
1079
1155
|
}
|
|
1080
1156
|
}
|
|
1081
1157
|
function parseAgentFile(raw, filename) {
|
|
1082
|
-
const { data, content } =
|
|
1158
|
+
const { data, content } = matter2(raw);
|
|
1083
1159
|
const meta = data;
|
|
1084
1160
|
if (!meta["id"] || !content.trim()) {
|
|
1085
1161
|
logger.warn("Skipping invalid agent file", { filename });
|
|
@@ -1097,19 +1173,19 @@ function parseAgentFile(raw, filename) {
|
|
|
1097
1173
|
return { metadata, prompt: content.trim() };
|
|
1098
1174
|
}
|
|
1099
1175
|
async function loadAgentsFromDir(dir) {
|
|
1100
|
-
if (!await
|
|
1176
|
+
if (!await pathExists2(dir)) {
|
|
1101
1177
|
return [];
|
|
1102
1178
|
}
|
|
1103
1179
|
let files;
|
|
1104
1180
|
try {
|
|
1105
|
-
files = (await
|
|
1181
|
+
files = (await readdir2(dir)).filter((f) => f.endsWith(AGENT_EXTENSION));
|
|
1106
1182
|
} catch {
|
|
1107
1183
|
return [];
|
|
1108
1184
|
}
|
|
1109
1185
|
const agents = [];
|
|
1110
1186
|
for (const file of files) {
|
|
1111
1187
|
try {
|
|
1112
|
-
const raw = await
|
|
1188
|
+
const raw = await readFile3(join3(dir, file), "utf-8");
|
|
1113
1189
|
const agent = parseAgentFile(raw, file);
|
|
1114
1190
|
if (agent) {
|
|
1115
1191
|
agents.push(agent);
|
|
@@ -1128,7 +1204,10 @@ async function loadDefaultAgents() {
|
|
|
1128
1204
|
async function loadUserAgents(configDir) {
|
|
1129
1205
|
return loadAgentsFromDir(getAgentsDir(configDir));
|
|
1130
1206
|
}
|
|
1131
|
-
async function
|
|
1207
|
+
async function loadProjectAgents(projectDir) {
|
|
1208
|
+
return loadAgentsFromDir(getProjectAgentsDir(projectDir));
|
|
1209
|
+
}
|
|
1210
|
+
async function loadAllAgents(configDir, projectDir) {
|
|
1132
1211
|
const [defaultAgents, userAgents] = await Promise.all([loadDefaultAgents(), loadUserAgents(configDir)]);
|
|
1133
1212
|
const agentMap = /* @__PURE__ */ new Map();
|
|
1134
1213
|
for (const agent of defaultAgents) {
|
|
@@ -1137,12 +1216,40 @@ async function loadAllAgents(configDir) {
|
|
|
1137
1216
|
for (const agent of userAgents) {
|
|
1138
1217
|
agentMap.set(agent.metadata.id, agent);
|
|
1139
1218
|
}
|
|
1219
|
+
if (projectDir) {
|
|
1220
|
+
const projectAgents = await loadProjectAgents(projectDir);
|
|
1221
|
+
for (const agent of projectAgents) {
|
|
1222
|
+
agentMap.set(agent.metadata.id, agent);
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1140
1225
|
return Array.from(agentMap.values());
|
|
1141
1226
|
}
|
|
1227
|
+
async function saveAgentToProject(projectDir, agent) {
|
|
1228
|
+
await saveItemToDir(
|
|
1229
|
+
getProjectAgentsDir(projectDir),
|
|
1230
|
+
agent,
|
|
1231
|
+
AGENT_EXTENSION,
|
|
1232
|
+
(a) => matter2.stringify(a.prompt, a.metadata)
|
|
1233
|
+
);
|
|
1234
|
+
}
|
|
1235
|
+
async function deleteProjectAgent(projectDir, agentId) {
|
|
1236
|
+
const agentsDir = getProjectAgentsDir(projectDir);
|
|
1237
|
+
const paths = getAgentFilePaths(agentsDir, agentId);
|
|
1238
|
+
for (const filePath of paths) {
|
|
1239
|
+
try {
|
|
1240
|
+
await unlink2(filePath);
|
|
1241
|
+
return { success: true };
|
|
1242
|
+
} catch {
|
|
1243
|
+
continue;
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
return { success: false };
|
|
1247
|
+
}
|
|
1142
1248
|
async function loadAllAgentsDefault() {
|
|
1143
1249
|
try {
|
|
1144
|
-
const
|
|
1145
|
-
|
|
1250
|
+
const config = getRuntimeConfig();
|
|
1251
|
+
const configDir = getGlobalConfigDir(config.mode ?? "production");
|
|
1252
|
+
return await loadAllAgents(configDir, config.workdir);
|
|
1146
1253
|
} catch {
|
|
1147
1254
|
return loadDefaultAgents();
|
|
1148
1255
|
}
|
|
@@ -1150,24 +1257,20 @@ async function loadAllAgentsDefault() {
|
|
|
1150
1257
|
async function getDefaultAgentIds() {
|
|
1151
1258
|
for (const dir of [DEFAULTS_DIR, DEFAULTS_DIR_ALT]) {
|
|
1152
1259
|
try {
|
|
1153
|
-
const files = (await
|
|
1260
|
+
const files = (await readdir2(dir)).filter((f) => f.endsWith(AGENT_EXTENSION));
|
|
1154
1261
|
return files.map((f) => f.replace(AGENT_EXTENSION, ""));
|
|
1155
1262
|
} catch {
|
|
1156
1263
|
}
|
|
1157
1264
|
}
|
|
1158
1265
|
return [];
|
|
1159
1266
|
}
|
|
1160
|
-
async function getDefaultAgentContent(agentId) {
|
|
1161
|
-
const defaults = await loadDefaultAgents();
|
|
1162
|
-
return defaults.find((a) => a.metadata.id === agentId) ?? null;
|
|
1163
|
-
}
|
|
1164
1267
|
async function isDefaultAgent(agentId) {
|
|
1165
1268
|
const defaultIds = await getDefaultAgentIds();
|
|
1166
1269
|
return defaultIds.includes(agentId);
|
|
1167
1270
|
}
|
|
1168
1271
|
function getAgentFilePaths(agentsDir, agentId) {
|
|
1169
1272
|
const hyphenated = agentId.replace(/_/g, "-");
|
|
1170
|
-
return [
|
|
1273
|
+
return [join3(agentsDir, `${agentId}${AGENT_EXTENSION}`), join3(agentsDir, `${hyphenated}${AGENT_EXTENSION}`)];
|
|
1171
1274
|
}
|
|
1172
1275
|
function findAgentById(agentId, agents) {
|
|
1173
1276
|
return agents.find((a) => a.metadata.id === agentId);
|
|
@@ -1178,24 +1281,32 @@ function getSubAgents(agents) {
|
|
|
1178
1281
|
function getTopLevelAgents(agents) {
|
|
1179
1282
|
return agents.filter((a) => !a.metadata.subagent);
|
|
1180
1283
|
}
|
|
1181
|
-
async function agentExists(configDir, agentId) {
|
|
1284
|
+
async function agentExists(configDir, agentId, projectDir) {
|
|
1182
1285
|
const agentsDir = getAgentsDir(configDir);
|
|
1183
1286
|
const paths = getAgentFilePaths(agentsDir, agentId);
|
|
1184
1287
|
for (const filePath of paths) {
|
|
1185
|
-
if (await
|
|
1288
|
+
if (await pathExists2(filePath)) {
|
|
1186
1289
|
return true;
|
|
1187
1290
|
}
|
|
1188
1291
|
}
|
|
1292
|
+
if (projectDir) {
|
|
1293
|
+
const projectPaths = getAgentFilePaths(getProjectAgentsDir(projectDir), agentId);
|
|
1294
|
+
for (const filePath of projectPaths) {
|
|
1295
|
+
if (await pathExists2(filePath)) {
|
|
1296
|
+
return true;
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1189
1300
|
return false;
|
|
1190
1301
|
}
|
|
1191
1302
|
async function saveAgent(configDir, agent) {
|
|
1192
1303
|
const agentsDir = getAgentsDir(configDir);
|
|
1193
|
-
if (!await
|
|
1194
|
-
await
|
|
1304
|
+
if (!await pathExists2(agentsDir)) {
|
|
1305
|
+
await mkdir2(agentsDir, { recursive: true });
|
|
1195
1306
|
}
|
|
1196
|
-
const filePath =
|
|
1197
|
-
const content =
|
|
1198
|
-
await
|
|
1307
|
+
const filePath = join3(agentsDir, `${agent.metadata.id}${AGENT_EXTENSION}`);
|
|
1308
|
+
const content = matter2.stringify(agent.prompt, agent.metadata);
|
|
1309
|
+
await writeFile2(filePath, content, "utf-8");
|
|
1199
1310
|
}
|
|
1200
1311
|
async function deleteAgent(configDir, agentId) {
|
|
1201
1312
|
const isDefault = await isDefaultAgent(agentId);
|
|
@@ -1206,7 +1317,7 @@ async function deleteAgent(configDir, agentId) {
|
|
|
1206
1317
|
const paths = getAgentFilePaths(agentsDir, agentId);
|
|
1207
1318
|
for (const filePath of paths) {
|
|
1208
1319
|
try {
|
|
1209
|
-
await
|
|
1320
|
+
await unlink2(filePath);
|
|
1210
1321
|
return { success: true };
|
|
1211
1322
|
} catch {
|
|
1212
1323
|
continue;
|
|
@@ -1216,7 +1327,7 @@ async function deleteAgent(configDir, agentId) {
|
|
|
1216
1327
|
}
|
|
1217
1328
|
|
|
1218
1329
|
// src/server/tools/read.ts
|
|
1219
|
-
import { readFile as
|
|
1330
|
+
import { readFile as readFile5, stat } from "fs/promises";
|
|
1220
1331
|
import { extname } from "path";
|
|
1221
1332
|
|
|
1222
1333
|
// src/server/tools/types.ts
|
|
@@ -1247,7 +1358,7 @@ import { resolve as resolve2, isAbsolute } from "path";
|
|
|
1247
1358
|
|
|
1248
1359
|
// src/server/tools/path-security.ts
|
|
1249
1360
|
import { realpath } from "fs/promises";
|
|
1250
|
-
import { resolve, normalize, join as
|
|
1361
|
+
import { resolve, normalize, join as join4, basename, sep } from "path";
|
|
1251
1362
|
import { homedir, tmpdir } from "os";
|
|
1252
1363
|
var SAFE_PATHS = /* @__PURE__ */ new Set([
|
|
1253
1364
|
"/dev/null",
|
|
@@ -1381,7 +1492,7 @@ function extractAbsolutePathsFromCommand(command) {
|
|
|
1381
1492
|
}
|
|
1382
1493
|
} else if (content.startsWith("~")) {
|
|
1383
1494
|
const pathPart = content.slice(1);
|
|
1384
|
-
const fullPath =
|
|
1495
|
+
const fullPath = join4(home, pathPart);
|
|
1385
1496
|
const resolved = normalize(resolve(fullPath));
|
|
1386
1497
|
if (!isSafePath(resolved)) {
|
|
1387
1498
|
paths.push(resolved);
|
|
@@ -1691,7 +1802,7 @@ function createTool(name, definition, handler2) {
|
|
|
1691
1802
|
|
|
1692
1803
|
// src/server/tools/file-tracker.ts
|
|
1693
1804
|
import { createHash } from "crypto";
|
|
1694
|
-
import { readFile as
|
|
1805
|
+
import { readFile as readFile4 } from "fs/promises";
|
|
1695
1806
|
import { resolve as resolve3 } from "path";
|
|
1696
1807
|
var FileNotReadError = class extends Error {
|
|
1697
1808
|
constructor(path) {
|
|
@@ -1709,7 +1820,7 @@ var FileChangedExternallyError = class extends Error {
|
|
|
1709
1820
|
};
|
|
1710
1821
|
async function computeFileHash(filePath) {
|
|
1711
1822
|
try {
|
|
1712
|
-
const content = await
|
|
1823
|
+
const content = await readFile4(filePath);
|
|
1713
1824
|
const hash = createHash("sha256");
|
|
1714
1825
|
hash.update(content);
|
|
1715
1826
|
return hash.digest("hex");
|
|
@@ -1844,7 +1955,7 @@ var readFileTool = createTool(
|
|
|
1844
1955
|
} catch {
|
|
1845
1956
|
return helpers.error(`File not found: ${args.path}`);
|
|
1846
1957
|
}
|
|
1847
|
-
const rawBuffer = await
|
|
1958
|
+
const rawBuffer = await readFile5(fullPath);
|
|
1848
1959
|
const mimeType = detectImageType(rawBuffer, args.path);
|
|
1849
1960
|
if (mimeType) {
|
|
1850
1961
|
const base64Data = rawBuffer.toString("base64");
|
|
@@ -1890,7 +2001,7 @@ var readFileTool = createTool(
|
|
|
1890
2001
|
);
|
|
1891
2002
|
|
|
1892
2003
|
// src/server/tools/write.ts
|
|
1893
|
-
import { writeFile as
|
|
2004
|
+
import { writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
|
|
1894
2005
|
import { dirname as dirname3 } from "path";
|
|
1895
2006
|
|
|
1896
2007
|
// src/server/tools/diagnostics.ts
|
|
@@ -1951,8 +2062,8 @@ var writeFileTool = createTool(
|
|
|
1951
2062
|
return helpers.error(validation.error?.message ?? "File validation failed");
|
|
1952
2063
|
}
|
|
1953
2064
|
const dir = dirname3(fullPath);
|
|
1954
|
-
await
|
|
1955
|
-
await
|
|
2065
|
+
await mkdir3(dir, { recursive: true });
|
|
2066
|
+
await writeFile3(fullPath, args.content, "utf-8");
|
|
1956
2067
|
const lineCount = args.content.split("\n").length;
|
|
1957
2068
|
const byteCount = Buffer.byteLength(args.content, "utf-8");
|
|
1958
2069
|
let output = `Successfully wrote ${lineCount} lines (${byteCount} bytes) to ${args.path}`;
|
|
@@ -1970,7 +2081,7 @@ var writeFileTool = createTool(
|
|
|
1970
2081
|
);
|
|
1971
2082
|
|
|
1972
2083
|
// src/server/tools/edit.ts
|
|
1973
|
-
import { readFile as
|
|
2084
|
+
import { readFile as readFile6, writeFile as writeFile4 } from "fs/promises";
|
|
1974
2085
|
|
|
1975
2086
|
// src/server/tools/edit-context.ts
|
|
1976
2087
|
var CONTEXT_LINES = 4;
|
|
@@ -2126,7 +2237,7 @@ var editFileTool = createTool(
|
|
|
2126
2237
|
}
|
|
2127
2238
|
let content;
|
|
2128
2239
|
try {
|
|
2129
|
-
content = await
|
|
2240
|
+
content = await readFile6(fullPath, "utf-8");
|
|
2130
2241
|
} catch {
|
|
2131
2242
|
return helpers.error(`File not found: ${args.path}`);
|
|
2132
2243
|
}
|
|
@@ -2191,7 +2302,7 @@ Make sure whitespace and indentation match exactly.`
|
|
|
2191
2302
|
/\n/g,
|
|
2192
2303
|
fileLineEnding === "crlf" ? "\r\n" : fileLineEnding === "cr" ? "\r" : "\n"
|
|
2193
2304
|
);
|
|
2194
|
-
await
|
|
2305
|
+
await writeFile4(fullPath, newContent, "utf-8");
|
|
2195
2306
|
let output = `Successfully replaced ${replaceAll ? occurrences : 1} occurrence(s) in ${args.path}`;
|
|
2196
2307
|
let diagnostics = [];
|
|
2197
2308
|
if (context.lspManager) {
|
|
@@ -2692,66 +2803,10 @@ function createToolProgressHandler(eventStore, messageId, callId, sessionId) {
|
|
|
2692
2803
|
}
|
|
2693
2804
|
|
|
2694
2805
|
// src/server/skills/registry.ts
|
|
2695
|
-
import { writeFile as
|
|
2806
|
+
import { writeFile as writeFile5, mkdir as mkdir4, unlink as unlink3 } from "fs/promises";
|
|
2696
2807
|
import { join as join5, dirname as dirname4 } from "path";
|
|
2697
2808
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2698
2809
|
import matter3 from "gray-matter";
|
|
2699
|
-
|
|
2700
|
-
// src/server/shared/item-loader.ts
|
|
2701
|
-
import { readdir as readdir2, readFile as readFile6, access as access3 } from "fs/promises";
|
|
2702
|
-
import { join as join4 } from "path";
|
|
2703
|
-
import { constants as constants3 } from "fs";
|
|
2704
|
-
import matter2 from "gray-matter";
|
|
2705
|
-
async function pathExists2(path) {
|
|
2706
|
-
try {
|
|
2707
|
-
await access3(path, constants3.R_OK);
|
|
2708
|
-
return true;
|
|
2709
|
-
} catch {
|
|
2710
|
-
return false;
|
|
2711
|
-
}
|
|
2712
|
-
}
|
|
2713
|
-
async function getDefaultIds(dir, extension) {
|
|
2714
|
-
try {
|
|
2715
|
-
const files = (await readdir2(dir)).filter((f) => f.endsWith(extension));
|
|
2716
|
-
return files.map((f) => f.replace(extension, ""));
|
|
2717
|
-
} catch {
|
|
2718
|
-
return [];
|
|
2719
|
-
}
|
|
2720
|
-
}
|
|
2721
|
-
async function loadItemsFromDir(dir, options) {
|
|
2722
|
-
if (!await pathExists2(dir)) {
|
|
2723
|
-
return [];
|
|
2724
|
-
}
|
|
2725
|
-
let files;
|
|
2726
|
-
try {
|
|
2727
|
-
files = (await readdir2(dir)).filter((f) => f.endsWith(options.extension));
|
|
2728
|
-
} catch {
|
|
2729
|
-
return [];
|
|
2730
|
-
}
|
|
2731
|
-
const items = [];
|
|
2732
|
-
for (const file of files) {
|
|
2733
|
-
try {
|
|
2734
|
-
const raw = await readFile6(join4(dir, file), "utf-8");
|
|
2735
|
-
const { data, content } = matter2(raw);
|
|
2736
|
-
if (data.id && content.trim()) {
|
|
2737
|
-
items.push({
|
|
2738
|
-
metadata: data,
|
|
2739
|
-
prompt: content.trim()
|
|
2740
|
-
});
|
|
2741
|
-
} else {
|
|
2742
|
-
logger.warn(`Skipping invalid ${options.logName} file`, { file });
|
|
2743
|
-
}
|
|
2744
|
-
} catch (err) {
|
|
2745
|
-
logger.warn(`Failed to parse ${options.logName} file`, {
|
|
2746
|
-
file,
|
|
2747
|
-
error: err instanceof Error ? err.message : String(err)
|
|
2748
|
-
});
|
|
2749
|
-
}
|
|
2750
|
-
}
|
|
2751
|
-
return items;
|
|
2752
|
-
}
|
|
2753
|
-
|
|
2754
|
-
// src/server/skills/registry.ts
|
|
2755
2810
|
var __bundleDir2 = dirname4(fileURLToPath2(import.meta.url));
|
|
2756
2811
|
var DEFAULTS_DIR2 = join5(__bundleDir2, "defaults");
|
|
2757
2812
|
var DEFAULTS_DIR_ALT2 = join5(__bundleDir2, "skill-defaults");
|
|
@@ -2760,6 +2815,9 @@ var SKILL_SETTING_PREFIX = "skill.enabled.";
|
|
|
2760
2815
|
function getSkillsDir(configDir) {
|
|
2761
2816
|
return join5(configDir, "skills");
|
|
2762
2817
|
}
|
|
2818
|
+
function getProjectSkillsDir(projectDir) {
|
|
2819
|
+
return join5(projectDir, ".openfox", "skills");
|
|
2820
|
+
}
|
|
2763
2821
|
async function loadDefaultSkills() {
|
|
2764
2822
|
let defaults = await loadItemsFromDir(DEFAULTS_DIR2, {
|
|
2765
2823
|
extension: SKILL_EXTENSION,
|
|
@@ -2779,7 +2837,13 @@ async function loadUserSkills(configDir) {
|
|
|
2779
2837
|
logName: "skill"
|
|
2780
2838
|
});
|
|
2781
2839
|
}
|
|
2782
|
-
async function
|
|
2840
|
+
async function loadProjectSkills(projectDir) {
|
|
2841
|
+
return loadItemsFromDir(getProjectSkillsDir(projectDir), {
|
|
2842
|
+
extension: SKILL_EXTENSION,
|
|
2843
|
+
logName: "skill"
|
|
2844
|
+
});
|
|
2845
|
+
}
|
|
2846
|
+
async function loadAllSkills(configDir, projectDir) {
|
|
2783
2847
|
const [defaultSkills, userSkills] = await Promise.all([loadDefaultSkills(), loadUserSkills(configDir)]);
|
|
2784
2848
|
const skillMap = /* @__PURE__ */ new Map();
|
|
2785
2849
|
for (const skill of defaultSkills) {
|
|
@@ -2788,14 +2852,20 @@ async function loadAllSkills(configDir) {
|
|
|
2788
2852
|
for (const skill of userSkills) {
|
|
2789
2853
|
skillMap.set(skill.metadata.id, skill);
|
|
2790
2854
|
}
|
|
2855
|
+
if (projectDir) {
|
|
2856
|
+
const projectSkills = await loadProjectSkills(projectDir);
|
|
2857
|
+
for (const skill of projectSkills) {
|
|
2858
|
+
skillMap.set(skill.metadata.id, skill);
|
|
2859
|
+
}
|
|
2860
|
+
}
|
|
2791
2861
|
return Array.from(skillMap.values());
|
|
2792
2862
|
}
|
|
2793
|
-
async function getEnabledSkills(configDir) {
|
|
2794
|
-
const all = await loadAllSkills(configDir);
|
|
2863
|
+
async function getEnabledSkills(configDir, projectDir) {
|
|
2864
|
+
const all = await loadAllSkills(configDir, projectDir);
|
|
2795
2865
|
return all.filter((s) => isSkillEnabled(s.metadata.id));
|
|
2796
2866
|
}
|
|
2797
|
-
async function getEnabledSkillMetadata(configDir) {
|
|
2798
|
-
const enabled = await getEnabledSkills(configDir);
|
|
2867
|
+
async function getEnabledSkillMetadata(configDir, projectDir) {
|
|
2868
|
+
const enabled = await getEnabledSkills(configDir, projectDir);
|
|
2799
2869
|
return enabled.map((s) => s.metadata);
|
|
2800
2870
|
}
|
|
2801
2871
|
function isSkillEnabled(skillId) {
|
|
@@ -2803,18 +2873,11 @@ function isSkillEnabled(skillId) {
|
|
|
2803
2873
|
if (value === null) return true;
|
|
2804
2874
|
return value === "true";
|
|
2805
2875
|
}
|
|
2806
|
-
function setSkillEnabled(skillId, enabled) {
|
|
2807
|
-
setSetting(`${SKILL_SETTING_PREFIX}${skillId}`, String(enabled));
|
|
2808
|
-
}
|
|
2809
2876
|
async function getDefaultSkillIds() {
|
|
2810
2877
|
const ids = await getDefaultIds(DEFAULTS_DIR2, SKILL_EXTENSION);
|
|
2811
2878
|
if (ids.length) return ids;
|
|
2812
2879
|
return getDefaultIds(DEFAULTS_DIR_ALT2, SKILL_EXTENSION);
|
|
2813
2880
|
}
|
|
2814
|
-
async function getDefaultSkillContent(skillId) {
|
|
2815
|
-
const defaults = await loadDefaultSkills();
|
|
2816
|
-
return defaults.find((s) => s.metadata.id === skillId) ?? null;
|
|
2817
|
-
}
|
|
2818
2881
|
async function isDefaultSkill(skillId) {
|
|
2819
2882
|
const defaultIds = await getDefaultSkillIds();
|
|
2820
2883
|
return defaultIds.includes(skillId);
|
|
@@ -2822,17 +2885,28 @@ async function isDefaultSkill(skillId) {
|
|
|
2822
2885
|
function findSkillById(skillId, skills) {
|
|
2823
2886
|
return skills.find((s) => s.metadata.id === skillId);
|
|
2824
2887
|
}
|
|
2825
|
-
async function skillExists(configDir, skillId) {
|
|
2826
|
-
|
|
2888
|
+
async function skillExists(configDir, skillId, projectDir) {
|
|
2889
|
+
if (await pathExists(join5(getSkillsDir(configDir), `${skillId}${SKILL_EXTENSION}`))) return true;
|
|
2890
|
+
if (projectDir && await pathExists(join5(getProjectSkillsDir(projectDir), `${skillId}${SKILL_EXTENSION}`)))
|
|
2891
|
+
return true;
|
|
2892
|
+
return false;
|
|
2827
2893
|
}
|
|
2828
2894
|
async function saveSkill(configDir, skill) {
|
|
2829
2895
|
const skillsDir = getSkillsDir(configDir);
|
|
2830
|
-
if (!await
|
|
2831
|
-
await
|
|
2896
|
+
if (!await pathExists(skillsDir)) {
|
|
2897
|
+
await mkdir4(skillsDir, { recursive: true });
|
|
2832
2898
|
}
|
|
2833
2899
|
const filePath = join5(skillsDir, `${skill.metadata.id}${SKILL_EXTENSION}`);
|
|
2834
2900
|
const content = matter3.stringify(skill.prompt, skill.metadata);
|
|
2835
|
-
await
|
|
2901
|
+
await writeFile5(filePath, content, "utf-8");
|
|
2902
|
+
}
|
|
2903
|
+
async function saveSkillToProject(projectDir, skill) {
|
|
2904
|
+
await saveItemToDir(
|
|
2905
|
+
getProjectSkillsDir(projectDir),
|
|
2906
|
+
skill,
|
|
2907
|
+
SKILL_EXTENSION,
|
|
2908
|
+
(s) => matter3.stringify(s.prompt, s.metadata)
|
|
2909
|
+
);
|
|
2836
2910
|
}
|
|
2837
2911
|
async function deleteSkill(configDir, skillId) {
|
|
2838
2912
|
const isDefault = await isDefaultSkill(skillId);
|
|
@@ -2841,13 +2915,16 @@ async function deleteSkill(configDir, skillId) {
|
|
|
2841
2915
|
}
|
|
2842
2916
|
const filePath = join5(getSkillsDir(configDir), `${skillId}${SKILL_EXTENSION}`);
|
|
2843
2917
|
try {
|
|
2844
|
-
await
|
|
2918
|
+
await unlink3(filePath);
|
|
2845
2919
|
deleteSetting(`${SKILL_SETTING_PREFIX}${skillId}`);
|
|
2846
2920
|
return { success: true };
|
|
2847
2921
|
} catch {
|
|
2848
2922
|
return { success: false };
|
|
2849
2923
|
}
|
|
2850
2924
|
}
|
|
2925
|
+
async function deleteProjectSkill(projectDir, skillId) {
|
|
2926
|
+
return deleteItemFromDir(getProjectSkillsDir(projectDir), skillId, SKILL_EXTENSION);
|
|
2927
|
+
}
|
|
2851
2928
|
|
|
2852
2929
|
// src/server/chat/agent-loop.ts
|
|
2853
2930
|
import stripAnsi from "strip-ansi";
|
|
@@ -3141,8 +3218,9 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
|
|
|
3141
3218
|
eventStore.append(sessionId, createFormatRetryEvent(formatRetryCount, MAX_FORMAT_RETRIES));
|
|
3142
3219
|
requestMessages.push({ role: "user", content: FORMAT_CORRECTION_PROMPT2, source: "history" });
|
|
3143
3220
|
}
|
|
3144
|
-
const
|
|
3145
|
-
const
|
|
3221
|
+
const runtimeConfig = getRuntimeConfig();
|
|
3222
|
+
const configDir = getGlobalConfigDir(runtimeConfig.mode ?? "production");
|
|
3223
|
+
const skills = await getEnabledSkillMetadata(configDir, runtimeConfig.workdir);
|
|
3146
3224
|
if (signal?.aborted) throw new Error("Aborted");
|
|
3147
3225
|
const assembledRequest = config.assembleRequest({
|
|
3148
3226
|
workdir: session.workdir,
|
|
@@ -3532,8 +3610,9 @@ async function executeSubAgent(options) {
|
|
|
3532
3610
|
}
|
|
3533
3611
|
const { content: instructionContent, files } = await getAllInstructions(session.workdir, session.projectId);
|
|
3534
3612
|
const injectedFiles = toInjectedFiles(files);
|
|
3535
|
-
const
|
|
3536
|
-
const
|
|
3613
|
+
const config = getRuntimeConfig();
|
|
3614
|
+
const configDir = getGlobalConfigDir(config.mode ?? "production");
|
|
3615
|
+
const skills = await getEnabledSkillMetadata(configDir, config.workdir);
|
|
3537
3616
|
const systemPrompt = buildSubAgentSystemPrompt(
|
|
3538
3617
|
session.workdir,
|
|
3539
3618
|
agentDef,
|
|
@@ -3802,7 +3881,7 @@ var callSubAgentTool = {
|
|
|
3802
3881
|
};
|
|
3803
3882
|
}
|
|
3804
3883
|
try {
|
|
3805
|
-
const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-
|
|
3884
|
+
const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-NFFQWH6M.js");
|
|
3806
3885
|
const toolRegistry = getToolRegistryForAgent2(agentDef);
|
|
3807
3886
|
const turnMetrics = new TurnMetrics();
|
|
3808
3887
|
const result = await executeSubAgent({
|
|
@@ -3850,7 +3929,7 @@ var handler = async (args, _context, helpers) => {
|
|
|
3850
3929
|
}
|
|
3851
3930
|
const config = getRuntimeConfig();
|
|
3852
3931
|
const configDir = getGlobalConfigDir(config.mode ?? "production");
|
|
3853
|
-
const allSkills = await loadAllSkills(configDir);
|
|
3932
|
+
const allSkills = await loadAllSkills(configDir, config.workdir);
|
|
3854
3933
|
const skill = findSkillById(skillId, allSkills);
|
|
3855
3934
|
if (!skill) {
|
|
3856
3935
|
const available = allSkills.map((s) => s.metadata.id).join(", ");
|
|
@@ -4054,7 +4133,7 @@ var webFetchTool = createTool(
|
|
|
4054
4133
|
|
|
4055
4134
|
// src/server/dev-server/manager.ts
|
|
4056
4135
|
import { spawn as spawn3 } from "child_process";
|
|
4057
|
-
import { readFile as readFile7, writeFile as
|
|
4136
|
+
import { readFile as readFile7, writeFile as writeFile6, mkdir as mkdir5 } from "fs/promises";
|
|
4058
4137
|
import { resolve as resolve5, join as join6 } from "path";
|
|
4059
4138
|
var MAX_LOG_LINES = 2e3;
|
|
4060
4139
|
var MAX_LOG_BYTES = 1e5;
|
|
@@ -4137,9 +4216,9 @@ var DevServerManager = class {
|
|
|
4137
4216
|
async saveConfig(workdir, config) {
|
|
4138
4217
|
const resolved = this.resolveWorkdir(workdir);
|
|
4139
4218
|
const dirPath = join6(resolved, ".openfox");
|
|
4140
|
-
await
|
|
4219
|
+
await mkdir5(dirPath, { recursive: true });
|
|
4141
4220
|
const configPath = getDevServerConfigPath(workdir);
|
|
4142
|
-
await
|
|
4221
|
+
await writeFile6(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
4143
4222
|
}
|
|
4144
4223
|
async start(workdir) {
|
|
4145
4224
|
const instance = this.getInstance(workdir);
|
|
@@ -4839,7 +4918,7 @@ async function performContextCompaction(options) {
|
|
|
4839
4918
|
const subAgentDefs = getSubAgents(allAgents);
|
|
4840
4919
|
const toolRegistry = getToolRegistryForAgent(plannerDef);
|
|
4841
4920
|
const configDir = getGlobalConfigDir(config.mode ?? "production");
|
|
4842
|
-
const skills = await getEnabledSkillMetadata(configDir);
|
|
4921
|
+
const skills = await getEnabledSkillMetadata(configDir, config.workdir);
|
|
4843
4922
|
const assembledRequest = assembleAgentRequest({
|
|
4844
4923
|
agentDef: plannerDef,
|
|
4845
4924
|
subAgentDefs,
|
|
@@ -4942,12 +5021,21 @@ export {
|
|
|
4942
5021
|
cancelPathConfirmationsForSession,
|
|
4943
5022
|
checkAborted,
|
|
4944
5023
|
spawnShellProcess,
|
|
5024
|
+
pathExists,
|
|
5025
|
+
getDefaultIds,
|
|
5026
|
+
loadItemsFromDir,
|
|
5027
|
+
saveItemToDir,
|
|
5028
|
+
jsonSerializer,
|
|
5029
|
+
deleteItemFromDir,
|
|
4945
5030
|
loadDefaultAgents,
|
|
4946
5031
|
loadUserAgents,
|
|
5032
|
+
loadProjectAgents,
|
|
4947
5033
|
loadAllAgents,
|
|
5034
|
+
saveAgentToProject,
|
|
5035
|
+
deleteProjectAgent,
|
|
4948
5036
|
loadAllAgentsDefault,
|
|
4949
5037
|
getDefaultAgentIds,
|
|
4950
|
-
|
|
5038
|
+
isDefaultAgent,
|
|
4951
5039
|
findAgentById,
|
|
4952
5040
|
getSubAgents,
|
|
4953
5041
|
getTopLevelAgents,
|
|
@@ -4964,20 +5052,19 @@ export {
|
|
|
4964
5052
|
createToolResultEvent,
|
|
4965
5053
|
createChatDoneEvent,
|
|
4966
5054
|
assembleAgentRequest,
|
|
4967
|
-
pathExists2 as pathExists,
|
|
4968
|
-
getDefaultIds,
|
|
4969
|
-
loadItemsFromDir,
|
|
4970
5055
|
loadDefaultSkills,
|
|
4971
5056
|
loadUserSkills,
|
|
5057
|
+
loadProjectSkills,
|
|
4972
5058
|
loadAllSkills,
|
|
4973
5059
|
isSkillEnabled,
|
|
4974
|
-
setSkillEnabled,
|
|
4975
5060
|
getDefaultSkillIds,
|
|
4976
|
-
|
|
5061
|
+
isDefaultSkill,
|
|
4977
5062
|
findSkillById,
|
|
4978
5063
|
skillExists,
|
|
4979
5064
|
saveSkill,
|
|
5065
|
+
saveSkillToProject,
|
|
4980
5066
|
deleteSkill,
|
|
5067
|
+
deleteProjectSkill,
|
|
4981
5068
|
maybeAutoCompactContext,
|
|
4982
5069
|
performManualContextCompaction,
|
|
4983
5070
|
resolveCompactionStatsIdentity,
|
|
@@ -4993,4 +5080,4 @@ export {
|
|
|
4993
5080
|
getToolRegistryForAgent,
|
|
4994
5081
|
createToolRegistry
|
|
4995
5082
|
};
|
|
4996
|
-
//# sourceMappingURL=chunk-
|
|
5083
|
+
//# sourceMappingURL=chunk-ARJIHQ3S.js.map
|