openfox 2.0.84 → 2.0.86

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.
Files changed (61) hide show
  1. package/dist/{chat-handler-377ZHEDW.js → chat-handler-AVGJQSYW.js} +16 -15
  2. package/dist/chunk-2Y2K66PD.js +7 -0
  3. package/dist/{chunk-JKZPMRH2.js → chunk-3JYPDZT2.js} +2 -2
  4. package/dist/{chunk-SJTG56CH.js → chunk-47WNBFDO.js} +2 -2
  5. package/dist/{chunk-J5E6ZE7O.js → chunk-4YXILHQC.js} +135 -103
  6. package/dist/{chunk-3D3N2PXI.js → chunk-5W2FIWDH.js} +3 -3
  7. package/dist/{chunk-IIRXKSB5.js → chunk-ACL4YUJH.js} +10 -2
  8. package/dist/{chunk-G4PVYDVM.js → chunk-B6VZS5SC.js} +20 -17
  9. package/dist/{chunk-WL6AOKRD.js → chunk-BKH4SIWV.js} +11 -9
  10. package/dist/{chunk-XIVQNOXU.js → chunk-CK7G2JLY.js} +29 -24
  11. package/dist/chunk-FYYPQ27K.js +399 -0
  12. package/dist/{chunk-FVY2JOTO.js → chunk-H765CIHN.js} +2 -2
  13. package/dist/{chunk-AANVMTYU.js → chunk-L4S5N3WV.js} +8 -3
  14. package/dist/{chunk-VB23QPW3.js → chunk-M6X72DYZ.js} +3 -3
  15. package/dist/{chunk-SBSQD7MG.js → chunk-MTZ3PC6K.js} +2 -2
  16. package/dist/{chunk-NH2PVB6R.js → chunk-N54PQSCH.js} +33 -24
  17. package/dist/{chunk-A2IZ4PWQ.js → chunk-OHKBGMLO.js} +15 -4
  18. package/dist/{chunk-55L4SHCO.js → chunk-PUJO6ITQ.js} +7 -7
  19. package/dist/{chunk-CKWD5V4W.js → chunk-SBVKT4GT.js} +95 -366
  20. package/dist/{chunk-CNJ63FXJ.js → chunk-STFIEU5F.js} +3 -2
  21. package/dist/{chunk-X6BXZFO7.js → chunk-U7RLUZBP.js} +1 -1
  22. package/dist/{chunk-BUXIESO5.js → chunk-V5LOH363.js} +6 -74
  23. package/dist/{chunk-5ZHVQOI3.js → chunk-W23S3TU5.js} +2 -2
  24. package/dist/{chunk-DQP5HSDS.js → chunk-WVMOGE7U.js} +3 -3
  25. package/dist/cli/dev.js +1 -1
  26. package/dist/cli/index.js +1 -1
  27. package/dist/{client-TA2VD4LR.js → client-C2P67MA4.js} +4 -4
  28. package/dist/{compactor-YKESKGHL.js → compactor-2YT66FDZ.js} +10 -8
  29. package/dist/{config-EN3WEH4A.js → config-JN6MW5SL.js} +2 -2
  30. package/dist/{events-GF2WNELM.js → events-OEDAFNEI.js} +7 -4
  31. package/dist/{folding-UACKBHUZ.js → folding-FGTCP73N.js} +7 -2
  32. package/dist/{http-client-QZY7W36Q.js → http-client-I52X7GQB.js} +3 -3
  33. package/dist/{manager-WOUOQVLV.js → manager-TD2UT62O.js} +4 -4
  34. package/dist/{orchestrator-LRKFV4MN.js → orchestrator-AGJ7EMFZ.js} +15 -14
  35. package/dist/package.json +1 -1
  36. package/dist/{path-security-AWDNKRZ4.js → path-security-DWL3R2SF.js} +10 -7
  37. package/dist/{platform-7AK5MB4K.js → platform-OYKGQ7Z3.js} +3 -3
  38. package/dist/{processor-LXVRVPBN.js → processor-VCDVG7RV.js} +16 -15
  39. package/dist/{protocol-Q7X4NEME.js → protocol-BUA2W2KM.js} +3 -3
  40. package/dist/{protocol-9WP7lLec.d.ts → protocol-BzTZcNEh.d.ts} +3 -1
  41. package/dist/provider/index.d.ts +4 -4
  42. package/dist/{provider-QVVJ6XNZ.js → provider-YNYYAR6C.js} +7 -7
  43. package/dist/{provider-manager-7246YSJT.js → provider-manager-3DW3A2VC.js} +5 -5
  44. package/dist/{serve-SYGARZPL.js → serve-6GYDVM34.js} +22 -21
  45. package/dist/server/index.d.ts +4 -4
  46. package/dist/server/index.js +21 -20
  47. package/dist/{server-ZU3IU7WH.js → server-3X46OIYC.js} +17 -16
  48. package/dist/{sessions-SFG42M4W.js → sessions-V3BF2OTU.js} +5 -2
  49. package/dist/{settings-6TJIHDVX.js → settings-AGNYWEIE.js} +2 -2
  50. package/dist/shared/index.d.ts +3 -3
  51. package/dist/shared/index.js +1 -1
  52. package/dist/{tools-6NVILBHW.js → tools-X65P65KF.js} +14 -13
  53. package/dist/{types-ulRvCqQX.d.ts → types-B4wa_vGm.d.ts} +2 -0
  54. package/dist/{types-BtY5XChg.d.ts → types-CrLD4iRS.d.ts} +1 -1
  55. package/dist/{update-VHU2XFPH.js → update-EOPW72IR.js} +2 -2
  56. package/dist/web/assets/index-xfwgrYl9.js +305 -0
  57. package/dist/web/index.html +1 -1
  58. package/dist/web/sw.js +1 -1
  59. package/package.json +1 -1
  60. package/dist/chunk-YWBJRUDI.js +0 -7
  61. package/dist/web/assets/index-BhxPPOY-.js +0 -305
