openfox 1.6.15 → 1.6.17

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.
@@ -2,7 +2,7 @@ import {
2
2
  maybeAutoCompactContext,
3
3
  performManualContextCompaction,
4
4
  resolveCompactionStatsIdentity
5
- } from "./chunk-3WHZ47PY.js";
5
+ } from "./chunk-R7U3CD2U.js";
6
6
  import "./chunk-NBU6KIOD.js";
7
7
  import "./chunk-574HZVLE.js";
8
8
  import "./chunk-55N6FAAZ.js";
@@ -22,4 +22,4 @@ export {
22
22
  performManualContextCompaction,
23
23
  resolveCompactionStatsIdentity
24
24
  };
25
- //# sourceMappingURL=auto-compaction-JZIM73ZY.js.map
25
+ //# sourceMappingURL=auto-compaction-VOWM5ZHF.js.map
@@ -10,8 +10,8 @@ import {
10
10
  } from "./chunk-F54ZJN4X.js";
11
11
  import {
12
12
  runChatTurn
13
- } from "./chunk-YM6VHAPM.js";
14
- import "./chunk-3WHZ47PY.js";
13
+ } from "./chunk-RPPEIB3F.js";
14
+ import "./chunk-R7U3CD2U.js";
15
15
  import "./chunk-NBU6KIOD.js";
16
16
  import "./chunk-574HZVLE.js";
17
17
  import "./chunk-55N6FAAZ.js";