@@ -8,7 +8,7 @@ import {
8
8
  spawnShellProcess,
9
9
  startProcessCommand,
10
10
  stopProcess
11
- } from "./chunk-JKZPMRH2.js";
11
+ } from "./chunk-3JYPDZT2.js";
12
12
  import {
13
13
  createMcpTools
14
14
  } from "./chunk-NWO6GRYE.js";
@@ -26,14 +26,14 @@ import {
26
26
  extractSensitivePathsFromCommand,
27
27
  registerPathConfirmation,
28
28
  requestPathAccess
29
- } from "./chunk-3D3N2PXI.js";
29
+ } from "./chunk-5W2FIWDH.js";
30
30
  import {
31
31
  createChatDoneMessage,
32
32
  createChatMessageMessage,
33
33
  createChatMessageUpdatedMessage,
34
34
  createChatPathConfirmationMessage,
35
35
  createQueueStateMessage
36
- } from "./chunk-SJTG56CH.js";
36
+ } from "./chunk-47WNBFDO.js";
37
37
  import {
38
38
  AskUserInterrupt,
39
39
  askUserTool
@@ -50,7 +50,7 @@ import {
50
50
  createToolCallEvent,
51
51
  createToolResultEvent,
52
52
  streamLLMPure
53
- } from "./chunk-FVY2JOTO.js";
53
+ } from "./chunk-H765CIHN.js";
54
54
  import {
55
55
  startInspectProxy
56
56
  } from "./chunk-EYIWUONA.js";
@@ -65,9 +65,8 @@ import {
65
65
  import {
66
66
  getCurrentContextWindowId,
67
67
  getCurrentWindowMessageOptions,
68
- getEventStore,
69
- getRuntimeConfig
70
- } from "./chunk-BUXIESO5.js";
68
+ getEventStore
69
+ } from "./chunk-V5LOH363.js";
71
70
  import {
72
71
  buildContextMessagesFromEventHistory,
73
72
  foldContextState,
@@ -77,7 +76,16 @@ import {
77
76
  handleToolResult,
78
77
  reorderToolMessages,
79
78
  stripOrphanedToolCalls
80
- } from "./chunk-A2IZ4PWQ.js";
79
+ } from "./chunk-OHKBGMLO.js";
80
+ import {
81
+ deleteItemFromDir,
82
+ findAgentById,
83
+ getRuntimeConfig,
84
+ getSubAgents,
85
+ loadAllAgentsDefault,
86
+ loadItemsFromDir,
87
+ pathExists
88
+ } from "./chunk-FYYPQ27K.js";
81
89
  import {
82
90
  modelSupportsVision
83
91
  } from "./chunk-V4IE7HJY.js";
@@ -97,14 +105,14 @@ import {
97
105
  deleteSetting,
98
106
  getSetting,
99
107
  setSetting
100
- } from "./chunk-CNJ63FXJ.js";
108
+ } from "./chunk-STFIEU5F.js";
101
109
  import {
102
110
  logger
103
111
  } from "./chunk-K44MW7JJ.js";
104
112
  import {
105
113
  loadGlobalConfig,
106
114
  saveGlobalConfig
107
- } from "./chunk-NH2PVB6R.js";
115
+ } from "./chunk-N54PQSCH.js";
108
116
  import {
109
117
  getGlobalConfigDir
110
118
  } from "./chunk-CQGTEGKL.js";
@@ -121,7 +129,7 @@ async function requestUserConfirmation(context, toolLabel, desc) {
121
129
  if (context.dangerLevel === "dangerous") return Promise.resolve(true);
122
130
  if (toolLabel === "workspace" || toolLabel === "command") {
123
131
  try {
124
- const { getSetting: getSetting2, SETTINGS_KEYS: SETTINGS_KEYS2 } = await import("./settings-6TJIHDVX.js");
132
+ const { getSetting: getSetting2, SETTINGS_KEYS: SETTINGS_KEYS2 } = await import("./settings-AGNYWEIE.js");
125
133
  if (getSetting2(SETTINGS_KEYS2.CONFIRM_ON_WORKSPACE_ACTIONS) !== "true") {
126
134
  return Promise.resolve(true);
127
135
  }
@@ -1469,283 +1477,13 @@ ${Object.entries(schema.fields).map(([f, t]) => ` ${f}: ${t}`).join("\n")}`
1469
1477
  );
1470
1478
 
1471
1479
  // src/server/sub-agents/manager.ts
1472
- import { readFile as readFile8, access as access5 } from "fs/promises";
1473
- import { join as join6, dirname as dirname5, isAbsolute as isAbsolute2 } from "path";
1474
-
1475
- // src/server/agents/registry.ts
1476
- import { readdir as readdir3, readFile as readFile5, writeFile as writeFile4, mkdir as mkdir3, access as access3, unlink as unlink2 } from "fs/promises";
1477
- import { join as join3, dirname as dirname2 } from "path";
1478
- import { constants as constants2 } from "fs";
1479
- import { fileURLToPath } from "url";
1480
- import matter2 from "gray-matter";
1481
-
1482
- // src/server/shared/item-loader.ts
1483
- import { readdir as readdir2, readFile as readFile4, access as access2, writeFile as writeFile3, mkdir as mkdir2, unlink } from "fs/promises";
1484
- import { join as join2 } from "path";
1485
- import { constants } from "fs";
1486
- import matter from "gray-matter";
1487
- async function pathExists(path) {
1488
- try {
1489
- await access2(path, constants.R_OK);
1490
- return true;
1491
- } catch {
1492
- return false;
1493
- }
1494
- }
1495
- async function getDefaultIds(dir, extension) {
1496
- try {
1497
- const files = (await readdir2(dir)).filter((f) => f.endsWith(extension));
1498
- return files.map((f) => f.replace(extension, ""));
1499
- } catch {
1500
- return [];
1501
- }
1502
- }
1503
- async function loadItemsFromDir(dir, options) {
1504
- if (!await pathExists(dir)) {
1505
- return [];
1506
- }
1507
- let files;
1508
- try {
1509
- files = (await readdir2(dir)).filter((f) => f.endsWith(options.extension));
1510
- } catch {
1511
- return [];
1512
- }
1513
- const items = [];
1514
- for (const file of files) {
1515
- try {
1516
- const raw = await readFile4(join2(dir, file), "utf-8");
1517
- const { data, content } = matter(raw);
1518
- if (data.id && content.trim()) {
1519
- items.push({
1520
- metadata: data,
1521
- prompt: content.trim()
1522
- });
1523
- } else {
1524
- logger.warn(`Skipping invalid ${options.logName} file`, { file });
1525
- }
1526
- } catch (err) {
1527
- logger.warn(`Failed to parse ${options.logName} file`, {
1528
- file,
1529
- error: err instanceof Error ? err.message : String(err)
1530
- });
1531
- }
1532
- }
1533
- return items;
1534
- }
1535
- async function saveItemToDir(dir, item, ext, serialize) {
1536
- if (!await pathExists(dir)) {
1537
- await mkdir2(dir, { recursive: true });
1538
- }
1539
- const meta = item.metadata;
1540
- const filePath = join2(dir, `${meta.id}${ext}`);
1541
- await writeFile3(filePath, serialize(item), "utf-8");
1542
- }
1543
- var jsonSerializer = (item) => JSON.stringify(item, null, 2) + "\n";
1544
- async function deleteItemFromDir(dir, id, ext) {
1545
- const filePath = join2(dir, `${id}${ext}`);
1546
- try {
1547
- await unlink(filePath);
1548
- return { success: true };
1549
- } catch {
1550
- return { success: false };
1551
- }
1552
- }
1553
-
1554
- // src/server/agents/registry.ts
1555
- var __bundleDir = dirname2(fileURLToPath(import.meta.url));
1556
- var DEFAULTS_DIR = join3(__bundleDir, "defaults");
1557
- var DEFAULTS_DIR_ALT = join3(__bundleDir, "agent-defaults");
1558
- var AGENT_EXTENSION = ".agent.md";
1559
- function getAgentsDir(configDir) {
1560
- return join3(configDir, "agents");
1561
- }
1562
- function getProjectAgentsDir(projectDir) {
1563
- return join3(projectDir, ".openfox", "agents");
1564
- }
1565
- async function pathExists2(path) {
1566
- try {
1567
- await access3(path, constants2.R_OK);
1568
- return true;
1569
- } catch {
1570
- return false;
1571
- }
1572
- }
1573
- function parseAgentFile(raw, filename) {
1574
- const { data, content } = matter2(raw);
1575
- const meta = data;
1576
- if (!meta["id"] || !content.trim()) {
1577
- logger.warn("Skipping invalid agent file", { filename });
1578
- return void 0;
1579
- }
1580
- const metadata = {
1581
- id: String(meta["id"]),
1582
- name: String(meta["name"] ?? meta["id"]),
1583
- description: String(meta["description"] ?? ""),
1584
- subagent: meta["subagent"] === true,
1585
- allowedTools: Array.isArray(meta["allowedTools"]) ? meta["allowedTools"].map(String) : [],
1586
- ...typeof meta["color"] === "string" ? { color: meta["color"] } : {},
1587
- ...Array.isArray(meta["results"]) ? { results: meta["results"].map(String) } : {}
1588
- };
1589
- return { metadata, prompt: content.trim() };
1590
- }
1591
- async function loadAgentsFromDir(dir) {
1592
- if (!await pathExists2(dir)) {
1593
- return [];
1594
- }
1595
- let files;
1596
- try {
1597
- files = (await readdir3(dir)).filter((f) => f.endsWith(AGENT_EXTENSION));
1598
- } catch {
1599
- return [];
1600
- }
1601
- const agents = [];
1602
- for (const file of files) {
1603
- try {
1604
- const raw = await readFile5(join3(dir, file), "utf-8");
1605
- const agent = parseAgentFile(raw, file);
1606
- if (agent) {
1607
- agents.push(agent);
1608
- }
1609
- } catch (err) {
1610
- logger.warn("Failed to parse agent file", { file, error: err instanceof Error ? err.message : String(err) });
1611
- }
1612
- }
1613
- return agents;
1614
- }
1615
- async function loadDefaultAgents() {
1616
- const agents = await loadAgentsFromDir(DEFAULTS_DIR);
1617
- if (agents.length > 0) return agents;
1618
- return loadAgentsFromDir(DEFAULTS_DIR_ALT);
1619
- }
1620
- async function loadUserAgents(configDir) {
1621
- return loadAgentsFromDir(getAgentsDir(configDir));
1622
- }
1623
- async function loadProjectAgents(projectDir) {
1624
- return loadAgentsFromDir(getProjectAgentsDir(projectDir));
1625
- }
1626
- async function loadAllAgents(configDir, projectDir) {
1627
- const [defaultAgents, userAgents] = await Promise.all([loadDefaultAgents(), loadUserAgents(configDir)]);
1628
- const agentMap = /* @__PURE__ */ new Map();
1629
- for (const agent of defaultAgents) {
1630
- agentMap.set(agent.metadata.id, agent);
1631
- }
1632
- for (const agent of userAgents) {
1633
- agentMap.set(agent.metadata.id, agent);
1634
- }
1635
- if (projectDir) {
1636
- const projectAgents = await loadProjectAgents(projectDir);
1637
- for (const agent of projectAgents) {
1638
- agentMap.set(agent.metadata.id, agent);
1639
- }
1640
- }
1641
- return Array.from(agentMap.values());
1642
- }
1643
- async function saveAgentToProject(projectDir, agent) {
1644
- await saveItemToDir(
1645
- getProjectAgentsDir(projectDir),
1646
- agent,
1647
- AGENT_EXTENSION,
1648
- (a) => matter2.stringify(a.prompt, a.metadata)
1649
- );
1650
- }
1651
- async function deleteProjectAgent(projectDir, agentId) {
1652
- const agentsDir = getProjectAgentsDir(projectDir);
1653
- const paths = getAgentFilePaths(agentsDir, agentId);
1654
- for (const filePath of paths) {
1655
- try {
1656
- await unlink2(filePath);
1657
- return { success: true };
1658
- } catch {
1659
- continue;
1660
- }
1661
- }
1662
- return { success: false };
1663
- }
1664
- async function loadAllAgentsDefault() {
1665
- try {
1666
- const config = getRuntimeConfig();
1667
- const configDir = getGlobalConfigDir(config.mode ?? "production");
1668
- return await loadAllAgents(configDir, config.workdir);
1669
- } catch {
1670
- return loadDefaultAgents();
1671
- }
1672
- }
1673
- async function getDefaultAgentIds() {
1674
- for (const dir of [DEFAULTS_DIR, DEFAULTS_DIR_ALT]) {
1675
- try {
1676
- const files = (await readdir3(dir)).filter((f) => f.endsWith(AGENT_EXTENSION));
1677
- return files.map((f) => f.replace(AGENT_EXTENSION, ""));
1678
- } catch {
1679
- }
1680
- }
1681
- return [];
1682
- }
1683
- async function isDefaultAgent(agentId) {
1684
- const defaultIds = await getDefaultAgentIds();
1685
- return defaultIds.includes(agentId);
1686
- }
1687
- function getAgentFilePaths(agentsDir, agentId) {
1688
- const hyphenated = agentId.replace(/_/g, "-");
1689
- return [join3(agentsDir, `${agentId}${AGENT_EXTENSION}`), join3(agentsDir, `${hyphenated}${AGENT_EXTENSION}`)];
1690
- }
1691
- function findAgentById(agentId, agents) {
1692
- return agents.find((a) => a.metadata.id === agentId);
1693
- }
1694
- function getSubAgents(agents) {
1695
- return agents.filter((a) => a.metadata.subagent);
1696
- }
1697
- function getTopLevelAgents(agents) {
1698
- return agents.filter((a) => !a.metadata.subagent);
1699
- }
1700
- async function agentExists(configDir, agentId, projectDir) {
1701
- const agentsDir = getAgentsDir(configDir);
1702
- const paths = getAgentFilePaths(agentsDir, agentId);
1703
- for (const filePath of paths) {
1704
- if (await pathExists2(filePath)) {
1705
- return true;
1706
- }
1707
- }
1708
- if (projectDir) {
1709
- const projectPaths = getAgentFilePaths(getProjectAgentsDir(projectDir), agentId);
1710
- for (const filePath of projectPaths) {
1711
- if (await pathExists2(filePath)) {
1712
- return true;
1713
- }
1714
- }
1715
- }
1716
- return false;
1717
- }
1718
- async function saveAgent(configDir, agent) {
1719
- const agentsDir = getAgentsDir(configDir);
1720
- if (!await pathExists2(agentsDir)) {
1721
- await mkdir3(agentsDir, { recursive: true });
1722
- }
1723
- const filePath = join3(agentsDir, `${agent.metadata.id}${AGENT_EXTENSION}`);
1724
- const content = matter2.stringify(agent.prompt, agent.metadata);
1725
- await writeFile4(filePath, content, "utf-8");
1726
- }
1727
- async function deleteAgent(configDir, agentId) {
1728
- const isDefault = await isDefaultAgent(agentId);
1729
- if (isDefault) {
1730
- return { success: false, reason: "Cannot delete built-in defaults" };
1731
- }
1732
- const agentsDir = getAgentsDir(configDir);
1733
- const paths = getAgentFilePaths(agentsDir, agentId);
1734
- for (const filePath of paths) {
1735
- try {
1736
- await unlink2(filePath);
1737
- return { success: true };
1738
- } catch {
1739
- continue;
1740
- }
1741
- }
1742
- return { success: false };
1743
- }
1480
+ import { readFile as readFile6, access as access3 } from "fs/promises";
1481
+ import { join as join4, dirname as dirname4, isAbsolute as isAbsolute2 } from "path";
1744
1482
 
1745
1483
  // src/server/context/instructions.ts
1746
- import { readFile as readFile6, access as access4 } from "fs/promises";
1747
- import { join as join4, dirname as dirname3 } from "path";
1748
- import { constants as constants3 } from "fs";
1484
+ import { readFile as readFile4, access as access2 } from "fs/promises";
1485
+ import { join as join2, dirname as dirname2 } from "path";
1486
+ import { constants } from "fs";
1749
1487
  var INSTRUCTION_FILENAMES = ["AGENTS.md", "CLAUDE.md"];
1750
1488
  async function findInstructionFiles(workdir) {
1751
1489
  const foundFiles = [];
@@ -1753,7 +1491,7 @@ async function findInstructionFiles(workdir) {
1753
1491
  let currentDir = workdir;
1754
1492
  while (true) {
1755
1493
  pathsToCheck.unshift(currentDir);
1756
- const parentDir = dirname3(currentDir);
1494
+ const parentDir = dirname2(currentDir);
1757
1495
  if (parentDir === currentDir) {
1758
1496
  break;
1759
1497
  }
@@ -1761,7 +1499,7 @@ async function findInstructionFiles(workdir) {
1761
1499
  }
1762
1500
  for (const dir of pathsToCheck) {
1763
1501
  for (const filename of INSTRUCTION_FILENAMES) {
1764
- const filePath = join4(dir, filename);
1502
+ const filePath = join2(dir, filename);
1765
1503
  if (await fileExists(filePath)) {
1766
1504
  foundFiles.push({
1767
1505
  path: filePath,
@@ -1776,7 +1514,7 @@ async function loadInstructions(files) {
1776
1514
  const contents = [];
1777
1515
  for (const file of files) {
1778
1516
  try {
1779
- const content = await readFile6(file.path, "utf-8");
1517
+ const content = await readFile4(file.path, "utf-8");
1780
1518
  contents.push(`Instructions from: ${file.path}
1781
1519
  ${content}`);
1782
1520
  } catch {
@@ -1811,7 +1549,7 @@ ${project.customInstructions}`);
1811
1549
  ${agentContent}`);
1812
1550
  for (const file of agentFiles) {
1813
1551
  try {
1814
- const content = await readFile6(file.path, "utf-8");
1552
+ const content = await readFile4(file.path, "utf-8");
1815
1553
  allFiles.push({ ...file, content });
1816
1554
  } catch {
1817
1555
  allFiles.push(file);
@@ -1826,7 +1564,7 @@ ${agentContent}`);
1826
1564
  }