@@ -61,7 +61,7 @@ async function startChatSession(sessionId, content, deps, options) {
61
61
  sessionManager.setRunning(sessionId, true);
62
62
  broadcastForSession(sessionId, createSessionRunningMessage(true));
63
63
  try {
64
- const { maybeAutoCompactContext } = await import("./auto-compaction-JZIM73ZY.js");
64
+ const { maybeAutoCompactContext } = await import("./auto-compaction-VOWM5ZHF.js");
65
65
  await maybeAutoCompactContext({
66
66
  sessionManager,
67
67
  sessionId,
@@ -170,4 +170,4 @@ export {
170
170
  startChatSession,
171
171
  stopSessionExecution
172
172
  };
173
- //# sourceMappingURL=chat-handler-F2A2IMQB.js.map
173
+ //# sourceMappingURL=chat-handler-7HWNXQ4G.js.map
@@ -154,7 +154,7 @@ async function runCli(options) {
154
154
  if (!configExists) {
155
155
  await runNetworkSetup(mode);
156
156
  }
157
- const { runServe } = await import("./serve-5AY7GMN7.js");
157
+ const { runServe } = await import("./serve-FEG4BUYZ.js");
158
158
  await runServe({
159
159
  mode,
160
160
  port: values.port ? parseInt(values.port) : void 0,
@@ -167,4 +167,4 @@ async function runCli(options) {
167
167
  export {
168
168
  runCli
169
169
  };
170
- //# sourceMappingURL=chunk-JFKYCGZ5.js.map
170
+ //# sourceMappingURL=chunk-EAQNNNUR.js.map
@@ -34,6 +34,7 @@ import {
34
34
  } from "./chunk-22CTURMH.js";
35
35
  import {
36
36
  SETTINGS_KEYS,
37
+ deleteSetting,
37
38
  getSetting,
38
39
  setSetting
39
40
  } from "./chunk-7IOZFJBW.js";
@@ -909,48 +910,17 @@ Error: ${toolResult.error}` : `Error: ${toolResult.error}`;
909
910
  }
910
911
 
911
912
  // src/server/agents/registry.ts
912
- import { readdir, readFile as readFile3, writeFile, copyFile, mkdir, access as access2, unlink } from "fs/promises";
913
- import { join as join3, dirname as dirname2 } from "path";
913
+ import { readdir, readFile as readFile2, writeFile, mkdir, access as access2, unlink } from "fs/promises";
914
+ import { join as join2, dirname as dirname2 } from "path";
914
915
  import { constants as constants2 } from "fs";
915
916
  import { fileURLToPath } from "url";
916
917
  import matter from "gray-matter";
917
-
918
- // src/server/utils/defaults.ts
919
- import { readFile as readFile2 } from "fs/promises";
920
- import { join as join2 } from "path";
921
- async function findModifiedDefaultFiles(defaultIds, extension, bundledDirs, userDir) {
922
- const [primaryDir, altDir] = bundledDirs;
923
- const modified = [];
924
- for (const id of defaultIds) {
925
- const filename = `${id}${extension}`;
926
- const userPath = join2(userDir, filename);
927
- let bundledContent = null;
928
- for (const dir of [primaryDir, altDir]) {
929
- try {
930
- bundledContent = await readFile2(join2(dir, filename), "utf-8");
931
- break;
932
- } catch {
933
- }
934
- }
935
- if (!bundledContent) continue;
936
- try {
937
- const userContent = await readFile2(userPath, "utf-8");
938
- if (userContent !== bundledContent) {
939
- modified.push(id);
940
- }
941
- } catch {
942
- }
943
- }
944
- return modified;
945
- }
946
-
947
- // src/server/agents/registry.ts
948
918
  var __bundleDir = dirname2(fileURLToPath(import.meta.url));
949
- var DEFAULTS_DIR = join3(__bundleDir, "defaults");
950
- var DEFAULTS_DIR_ALT = join3(__bundleDir, "agent-defaults");
919
+ var DEFAULTS_DIR = join2(__bundleDir, "defaults");
920
+ var DEFAULTS_DIR_ALT = join2(__bundleDir, "agent-defaults");
951
921
  var AGENT_EXTENSION = ".agent.md";
952
922
  function getAgentsDir(configDir) {
953
- return join3(configDir, "agents");
923
+ return join2(configDir, "agents");
954
924
  }
955
925
  async function pathExists(path) {
956
926
  try {
@@ -960,37 +930,6 @@ async function pathExists(path) {
960
930
  return false;
961
931
  }
962
932
  }
963
- async function ensureDefaultAgents(configDir) {
964
- const agentsDir = getAgentsDir(configDir);
965
- if (!await pathExists(agentsDir)) {
966
- await mkdir(agentsDir, { recursive: true });
967
- }
968
- let defaultFiles;
969
- let sourceDir;
970
- try {
971
- defaultFiles = (await readdir(DEFAULTS_DIR)).filter((f) => f.endsWith(AGENT_EXTENSION));
972
- sourceDir = DEFAULTS_DIR;
973
- } catch {
974
- try {
975
- defaultFiles = (await readdir(DEFAULTS_DIR_ALT)).filter((f) => f.endsWith(AGENT_EXTENSION));
976
- sourceDir = DEFAULTS_DIR_ALT;
977
- } catch {
978
- logger.warn("No bundled agent defaults found", { dir: DEFAULTS_DIR });
979
- return;
980
- }
981
- }
982
- for (const file of defaultFiles) {
983
- const targetPath = join3(agentsDir, file);
984
- if (!await pathExists(targetPath)) {
985
- try {
986
- await copyFile(join3(sourceDir, file), targetPath);
987
- logger.info("Installed default agent", { file });
988
- } catch (err) {
989
- logger.error("Failed to copy default agent", { file, error: err instanceof Error ? err.message : String(err) });
990
- }
991
- }
992
- }
993
- }
994
933
  function parseAgentFile(raw, filename) {
995
934
  const { data, content } = matter(raw);
996
935
  const meta = data;
@@ -1022,7 +961,7 @@ async function loadAgentsFromDir(dir) {
1022
961
  const agents = [];
1023
962
  for (const file of files) {
1024
963
  try {
1025
- const raw = await readFile3(join3(dir, file), "utf-8");
964
+ const raw = await readFile2(join2(dir, file), "utf-8");
1026
965
  const agent = parseAgentFile(raw, file);
1027
966
  if (agent) {
1028
967
  agents.push(agent);
@@ -1033,13 +972,21 @@ async function loadAgentsFromDir(dir) {
1033
972
  }
1034
973
  return agents;
1035
974
  }
975
+ async function loadDefaultAgents() {
976
+ const agents = await loadAgentsFromDir(DEFAULTS_DIR);
977
+ if (agents.length > 0) return agents;
978
+ return loadAgentsFromDir(DEFAULTS_DIR_ALT);
979
+ }
980
+ async function loadUserAgents(configDir) {
981
+ return loadAgentsFromDir(getAgentsDir(configDir));
982
+ }
1036
983
  async function loadAllAgents(configDir) {
1037
- const [builtinAgents, userAgents] = await Promise.all([
1038
- loadBuiltinAgents(),
1039
- loadAgentsFromDir(getAgentsDir(configDir))
984
+ const [defaultAgents, userAgents] = await Promise.all([
985
+ loadDefaultAgents(),
986
+ loadUserAgents(configDir)
1040
987
  ]);
1041
988
  const agentMap = /* @__PURE__ */ new Map();
1042
- for (const agent of builtinAgents) {
989
+ for (const agent of defaultAgents) {
1043
990
  agentMap.set(agent.metadata.id, agent);
1044
991
  }
1045
992
  for (const agent of userAgents) {
@@ -1052,14 +999,9 @@ async function loadAllAgentsDefault() {
1052
999
  const configDir = getGlobalConfigDir(getRuntimeConfig().mode ?? "production");
1053
1000
  return await loadAllAgents(configDir);
1054
1001
  } catch {
1055
- return loadBuiltinAgents();
1002
+ return loadDefaultAgents();
1056
1003
  }
1057
1004
  }
1058
- async function loadBuiltinAgents() {
1059
- const agents = await loadAgentsFromDir(DEFAULTS_DIR);
1060
- if (agents.length > 0) return agents;
1061
- return loadAgentsFromDir(DEFAULTS_DIR_ALT);
1062
- }
1063
1005
  async function getDefaultAgentIds() {
1064
1006
  for (const dir of [DEFAULTS_DIR, DEFAULTS_DIR_ALT]) {
1065
1007
  try {
@@ -1070,33 +1012,19 @@ async function getDefaultAgentIds() {
1070
1012
  }
1071
1013
  return [];
1072
1014
  }
1073
- async function restoreDefaultAgent(configDir, agentId) {
1074
- const defaultIds = await getDefaultAgentIds();
1075
- if (!defaultIds.includes(agentId)) return false;
1076
- const userPath = join3(getAgentsDir(configDir), `${agentId}${AGENT_EXTENSION}`);
1077
- try {
1078
- await unlink(userPath);
1079
- } catch {
1080
- }
1081
- return true;
1015
+ async function getDefaultAgentContent(agentId) {
1016
+ const defaults = await loadDefaultAgents();
1017
+ return defaults.find((a) => a.metadata.id === agentId) ?? null;
1082
1018
  }
1083
- async function getModifiedDefaultAgentIds(configDir) {
1019
+ async function isDefaultAgent(agentId) {
1084
1020
  const defaultIds = await getDefaultAgentIds();
1085
- return findModifiedDefaultFiles(defaultIds, AGENT_EXTENSION, [DEFAULTS_DIR, DEFAULTS_DIR_ALT], getAgentsDir(configDir));
1086
- }
1087
- async function restoreAllDefaultAgents(configDir) {
1088
- const ids = await getDefaultAgentIds();
1089
- let count = 0;
1090
- for (const id of ids) {
1091
- if (await restoreDefaultAgent(configDir, id)) count++;
1092
- }
1093
- return count;
1021
+ return defaultIds.includes(agentId);
1094
1022
  }
1095
1023
  function getAgentFilePaths(agentsDir, agentId) {
1096
1024
  const hyphenated = agentId.replace(/_/g, "-");
1097
1025
  return [
1098
- join3(agentsDir, `${agentId}${AGENT_EXTENSION}`),
1099
- join3(agentsDir, `${hyphenated}${AGENT_EXTENSION}`)
1026
+ join2(agentsDir, `${agentId}${AGENT_EXTENSION}`),
1027
+ join2(agentsDir, `${hyphenated}${AGENT_EXTENSION}`)
1100
1028
  ];
1101
1029
  }
1102
1030
  function findAgentById(agentId, agents) {
@@ -1120,26 +1048,30 @@ async function saveAgent(configDir, agent) {
1120
1048
  if (!await pathExists(agentsDir)) {
1121
1049
  await mkdir(agentsDir, { recursive: true });
1122
1050
  }
1123
- const filePath = join3(agentsDir, `${agent.metadata.id}${AGENT_EXTENSION}`);
1051
+ const filePath = join2(agentsDir, `${agent.metadata.id}${AGENT_EXTENSION}`);
1124
1052
  const content = matter.stringify(agent.prompt, agent.metadata);
1125
1053
  await writeFile(filePath, content, "utf-8");
1126
1054
  }
1127
1055
  async function deleteAgent(configDir, agentId) {
1056
+ const isDefault = await isDefaultAgent(agentId);
1057
+ if (isDefault) {
1058
+ return { success: false, reason: "Cannot delete built-in defaults" };
1059
+ }
1128
1060
  const agentsDir = getAgentsDir(configDir);
1129
1061
  const paths = getAgentFilePaths(agentsDir, agentId);
1130
1062
  for (const filePath of paths) {
1131
1063
  try {
1132
1064
  await unlink(filePath);
1133
- return true;
1065
+ return { success: true };
1134
1066
  } catch {
1135
1067
  continue;
1136
1068
  }
1137
1069
  }
1138
- return false;
1070
+ return { success: false };
1139
1071
  }
1140
1072
 
1141
1073
  // src/server/tools/read.ts
1142
- import { readFile as readFile5, stat as stat2 } from "fs/promises";
1074
+ import { readFile as readFile4, stat as stat2 } from "fs/promises";
1143
1075
  import { extname } from "path";
1144
1076
 
1145
1077
  // src/server/tools/types.ts
@@ -1170,7 +1102,7 @@ import { resolve as resolve2, isAbsolute } from "path";
1170
1102
 
1171
1103
  // src/server/tools/path-security.ts
1172
1104
  import { realpath } from "fs/promises";
1173
- import { resolve, normalize, join as join4, basename, sep } from "path";
1105
+ import { resolve, normalize, join as join3, basename, sep } from "path";
1174
1106
  import { homedir, tmpdir } from "os";
1175
1107
  var SAFE_PATHS = /* @__PURE__ */ new Set([
1176
1108
  "/dev/null",
@@ -1305,7 +1237,7 @@ function extractAbsolutePathsFromCommand(command) {
1305
1237
  }
1306
1238
  } else if (content.startsWith("~")) {
1307
1239
  const pathPart = content.slice(1);
1308
- const fullPath = join4(home, pathPart);
1240
+ const fullPath = join3(home, pathPart);
1309
1241
  const resolved = normalize(resolve(fullPath));
1310
1242
  if (!isSafePath(resolved)) {
1311
1243
  paths.push(resolved);
@@ -1583,7 +1515,7 @@ function createTool(name, definition, handler2) {
1583
1515
 
1584
1516
  // src/server/tools/file-tracker.ts
1585
1517
  import { createHash } from "crypto";
1586
- import { readFile as readFile4 } from "fs/promises";
1518
+ import { readFile as readFile3 } from "fs/promises";
1587
1519
  import { resolve as resolve3 } from "path";
1588
1520
  var FileNotReadError = class extends Error {
1589
1521
  constructor(path) {
@@ -1599,7 +1531,7 @@ var FileChangedExternallyError = class extends Error {
1599
1531
  };
1600
1532
  async function computeFileHash(filePath) {
1601
1533
  try {
1602
- const content = await readFile4(filePath);
1534
+ const content = await readFile3(filePath);
1603
1535
  const hash = createHash("sha256");
1604
1536
  hash.update(content);
1605
1537
  return hash.digest("hex");
@@ -1732,7 +1664,7 @@ var readFileTool = createTool(
1732
1664
  } catch {
1733
1665
  return helpers.error(`File not found: ${args.path}`);
1734
1666
  }
1735
- const rawBuffer = await readFile5(fullPath);
1667
+ const rawBuffer = await readFile4(fullPath);
1736
1668
  const mimeType = detectImageType(rawBuffer, args.path);
1737
1669
  if (mimeType) {
1738
1670
  const base64Data = rawBuffer.toString("base64");
@@ -1866,7 +1798,7 @@ var writeFileTool = createTool(
1866
1798
  );
1867
1799
 
1868
1800
  // src/server/tools/edit.ts
1869
- import { readFile as readFile6, writeFile as writeFile3 } from "fs/promises";
1801
+ import { readFile as readFile5, writeFile as writeFile3 } from "fs/promises";
1870
1802
 
1871
1803
  // src/server/tools/edit-context.ts
1872
1804
  var CONTEXT_LINES = 4;
@@ -2022,7 +1954,7 @@ var editFileTool = createTool(
2022
1954
  }
2023
1955
  let content;
2024
1956
  try {
2025
- content = await readFile6(fullPath, "utf-8");
1957
+ content = await readFile5(fullPath, "utf-8");
2026
1958
  } catch {
2027
1959
  return helpers.error(`File not found: ${args.path}`);
2028
1960
  }
@@ -2545,19 +2477,17 @@ function createToolProgressHandler(messageId, callId, onMessage) {
2545
2477
  }
2546
2478
 
2547
2479
  // src/server/skills/registry.ts
2548
- import { readdir as readdir3 } from "fs/promises";
2549
- import { join as join6 } from "path";
2550
-
2551
- // src/server/commands/registry-utils.ts
2552
- import { readdir as readdir2, readFile as readFile7, writeFile as writeFile4, copyFile as copyFile2, mkdir as mkdir3, access as access3, unlink as unlink2 } from "fs/promises";
2480
+ import { writeFile as writeFile4, mkdir as mkdir3, unlink as unlink2 } from "fs/promises";
2553
2481
  import { join as join5, dirname as dirname4 } from "path";
2554
- import { constants as constants3 } from "fs";
2555
2482
  import { fileURLToPath as fileURLToPath2 } from "url";
2483
+ import matter3 from "gray-matter";
2484
+
2485
+ // src/server/shared/item-loader.ts
2486
+ import { readdir as readdir2, readFile as readFile6, access as access3 } from "fs/promises";
2487
+ import { join as join4 } from "path";
2488
+ import { constants as constants3 } from "fs";
2556
2489
  import matter2 from "gray-matter";
2557
- function getBundleDir() {
2558
- return dirname4(fileURLToPath2(import.meta.url));
2559
- }
2560
- async function dirExists(path) {
2490
+ async function pathExists2(path) {
2561
2491
  try {
2562
2492
  await access3(path, constants3.R_OK);
2563
2493
  return true;
@@ -2565,92 +2495,88 @@ async function dirExists(path) {
2565
2495
  return false;
2566
2496
  }
2567
2497
  }
2568
- async function ensureDir(path) {
2569
- if (!await dirExists(path)) {
2570
- await mkdir3(path, { recursive: true });
2498
+ async function getDefaultIds(dir, extension) {
2499
+ try {
2500
+ const files = (await readdir2(dir)).filter((f) => f.endsWith(extension));
2501
+ return files.map((f) => f.replace(extension, ""));
2502
+ } catch {
2503
+ return [];
2571
2504
  }
2572
2505
  }
2573
- async function loadItems(dir, extension) {
2574
- if (!await dirExists(dir)) return [];
2506
+ async function loadItemsFromDir(dir, options) {
2507
+ if (!await pathExists2(dir)) {
2508
+ return [];
2509
+ }
2575
2510
  let files;
2576
2511
  try {
2577
- files = (await readdir2(dir)).filter((f) => f.endsWith(extension));
2512
+ files = (await readdir2(dir)).filter((f) => f.endsWith(options.extension));
2578
2513
  } catch {
2579
2514
  return [];
2580
2515
  }
2581
2516
  const items = [];
2582
2517
  for (const file of files) {
2583
2518
  try {
2584
- const raw = await readFile7(join5(dir, file), "utf-8");
2519
+ const raw = await readFile6(join4(dir, file), "utf-8");
2585
2520
  const { data, content } = matter2(raw);
2586
2521
  if (data.id && content.trim()) {
2587
- items.push({ metadata: data, prompt: content.trim() });
2522
+ items.push({
2523
+ metadata: data,
2524
+ prompt: content.trim()
2525
+ });
2588
2526
  } else {
2589
- logger.warn(`Skipping invalid ${extension} file`, { file });
2527
+ logger.warn(`Skipping invalid ${options.logName} file`, { file });
2590
2528
  }
2591
2529
  } catch (err) {
2592
- logger.warn(`Failed to parse ${extension} file`, { file, error: err instanceof Error ? err.message : String(err) });
2530
+ logger.warn(`Failed to parse ${options.logName} file`, {
2531
+ file,
2532
+ error: err instanceof Error ? err.message : String(err)
2533
+ });
2593
2534
  }
2594
2535
  }
2595
2536
  return items;
2596
2537
  }
2597
- async function saveItem(dir, id, extension, item) {
2598
- await ensureDir(dir);
2599
- const filePath = join5(dir, `${id}${extension}`);
2600
- const content = matter2.stringify(item.prompt, item.metadata);
2601
- await writeFile4(filePath, content, "utf-8");
2602
- }
2603
- async function deleteItem(dir, id, extension) {
2604
- const filePath = join5(dir, `${id}${extension}`);
2605
- try {
2606
- await unlink2(filePath);
2607
- return true;
2608
- } catch {
2609
- return false;
2610
- }
2611
- }
2612
- function findById(id, items) {
2613
- return items.find((i) => i.metadata.id === id);
2614
- }
2615
- async function getDefaultIds(bundleDir, defaultsDir, extension) {
2616
- try {
2617
- const files = (await readdir2(join5(bundleDir, defaultsDir))).filter((f) => f.endsWith(extension));
2618
- return files.map((f) => f.replace(extension, ""));
2619
- } catch {
2620
- return [];
2621
- }
2622
- }
2623
- async function restoreDefault(itemDir, bundleDir, defaultsDir, id, extension) {
2624
- const filename = `${id}${extension}`;
2625
- const src = join5(bundleDir, defaultsDir, filename);
2626
- if (await dirExists(src)) {
2627
- await copyFile2(src, join5(itemDir, filename));
2628
- return true;
2629
- }
2630
- return false;
2631
- }
2632
2538
 
2633
2539
  // src/server/skills/registry.ts
2634
- var DEFAULTS_DIR2 = "defaults";
2635
- var DEFAULTS_DIR_ALT2 = "skill-defaults";
2540
+ var __bundleDir2 = dirname4(fileURLToPath2(import.meta.url));
2541
+ var DEFAULTS_DIR2 = join5(__bundleDir2, "defaults");
2542
+ var DEFAULTS_DIR_ALT2 = join5(__bundleDir2, "skill-defaults");
2636
2543
  var SKILL_EXTENSION = ".skill.md";
2637
2544
  var SKILL_SETTING_PREFIX = "skill.enabled.";
2638
2545
  function getSkillsDir(configDir) {
2639
- return join6(configDir, "skills");
2546
+ return join5(configDir, "skills");
2640
2547
  }
2641
- async function ensureDefaultSkills(configDir) {
2642
- const bundleDir = getBundleDir();
2643
- const skillsDir = getSkillsDir(configDir);
2644
- await ensureDir(skillsDir);
2645
- const ids = await getDefaultIds(bundleDir, DEFAULTS_DIR2, SKILL_EXTENSION);
2646
- for (const id of ids) {
2647
- if (!await restoreDefault(skillsDir, bundleDir, DEFAULTS_DIR2, id, SKILL_EXTENSION)) {
2648
- await restoreDefault(skillsDir, bundleDir, DEFAULTS_DIR_ALT2, id, SKILL_EXTENSION);
2649
- }
2548
+ async function loadDefaultSkills() {
2549
+ let defaults = await loadItemsFromDir(DEFAULTS_DIR2, {
2550
+ extension: SKILL_EXTENSION,
2551
+ logName: "skill"
2552
+ });
2553
+ if (!defaults.length) {
2554
+ defaults = await loadItemsFromDir(DEFAULTS_DIR_ALT2, {
2555
+ extension: SKILL_EXTENSION,
2556
+ logName: "skill"
2557
+ });
2650
2558
  }
2559
+ return defaults;
2560
+ }
2561
+ async function loadUserSkills(configDir) {
2562
+ return loadItemsFromDir(getSkillsDir(configDir), {
2563
+ extension: SKILL_EXTENSION,
2564
+ logName: "skill"
2565
+ });
2651
2566
  }
2652
2567
  async function loadAllSkills(configDir) {
2653
- return loadItems(getSkillsDir(configDir), SKILL_EXTENSION);
2568
+ const [defaultSkills, userSkills] = await Promise.all([
2569
+ loadDefaultSkills(),
2570
+ loadUserSkills(configDir)
2571
+ ]);
2572
+ const skillMap = /* @__PURE__ */ new Map();
2573
+ for (const skill of defaultSkills) {
2574
+ skillMap.set(skill.metadata.id, skill);
2575
+ }
2576
+ for (const skill of userSkills) {
2577
+ skillMap.set(skill.metadata.id, skill);
2578
+ }
2579
+ return Array.from(skillMap.values());
2654
2580
  }
2655
2581
  async function getEnabledSkills(configDir) {
2656
2582
  const all = await loadAllSkills(configDir);
@@ -2669,46 +2595,46 @@ function setSkillEnabled(skillId, enabled) {
2669
2595
  setSetting(`${SKILL_SETTING_PREFIX}${skillId}`, String(enabled));
2670
2596
  }
2671
2597
  async function getDefaultSkillIds() {
2672
- const bundleDir = getBundleDir();
2673
- const ids = await getDefaultIds(bundleDir, DEFAULTS_DIR2, SKILL_EXTENSION);
2598
+ const ids = await getDefaultIds(DEFAULTS_DIR2, SKILL_EXTENSION);
2674
2599
  if (ids.length) return ids;
2675
- return getDefaultIds(bundleDir, DEFAULTS_DIR_ALT2, SKILL_EXTENSION);
2676
- }
2677
- async function restoreDefaultSkill(configDir, skillId) {
2678
- const bundleDir = getBundleDir();
2679
- const skillsDir = getSkillsDir(configDir);
2680
- return restoreDefault(skillsDir, bundleDir, DEFAULTS_DIR2, skillId, SKILL_EXTENSION) || restoreDefault(skillsDir, bundleDir, DEFAULTS_DIR_ALT2, skillId, SKILL_EXTENSION);
2600
+ return getDefaultIds(DEFAULTS_DIR_ALT2, SKILL_EXTENSION);
2681
2601
  }
2682
- async function getModifiedDefaultSkillIds(configDir) {
2683
- const bundleDir = getBundleDir();
2684
- const ids = await getDefaultSkillIds();
2685
- const files = (await readdir3(join6(bundleDir, DEFAULTS_DIR2))).filter((f) => f.endsWith(SKILL_EXTENSION));
2686
- return files.map((f) => f.replace(SKILL_EXTENSION, "")).filter((id) => ids.includes(id));
2602
+ async function getDefaultSkillContent(skillId) {
2603
+ const defaults = await loadDefaultSkills();
2604
+ return defaults.find((s) => s.metadata.id === skillId) ?? null;
2687
2605
  }
2688
- async function restoreAllDefaultSkills(configDir) {
2689
- const ids = await getDefaultSkillIds();
2690
- let count = 0;
2691
- for (const id of ids) {
2692
- if (await restoreDefaultSkill(configDir, id)) count++;
2693
- }
2694
- return count;
2606
+ async function isDefaultSkill(skillId) {
2607
+ const defaultIds = await getDefaultSkillIds();
2608
+ return defaultIds.includes(skillId);
2695
2609
  }
2696
2610
  function findSkillById(skillId, skills) {
2697
- return findById(skillId, skills);
2611
+ return skills.find((s) => s.metadata.id === skillId);
2698
2612
  }
2699
2613
  async function skillExists(configDir, skillId) {
2700
- return dirExists(join6(getSkillsDir(configDir), `${skillId}${SKILL_EXTENSION}`));
2614
+ return pathExists2(join5(getSkillsDir(configDir), `${skillId}${SKILL_EXTENSION}`));
2701
2615
  }
2702
2616
  async function saveSkill(configDir, skill) {
2703
- return saveItem(getSkillsDir(configDir), skill.metadata.id, SKILL_EXTENSION, skill);
2617
+ const skillsDir = getSkillsDir(configDir);
2618
+ if (!await pathExists2(skillsDir)) {
2619
+ await mkdir3(skillsDir, { recursive: true });
2620
+ }
2621
+ const filePath = join5(skillsDir, `${skill.metadata.id}${SKILL_EXTENSION}`);
2622
+ const content = matter3.stringify(skill.prompt, skill.metadata);
2623
+ await writeFile4(filePath, content, "utf-8");
2704
2624
  }
2705
2625
  async function deleteSkill(configDir, skillId) {
2706
- const deleted = await deleteItem(getSkillsDir(configDir), skillId, SKILL_EXTENSION);
2707
- if (deleted) {
2708
- const { deleteSetting } = await import("./settings-NCLN4JDZ.js");
2626
+ const isDefault = await isDefaultSkill(skillId);
2627
+ if (isDefault) {
2628
+ return { success: false, reason: "Cannot delete built-in defaults" };
2629
+ }
2630
+ const filePath = join5(getSkillsDir(configDir), `${skillId}${SKILL_EXTENSION}`);
2631
+ try {
2632
+ await unlink2(filePath);
2709
2633
  deleteSetting(`${SKILL_SETTING_PREFIX}${skillId}`);
2634
+ return { success: true };
2635
+ } catch {
2636
+ return { success: false };
2710
2637
  }
2711
- return deleted;
2712
2638
  }
2713
2639
 
2714
2640
  // src/server/chat/agent-loop.ts
@@ -3377,7 +3303,7 @@ var callSubAgentTool = {
3377
3303
  };
3378
3304
  }
3379
3305
  try {
3380
- const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-VOWNOP6V.js");
3306
+ const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-YRDPOS6P.js");
3381
3307
  const toolRegistry = getToolRegistryForAgent2(agentDef);
3382
3308
  const turnMetrics = new TurnMetrics();
3383
3309
  const result = await executeSubAgent({
@@ -3632,8 +3558,8 @@ var webFetchTool = createTool(
3632
3558
 
3633
3559
  // src/server/dev-server/manager.ts
3634
3560
  import { spawn as spawn4 } from "child_process";
3635
- import { readFile as readFile8, writeFile as writeFile5, mkdir as mkdir4 } from "fs/promises";
3636
- import { resolve as resolve5, join as join7 } from "path";
3561
+ import { readFile as readFile7, writeFile as writeFile5, mkdir as mkdir4 } from "fs/promises";
3562
+ import { resolve as resolve5, join as join6 } from "path";
3637
3563
  var MAX_LOG_LINES = 2e3;
3638
3564
  var MAX_LOG_BYTES = 1e5;
3639
3565
  var CONFIG_PATH = ".openfox/dev.json";
@@ -3689,8 +3615,8 @@ var DevServerManager = class {
3689
3615
  }
3690
3616
  async loadConfig(workdir) {
3691
3617
  try {
3692
- const configPath = join7(this.resolveWorkdir(workdir), CONFIG_PATH);
3693
- const raw = await readFile8(configPath, "utf-8");
3618
+ const configPath = join6(this.resolveWorkdir(workdir), CONFIG_PATH);
3619
+ const raw = await readFile7(configPath, "utf-8");
3694
3620
  const parsed = JSON.parse(raw);
3695
3621
  if (!parsed.command || !parsed.url) return null;
3696
3622
  return {
@@ -3704,9 +3630,9 @@ var DevServerManager = class {
3704
3630
  }
3705
3631
  async saveConfig(workdir, config) {
3706
3632
  const resolved = this.resolveWorkdir(workdir);
3707
- const dirPath = join7(resolved, ".openfox");
3633
+ const dirPath = join6(resolved, ".openfox");
3708
3634
  await mkdir4(dirPath, { recursive: true });
3709
- const configPath = join7(resolved, CONFIG_PATH);
3635
+ const configPath = join6(resolved, CONFIG_PATH);
3710
3636
  await writeFile5(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
3711
3637
  }
3712
3638
  async start(workdir) {
@@ -4454,14 +4380,12 @@ export {
4454
4380
  cancelPathConfirmationsForSession,
4455
4381
  checkAborted,
4456
4382
  spawnShellProcess,
4457
- findModifiedDefaultFiles,
4458
- ensureDefaultAgents,
4383
+ loadDefaultAgents,
4384
+ loadUserAgents,
4459
4385
  loadAllAgents,
4460
4386
  loadAllAgentsDefault,
4461
4387
  getDefaultAgentIds,
4462
- restoreDefaultAgent,
4463
- getModifiedDefaultAgentIds,
4464
- restoreAllDefaultAgents,
4388
+ getDefaultAgentContent,
4465
4389
  findAgentById,
4466
4390
  getSubAgents,
4467
4391
  agentExists,
@@ -4478,24 +4402,17 @@ export {
4478
4402
  createChatDoneEvent,
4479
4403
  getAllInstructions,
4480
4404
  assembleAgentRequest,
4481
- getBundleDir,
4482
- dirExists,
4483
- ensureDir,
4484
- loadItems,
4485
- saveItem,
4486
- deleteItem,
4487
- findById,
4405
+ pathExists2 as pathExists,
4488
4406
  getDefaultIds,
4489
- restoreDefault,
4490
- ensureDefaultSkills,
4407
+ loadItemsFromDir,
4408
+ loadDefaultSkills,
4409
+ loadUserSkills,
4491
4410
  loadAllSkills,
4492
4411
  getEnabledSkillMetadata,
4493
4412
  isSkillEnabled,
4494
4413
  setSkillEnabled,
4495
4414
  getDefaultSkillIds,
4496
- restoreDefaultSkill,
4497
- getModifiedDefaultSkillIds,
4498
- restoreAllDefaultSkills,
4415
+ getDefaultSkillContent,
4499
4416
  findSkillById,
4500
4417
  skillExists,
4501
4418
  saveSkill,
@@ -4515,4 +4432,4 @@ export {
4515
4432
  getToolRegistryForAgent,
4516
4433
  createToolRegistry
4517
4434
  };
4518
- //# sourceMappingURL=chunk-3WHZ47PY.js.map
4435
+ //# sourceMappingURL=chunk-R7U3CD2U.js.map