1827
1565
  async function fileExists(path) {
1828
1566
  try {
1829
- await access4(path, constants3.R_OK);
1567
+ await access2(path, constants.R_OK);
1830
1568
  return true;
1831
1569
  } catch {
1832
1570
  return false;
@@ -1834,22 +1572,22 @@ async function fileExists(path) {
1834
1572
  }
1835
1573
 
1836
1574
  // src/server/skills/registry.ts
1837
- import { writeFile as writeFile5, mkdir as mkdir4, unlink as unlink3, readdir as readdir4, readFile as readFile7, realpath, rm } from "fs/promises";
1838
- import { join as join5, dirname as dirname4 } from "path";
1839
- import { fileURLToPath as fileURLToPath2 } from "url";
1575
+ import { writeFile as writeFile3, mkdir as mkdir2, unlink, readdir as readdir2, readFile as readFile5, realpath, rm } from "fs/promises";
1576
+ import { join as join3, dirname as dirname3 } from "path";
1577
+ import { fileURLToPath } from "url";
1840
1578
  import { homedir } from "os";
1841
- import matter3 from "gray-matter";
1842
- var __bundleDir2 = dirname4(fileURLToPath2(import.meta.url));
1843
- var DEFAULTS_DIR2 = join5(__bundleDir2, "defaults");
1844
- var DEFAULTS_DIR_ALT2 = join5(__bundleDir2, "skill-defaults");
1579
+ import matter from "gray-matter";
1580
+ var __bundleDir = dirname3(fileURLToPath(import.meta.url));
1581
+ var DEFAULTS_DIR = join3(__bundleDir, "defaults");
1582
+ var DEFAULTS_DIR_ALT = join3(__bundleDir, "skill-defaults");
1845
1583
  var SKILL_EXTENSION = ".skill.md";
1846
1584
  var SKILL_SETTING_PREFIX = "skill.enabled.";
1847
1585
  var PORTABLE_NAME_REGEX = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
1848
1586
  function getSkillsDir(configDir) {
1849
- return join5(configDir, "skills");
1587
+ return join3(configDir, "skills");
1850
1588
  }
1851
1589
  function getProjectSkillsDir(projectDir) {
1852
- return join5(projectDir, ".openfox", "skills");
1590
+ return join3(projectDir, ".openfox", "skills");
1853
1591
  }
1854
1592
  function portableDisplayName(data, id) {
1855
1593
  const metadata = data["metadata"];
@@ -1870,18 +1608,18 @@ function portableVersion(data) {
1870
1608
  async function loadPortableSkills(dir, source) {
1871
1609
  let entries;
1872
1610
  try {
1873
- entries = await readdir4(dir, { withFileTypes: true });
1611
+ entries = await readdir2(dir, { withFileTypes: true });
1874
1612
  } catch {
1875
1613
  return [];
1876
1614
  }
1877
1615
  const skills = [];
1878
1616
  for (const entry of entries) {
1879
1617
  if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;
1880
- const packageDir = join5(dir, entry.name);
1881
- const entrypoint = join5(packageDir, "SKILL.md");
1618
+ const packageDir = join3(dir, entry.name);
1619
+ const entrypoint = join3(packageDir, "SKILL.md");
1882
1620
  try {
1883
- const content = await readFile7(entrypoint, "utf-8");
1884
- const parsed = matter3(content);
1621
+ const content = await readFile5(entrypoint, "utf-8");
1622
+ const parsed = matter(content);
1885
1623
  const data = parsed.data;
1886
1624
  const id = typeof data["name"] === "string" ? data["name"].trim() : "";
1887
1625
  const description = typeof data["description"] === "string" ? data["description"].trim() : "";
@@ -1918,7 +1656,7 @@ async function loadPortableSkills(dir, source) {
1918
1656
  async function annotateLegacySkills(skills, dir, source) {
1919
1657
  return Promise.all(
1920
1658
  skills.map(async (skill) => {
1921
- const entrypoint = join5(dir, `${skill.metadata.id}${SKILL_EXTENSION}`);
1659
+ const entrypoint = join3(dir, `${skill.metadata.id}${SKILL_EXTENSION}`);
1922
1660
  let resolvedEntrypoint = entrypoint;
1923
1661
  try {
1924
1662
  resolvedEntrypoint = await realpath(entrypoint);
@@ -1928,7 +1666,7 @@ async function annotateLegacySkills(skills, dir, source) {
1928
1666
  ...skill,
1929
1667
  rawMetadata: { ...skill.metadata },
1930
1668
  entrypoint: resolvedEntrypoint,
1931
- directory: dirname4(resolvedEntrypoint),
1669
+ directory: dirname3(resolvedEntrypoint),
1932
1670
  source,
1933
1671
  legacy: true,
1934
1672
  warnings: ["Legacy .skill.md format"]
@@ -1957,9 +1695,9 @@ function getSelectedSkillDirectories() {
1957
1695
  }
1958
1696
  }
1959
1697
  async function loadDefaultSkills() {
1960
- const defaults = await loadSkillsDirectory(DEFAULTS_DIR2, "bundled");
1698
+ const defaults = await loadSkillsDirectory(DEFAULTS_DIR, "bundled");
1961
1699
  if (defaults.length) return defaults;
1962
- return loadSkillsDirectory(DEFAULTS_DIR_ALT2, "bundled");
1700
+ return loadSkillsDirectory(DEFAULTS_DIR_ALT, "bundled");
1963
1701
  }
1964
1702
  async function loadUserSkills(configDir) {
1965
1703
  return loadSkillsDirectory(getSkillsDir(configDir), "global-openfox");
@@ -1973,14 +1711,14 @@ async function loadAllSkills(configDir, projectDir, options = {}) {
1973
1711
  async function loadAllSkillsWithDiagnostics(configDir, projectDir, options = {}) {
1974
1712
  const home = options.homeDir ?? homedir();
1975
1713
  const selected = (options.selectedDirectories ?? getSelectedSkillDirectories()).map(
1976
- (dir) => dir === "~" ? home : dir.startsWith("~/") ? join5(home, dir.slice(2)) : dir
1714
+ (dir) => dir === "~" ? home : dir.startsWith("~/") ? join3(home, dir.slice(2)) : dir
1977
1715
  );
1978
1716
  const locations = [
1979
1717
  loadDefaultSkills(),
1980
- loadSkillsDirectory(join5(home, ".agents", "skills"), "global-shared"),
1718
+ loadSkillsDirectory(join3(home, ".agents", "skills"), "global-shared"),
1981
1719
  loadUserSkills(configDir),
1982
1720
  ...selected.map((dir) => loadSkillsDirectory(dir, "selected")),
1983
- ...projectDir ? [loadSkillsDirectory(join5(projectDir, ".agents", "skills"), "project-shared"), loadProjectSkills(projectDir)] : []
1721
+ ...projectDir ? [loadSkillsDirectory(join3(projectDir, ".agents", "skills"), "project-shared"), loadProjectSkills(projectDir)] : []
1984
1722
  ];
1985
1723
  const groups = await Promise.all(locations);
1986
1724
  const skillMap = /* @__PURE__ */ new Map();
@@ -2030,11 +1768,11 @@ function findSkillById(skillId, skills) {
2030
1768
  return skills.find((s) => s.metadata.id === skillId);
2031
1769
  }
2032
1770
  async function skillExists(configDir, skillId, projectDir) {
2033
- if (await pathExists(join5(getSkillsDir(configDir), `${skillId}${SKILL_EXTENSION}`))) return true;
2034
- if (await pathExists(join5(getSkillsDir(configDir), skillId, "SKILL.md"))) return true;
2035
- if (projectDir && await pathExists(join5(getProjectSkillsDir(projectDir), `${skillId}${SKILL_EXTENSION}`)))
1771
+ if (await pathExists(join3(getSkillsDir(configDir), `${skillId}${SKILL_EXTENSION}`))) return true;
1772
+ if (await pathExists(join3(getSkillsDir(configDir), skillId, "SKILL.md"))) return true;
1773
+ if (projectDir && await pathExists(join3(getProjectSkillsDir(projectDir), `${skillId}${SKILL_EXTENSION}`)))
2036
1774
  return true;
2037
- if (projectDir && await pathExists(join5(getProjectSkillsDir(projectDir), skillId, "SKILL.md"))) return true;
1775
+ if (projectDir && await pathExists(join3(getProjectSkillsDir(projectDir), skillId, "SKILL.md"))) return true;
2038
1776
  return false;
2039
1777
  }
2040
1778
  function portableFrontmatter(skill) {
@@ -2050,9 +1788,9 @@ function portableFrontmatter(skill) {
2050
1788
  };
2051
1789
  }
2052
1790
  async function savePortableSkill(dir, skill) {
2053
- const packageDir = join5(dir, skill.metadata.id);
2054
- await mkdir4(packageDir, { recursive: true });
2055
- await writeFile5(join5(packageDir, "SKILL.md"), matter3.stringify(skill.prompt, portableFrontmatter(skill)), "utf-8");
1791
+ const packageDir = join3(dir, skill.metadata.id);
1792
+ await mkdir2(packageDir, { recursive: true });
1793
+ await writeFile3(join3(packageDir, "SKILL.md"), matter.stringify(skill.prompt, portableFrontmatter(skill)), "utf-8");
2056
1794
  }
2057
1795
  async function saveSkill(configDir, skill) {
2058
1796
  await savePortableSkill(getSkillsDir(configDir), skill);
@@ -2099,7 +1837,7 @@ async function updateOwnedSkill(existing, changes) {
2099
1837
  rawMetadata: frontmatter,
2100
1838
  prompt: changes.prompt ?? existing.prompt
2101
1839
  };
2102
- await writeFile5(existing.entrypoint, matter3.stringify(updated2.prompt, frontmatter), "utf-8");
1840
+ await writeFile3(existing.entrypoint, matter.stringify(updated2.prompt, frontmatter), "utf-8");
2103
1841
  return updated2;
2104
1842
  }
2105
1843
  const metadata = {
@@ -2114,7 +1852,7 @@ async function updateOwnedSkill(existing, changes) {
2114
1852
  rawMetadata: metadata,
2115
1853
  prompt: changes.prompt ?? existing.prompt
2116
1854
  };
2117
- await writeFile5(existing.entrypoint, matter3.stringify(updated.prompt, metadata), "utf-8");
1855
+ await writeFile3(existing.entrypoint, matter.stringify(updated.prompt, metadata), "utf-8");
2118
1856
  return updated;
2119
1857
  }
2120
1858
  async function deleteOwnedSkill(existing) {
@@ -2122,8 +1860,8 @@ async function deleteOwnedSkill(existing) {
2122
1860
  return { success: false, reason: "This skill is read-only" };
2123
1861
  }
2124
1862
  try {
2125
- if (existing.legacy) await unlink3(existing.entrypoint);
2126
- else await rm(dirname4(existing.entrypoint), { recursive: true });
1863
+ if (existing.legacy) await unlink(existing.entrypoint);
1864
+ else await rm(dirname3(existing.entrypoint), { recursive: true });
2127
1865
  deleteSetting(`${SKILL_SETTING_PREFIX}${existing.metadata.id}`);
2128
1866
  return { success: true };
2129
1867
  } catch {
@@ -2135,9 +1873,9 @@ async function deleteSkill(configDir, skillId) {
2135
1873
  if (isDefault) {
2136
1874
  return { success: false, reason: "Cannot delete built-in defaults" };
2137
1875
  }
2138
- const filePath = join5(getSkillsDir(configDir), `${skillId}${SKILL_EXTENSION}`);
1876
+ const filePath = join3(getSkillsDir(configDir), `${skillId}${SKILL_EXTENSION}`);
2139
1877
  try {
2140
- await unlink3(filePath);
1878
+ await unlink(filePath);
2141
1879
  deleteSetting(`${SKILL_SETTING_PREFIX}${skillId}`);
2142
1880
  return { success: true };
2143
1881
  } catch {
@@ -2577,7 +2315,7 @@ ${CONTINUE_PROMPT}` : CONTINUE_PROMPT;
2577
2315
  sessionManager.setCurrentContextSize(sessionId, result.usage.promptTokens, config.subAgentMetadata?.subAgentId);
2578
2316
  if (!compacting) {
2579
2317
  const contextState2 = sessionManager.getContextState(sessionId);
2580
- const { shouldCompact, appendCompactionPrompt } = await import("./compactor-YKESKGHL.js");
2318
+ const { shouldCompact, appendCompactionPrompt } = await import("./compactor-2YT66FDZ.js");
2581
2319
  if (shouldCompact(
2582
2320
  contextState2.currentTokens,
2583
2321
  contextState2.maxTokens,
@@ -2940,7 +2678,7 @@ async function describeImageFromDataUrl(dataUrl, visionModel, options) {
2940
2678
  // src/server/context/image-processor.ts
2941
2679
  async function loadVisionModelFromGlobalConfig() {
2942
2680
  try {
2943
- const { loadGlobalConfig: loadGlobalConfig2, getVisionFallback } = await import("./config-EN3WEH4A.js");
2681
+ const { loadGlobalConfig: loadGlobalConfig2, getVisionFallback } = await import("./config-JN6MW5SL.js");
2944
2682
  const runtimeConfig = getRuntimeConfig();
2945
2683
  const mode = runtimeConfig.mode ?? "production";
2946
2684
  const globalConfig = await loadGlobalConfig2(mode);
@@ -3311,10 +3049,10 @@ async function loadGitIgnoreRules(workdir) {
3311
3049
  if (!isAbsolute2(workdir)) return "";
3312
3050
  let currentDir = workdir;
3313
3051
  while (true) {
3314
- const gitignorePath = join6(currentDir, ".gitignore");
3052
+ const gitignorePath = join4(currentDir, ".gitignore");
3315
3053
  try {
3316
- await access5(gitignorePath);
3317
- const content = await readFile8(gitignorePath, "utf-8");
3054
+ await access3(gitignorePath);
3055
+ const content = await readFile6(gitignorePath, "utf-8");
3318
3056
  const trimmed = content.trim();
3319
3057
  if (!trimmed) return "";
3320
3058
  const lines = trimmed.split("\n");
@@ -3328,7 +3066,7 @@ The following patterns from \`.gitignore\` should be excluded from file searches
3328
3066
  ${final}`;
3329
3067
  } catch {
3330
3068
  }
3331
- const parentDir = dirname5(currentDir);
3069
+ const parentDir = dirname4(currentDir);
3332
3070
  if (parentDir === currentDir) break;
3333
3071
  currentDir = parentDir;
3334
3072
  }
@@ -3516,7 +3254,7 @@ var callSubAgentTool = {
3516
3254
  };
3517
3255
  }
3518
3256
  try {
3519
- const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-6NVILBHW.js");
3257
+ const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-X65P65KF.js");
3520
3258
  const toolRegistry = getToolRegistryForAgent2(agentDef);
3521
3259
  const turnMetrics = new TurnMetrics();
3522
3260
  const result = await executeSubAgent({
@@ -3801,8 +3539,8 @@ var webFetchTool = createTool(
3801
3539
 
3802
3540
  // src/server/dev-server/manager.ts
3803
3541
  import "child_process";
3804
- import { readFile as readFile9, writeFile as writeFile6, mkdir as mkdir5 } from "fs/promises";
3805
- import { resolve as resolve4, join as join7 } from "path";
3542
+ import { readFile as readFile7, writeFile as writeFile4, mkdir as mkdir3 } from "fs/promises";
3543
+ import { resolve as resolve4, join as join5 } from "path";
3806
3544
  import net from "net";
3807
3545
  var MAX_LOG_LINES = 2e3;
3808
3546
  var MAX_LOG_BYTES = 1e5;
@@ -3810,7 +3548,7 @@ var DEFAULT_PROBE_PORT = 10469;
3810
3548
  var MAX_PORT_SCAN = 200;
3811
3549
  var PROBE_TIMEOUT_MS = 300;
3812
3550
  var getDevServerConfigPath = (workdir) => {
3813
- return join7(resolve4(workdir), ".openfox", "dev.json");
3551
+ return join5(resolve4(workdir), ".openfox", "dev.json");
3814
3552
  };
3815
3553
  var ERROR_PATTERNS = [
3816
3554
  /EADDRINUSE/,
@@ -3878,8 +3616,11 @@ var DevServerManager = class {
3878
3616
  }
3879
3617
  emitStateChange(workdir, state, errorMessage) {
3880
3618
  const resolved = this.resolveWorkdir(workdir);
3619
+ const instance = this.getInstance(workdir);
3620
+ const url = instance.resolvedUrl ?? instance.config?.url ?? null;
3621
+ const inspectProxyPort = instance.inspectProxyPort;
3881
3622
  for (const listener of this.stateListeners) {
3882
- listener(resolved, state, errorMessage);
3623
+ listener(resolved, state, errorMessage, url, inspectProxyPort);
3883
3624
  }
3884
3625
  }
3885
3626
  /** Probe whether a TCP port is in use */
@@ -3931,7 +3672,7 @@ var DevServerManager = class {
3931
3672
  const tryLoad = async (dir) => {
3932
3673
  try {
3933
3674
  const configPath = getDevServerConfigPath(dir);
3934
- const raw = await readFile9(configPath, "utf-8");
3675
+ const raw = await readFile7(configPath, "utf-8");
3935
3676
  const parsed = JSON.parse(raw);
3936
3677
  if (!parsed.command || !parsed.url) return null;
3937
3678
  return {
@@ -3957,10 +3698,10 @@ var DevServerManager = class {
3957
3698
  }
3958
3699
  async saveConfig(workdir, config) {
3959
3700
  const resolved = this.resolveWorkdir(workdir);
3960
- const dirPath = join7(resolved, ".openfox");
3961
- await mkdir5(dirPath, { recursive: true });
3701
+ const dirPath = join5(resolved, ".openfox");
3702
+ await mkdir3(dirPath, { recursive: true });
3962
3703
  const configPath = getDevServerConfigPath(workdir);
3963
- await writeFile6(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
3704
+ await writeFile4(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
3964
3705
  }
3965
3706
  async start(workdir) {
3966
3707
  const instance = this.getInstance(workdir);
@@ -4519,7 +4260,7 @@ var mcpConfigTool = createTool(
4519
4260
  mcpNotifyChanged?.(sessionId);
4520
4261
  }
4521
4262
  async function rebuildTools() {
4522
- const { setMcpTools: setMcpTools2 } = await import("./tools-6NVILBHW.js");
4263
+ const { setMcpTools: setMcpTools2 } = await import("./tools-X65P65KF.js");
4523
4264
  const mcpTools = createMcpTools(mcpManagerForTools);
4524
4265
  setMcpTools2(mcpTools);
4525
4266
  }
@@ -4798,7 +4539,7 @@ var workspaceTool = createTool(
4798
4539
  type: "function",
4799
4540
  function: {
4800
4541
  name: "workspace",
4801
- description: 'Manage workspaces for the current session. A workspace is a cloned copy of the project.\n\nUse "switch" to move between workspaces. Target "original" for the project root, or a workspace name.\nIf the workspace does not exist yet, it is created automatically.\n\nYou can also change the branch of the current workspace by calling switch with the current\nworkspace name and a branch parameter. The branch will be checked out without recreating\nthe workspace and without losing uncommitted changes.\n\nIf the requested branch does not exist, it will be created. By default it is based on the\ndefault branch of the project (origin/HEAD). You can specify sourceBranch to base the new\nbranch on a different existing branch.\n\nActions that change the workspace (switch, delete) require explicit user approval via a confirmation dialog.\n\nSetup commands (e.g. npm install) are configured via .openfox/workspace.json.\n\nActions:\n- switch: Switch to a workspace (target: "original" or a name, optional branch for new workspaces)\n- list: List all workspaces with their current branch and active status\n- delete: Delete a workspace by name (cannot delete "original")',
4542
+ description: 'Manage workspaces for the current session. A workspace is a cloned copy of the project.\n\nUse "switch" to move between workspaces. Target "original" for the project root, or a workspace name.\nIf the workspace does not exist yet, it is created automatically.\n\nYou can also change the branch of the current workspace by calling switch with the current\nworkspace name and a branch parameter. The branch will be checked out without recreating\nthe workspace and without losing uncommitted changes.\n\nIf the requested branch does not exist, it will be created. By default it is based on the\ndefault branch of the project (origin/HEAD). You can specify sourceBranch to base the new\nbranch on a different existing branch.\n\nActions that change the workspace (switch, delete) require explicit user approval via a confirmation dialog.\n\nSetup commands (e.g. npm install) are configured via .openfox/workspace.json.\n\nActions:\n- switch: Switch to a workspace (target: "original" or a name, optional branch for new workspaces)\n- list: List all workspaces with their current branch and active status\n- delete: Delete a workspace by name (cannot delete "original"). Use force=true to auto-switch other sessions that reference this workspace.',
4802
4543
  parameters: {
4803
4544
  type: "object",
4804
4545
  properties: {
@@ -4818,6 +4559,10 @@ var workspaceTool = createTool(
4818
4559
  sourceBranch: {
4819
4560
  type: "string",
4820
4561
  description: "If branch does not exist, base the new branch on this existing branch. Default: origin/HEAD."
4562
+ },
4563
+ force: {
4564
+ type: "boolean",
4565
+ description: "For action=delete: force deletion by auto-switching other sessions that reference this workspace to original first."
4821
4566
  }
4822
4567
  },
4823
4568
  required: ["action"]
@@ -4886,9 +4631,14 @@ var workspaceTool = createTool(
4886
4631
  if (await isGitRepository(context.workdir) === false) {
4887
4632
  return helpers.error("Project is not a git repository");
4888
4633
  }
4889
- const approved = await requestUserConfirmation(context, "workspace", `Delete workspace "${args.target}"`);
4634
+ const forceDesc = args.force ? " (will auto-switch other sessions to original)" : "";
4635
+ const approved = await requestUserConfirmation(
4636
+ context,
4637
+ "workspace",
4638
+ `Delete workspace "${args.target}"${forceDesc}`
4639
+ );
4890
4640
  if (!approved) return helpers.error(`User denied: delete workspace "${args.target}"`);
4891
- await sessionManager.deleteWorkspace(sessionId, args.target);
4641
+ await sessionManager.deleteWorkspace(sessionId, args.target, args.force === true);
4892
4642
  return helpers.success(
4893
4643
  JSON.stringify(
4894
4644
  {
@@ -5128,27 +4878,6 @@ function createToolRegistry() {
5128
4878
  }
5129
4879
 
5130
4880
  export {
5131
- pathExists,
5132
- getDefaultIds,
5133
- loadItemsFromDir,
5134
- saveItemToDir,
5135
- jsonSerializer,
5136
- deleteItemFromDir,
5137
- loadDefaultAgents,
5138
- loadUserAgents,
5139
- loadProjectAgents,
5140
- loadAllAgents,
5141
- saveAgentToProject,
5142
- deleteProjectAgent,
5143
- loadAllAgentsDefault,
5144
- getDefaultAgentIds,
5145
- isDefaultAgent,
5146
- findAgentById,
5147
- getSubAgents,
5148
- getTopLevelAgents,
5149
- agentExists,
5150
- saveAgent,
5151
- deleteAgent,
5152
4881
  getAllInstructions,
5153
4882
  loadDefaultSkills,
5154
4883
  loadUserSkills,
@@ -5188,4 +4917,4 @@ export {
5188
4917
  getToolRegistryForAgent,
5189
4918
  createToolRegistry
5190
4919
  };
5191
- //# sourceMappingURL=chunk-CKWD5V4W.js.map
4920
+ //# sourceMappingURL=chunk-SBVKT4GT.js.map