reasonix 0.43.0 → 0.44.0

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 (169) hide show
  1. package/README.md +49 -11
  2. package/README.zh-CN.md +35 -7
  3. package/dashboard/app.css +225 -4
  4. package/dashboard/dist/app.js +6441 -6080
  5. package/dashboard/dist/app.js.map +1 -1
  6. package/data/deepseek-tokenizer.json.gz +0 -0
  7. package/dist/cli/{acp-DAGPCVFZ.js → acp-TYZ2CTDL.js} +28 -30
  8. package/dist/cli/acp-TYZ2CTDL.js.map +1 -0
  9. package/dist/cli/chat-TH7VNNCJ.js +51 -0
  10. package/dist/cli/chunk-2425HK6U.js +0 -0
  11. package/dist/cli/chunk-25T6CVUP.js +0 -0
  12. package/dist/cli/chunk-2UQP6H6T.js +0 -0
  13. package/dist/cli/{chunk-3Z6IBU3D.js → chunk-2V6EAEUW.js} +95 -31
  14. package/dist/cli/chunk-2V6EAEUW.js.map +1 -0
  15. package/dist/cli/{chunk-XCGGEJTI.js → chunk-4CTDEJUF.js} +2 -2
  16. package/dist/cli/chunk-4QUNBQQ2.js +0 -0
  17. package/dist/cli/{chunk-74EX7SUH.js → chunk-5QCB62C4.js} +33 -7
  18. package/dist/cli/{chunk-74EX7SUH.js.map → chunk-5QCB62C4.js.map} +1 -1
  19. package/dist/cli/chunk-6OWJV3YW.js +390 -0
  20. package/dist/cli/chunk-6OWJV3YW.js.map +1 -0
  21. package/dist/cli/chunk-6PBZN4VI.js +0 -0
  22. package/dist/cli/{chunk-7O5ALB4C.js → chunk-7CIGMZT3.js} +2 -2
  23. package/dist/cli/{chunk-H6PS7IUE.js → chunk-7UCMM425.js} +7 -3
  24. package/dist/cli/chunk-7UCMM425.js.map +1 -0
  25. package/dist/cli/{chunk-TJX6BFZZ.js → chunk-AB2RED3C.js} +3 -3
  26. package/dist/cli/{chunk-XPDVG52A.js → chunk-AVFXO2EZ.js} +361 -13
  27. package/dist/cli/chunk-AVFXO2EZ.js.map +1 -0
  28. package/dist/cli/{chunk-FHOGSSCH.js → chunk-C53JQES5.js} +3 -3
  29. package/dist/cli/{chunk-RE4RAVFF.js → chunk-CGDR2ELH.js} +92 -30
  30. package/dist/cli/chunk-CGDR2ELH.js.map +1 -0
  31. package/dist/cli/{chunk-OSZC7C6F.js → chunk-CWZKQ5FE.js} +7 -4
  32. package/dist/cli/chunk-CWZKQ5FE.js.map +1 -0
  33. package/dist/cli/{devtools-YECO25QO.js → chunk-FEZK652I.js} +10 -85
  34. package/dist/cli/chunk-FEZK652I.js.map +1 -0
  35. package/dist/cli/{chunk-45U62RI3.js → chunk-HNXDZGC6.js} +104 -2
  36. package/dist/cli/chunk-HNXDZGC6.js.map +1 -0
  37. package/dist/cli/chunk-J5XJHLWM.js +0 -0
  38. package/dist/cli/chunk-JMBMLOBP.js +0 -0
  39. package/dist/cli/{chunk-5JJRUIPA.js → chunk-JNAQYELD.js} +16 -8
  40. package/dist/cli/{chunk-5JJRUIPA.js.map → chunk-JNAQYELD.js.map} +1 -1
  41. package/dist/cli/{chunk-YFGF5NKA.js → chunk-KGBG6M2X.js} +19 -15
  42. package/dist/cli/chunk-KGBG6M2X.js.map +1 -0
  43. package/dist/cli/{chunk-3BXRZFWS.js → chunk-KLQTAZIY.js} +12 -4
  44. package/dist/cli/chunk-KLQTAZIY.js.map +1 -0
  45. package/dist/cli/{chunk-VK5HG73G.js → chunk-KM465GST.js} +9 -9
  46. package/dist/cli/{chunk-DOYHN4KB.js → chunk-LIR2HBQH.js} +2 -2
  47. package/dist/cli/{chunk-YYQAUTTN.js → chunk-MJ6W5UN3.js} +2 -2
  48. package/dist/cli/{chunk-6PZ3CXBP.js → chunk-MRHHQJAQ.js} +5 -4
  49. package/dist/cli/chunk-MRHHQJAQ.js.map +1 -0
  50. package/dist/cli/{chunk-PQXPXJBJ.js → chunk-NVURFF27.js} +16 -5
  51. package/dist/cli/chunk-NVURFF27.js.map +1 -0
  52. package/dist/cli/{chunk-2R4QCDOZ.js → chunk-OPFUUYHL.js} +540 -287
  53. package/dist/cli/chunk-OPFUUYHL.js.map +1 -0
  54. package/dist/cli/chunk-PLHAZOLZ.js +0 -0
  55. package/dist/cli/{chunk-HFEAY5DT.js → chunk-R3CTO2HM.js} +2 -2
  56. package/dist/cli/{chunk-O52OLQL3.js → chunk-RDRC3XDT.js} +136 -38
  57. package/dist/cli/chunk-RDRC3XDT.js.map +1 -0
  58. package/dist/cli/chunk-S4XVGLRW.js +0 -0
  59. package/dist/cli/chunk-SZ5XES2N.js +0 -0
  60. package/dist/cli/{chunk-2K65GZBT.js → chunk-TEUDEGX2.js} +64 -19
  61. package/dist/cli/chunk-TEUDEGX2.js.map +1 -0
  62. package/dist/cli/{chunk-2Z35JOA4.js → chunk-TKVXTQ3T.js} +4 -4
  63. package/dist/cli/{chunk-2Z35JOA4.js.map → chunk-TKVXTQ3T.js.map} +1 -1
  64. package/dist/cli/chunk-TUK7OWJA.js +0 -0
  65. package/dist/cli/{chunk-32TIKD5U.js → chunk-TXJMRPIL.js} +3 -3
  66. package/dist/cli/{chunk-2KDUS647.js → chunk-V26WPN3J.js} +7 -4
  67. package/dist/cli/chunk-V26WPN3J.js.map +1 -0
  68. package/dist/cli/{chunk-F3PXYSNN.js → chunk-WK3UFQY3.js} +2 -2
  69. package/dist/cli/{chunk-6G3CUUFG.js → chunk-X53B3JIX.js} +3 -3
  70. package/dist/cli/{chunk-6G3CUUFG.js.map → chunk-X53B3JIX.js.map} +1 -1
  71. package/dist/cli/chunk-XJXDHAES.js +0 -0
  72. package/dist/cli/{chunk-6AK4EY3D.js → chunk-XSU4QVFW.js} +1 -81
  73. package/dist/cli/chunk-XSU4QVFW.js.map +1 -0
  74. package/dist/cli/chunk-XXC2BYTV.js +0 -0
  75. package/dist/cli/{chunk-P7EKE5ZQ.js → chunk-Z4S7EYXG.js} +4482 -1310
  76. package/dist/cli/chunk-Z4S7EYXG.js.map +1 -0
  77. package/dist/cli/chunk-ZZM6QJ4W.js +0 -0
  78. package/dist/cli/{chunk-YQ6NTIIE.js → chunk-ZZYBBX5N.js} +13 -5
  79. package/dist/cli/chunk-ZZYBBX5N.js.map +1 -0
  80. package/dist/cli/{code-SMKEW6CD.js → code-PSVJ3KEN.js} +48 -36
  81. package/dist/cli/code-PSVJ3KEN.js.map +1 -0
  82. package/dist/cli/{commands-FVVB5FZF.js → commands-OCU42XG4.js} +4 -4
  83. package/dist/cli/{commit-HE4VSPZ7.js → commit-XCQIQCYG.js} +3 -3
  84. package/dist/cli/{desktop-Q7NDXCON.js → desktop-KWGR4BNE.js} +210 -69
  85. package/dist/cli/desktop-KWGR4BNE.js.map +1 -0
  86. package/dist/cli/devtools-HW3WDT3Q.js +91 -0
  87. package/dist/cli/devtools-HW3WDT3Q.js.map +1 -0
  88. package/dist/cli/{diff-435UTPC5.js → diff-NHANTNC3.js} +9 -9
  89. package/dist/cli/{doctor-OT7KH75K.js → doctor-CC5CLOGG.js} +10 -10
  90. package/dist/cli/events-XEFAD5VX.js +0 -0
  91. package/dist/cli/index.js +132 -94
  92. package/dist/cli/index.js.map +1 -1
  93. package/dist/cli/{mcp-WUL2WO75.js → mcp-MPVGBBJF.js} +2 -2
  94. package/dist/cli/{mcp-browse-RR7R4XET.js → mcp-browse-4XOTC3FJ.js} +3 -3
  95. package/dist/cli/{mcp-inspect-REGLYBWT.js → mcp-inspect-CEMGKKAH.js} +14 -9
  96. package/dist/cli/mcp-inspect-CEMGKKAH.js.map +1 -0
  97. package/dist/cli/{prompt-UW6EFLVR.js → prompt-2D7ID24X.js} +4 -4
  98. package/dist/cli/prune-sessions-3RWUBYRS.js +0 -0
  99. package/dist/cli/{replay-YOURXV4C.js → replay-SR44E6RS.js} +10 -10
  100. package/dist/cli/{run-Q6BUXV66.js → run-MDGL27WL.js} +35 -36
  101. package/dist/cli/run-MDGL27WL.js.map +1 -0
  102. package/dist/cli/{server-XGDBRWMB.js → server-27ARQXIZ.js} +67 -24
  103. package/dist/cli/server-27ARQXIZ.js.map +1 -0
  104. package/dist/cli/{sessions-FH7QVYSY.js → sessions-CKQXCYGP.js} +18 -18
  105. package/dist/cli/sessions-CKQXCYGP.js.map +1 -0
  106. package/dist/cli/{setup-VDS6SVEP.js → setup-TPAGSVXO.js} +6 -6
  107. package/dist/cli/{stats-MQVI2XQH.js → stats-DPUBZNVX.js} +6 -4
  108. package/dist/cli/update-6ITLPRDV.js +0 -0
  109. package/dist/cli/{version-DAHGZY5N.js → version-2X3BHVVK.js} +15 -15
  110. package/dist/index.d.ts +181 -53
  111. package/dist/index.js +1322 -533
  112. package/dist/index.js.map +1 -1
  113. package/package.json +21 -8
  114. package/dist/cli/.-3G6VX5S7.js +0 -327
  115. package/dist/cli/.-6YRPB2C7.js +0 -329
  116. package/dist/cli/.-EYSVINK3.js +0 -317
  117. package/dist/cli/acp-DAGPCVFZ.js.map +0 -1
  118. package/dist/cli/chat-7ES4IBNH.js +0 -50
  119. package/dist/cli/chunk-2K65GZBT.js.map +0 -1
  120. package/dist/cli/chunk-2KDUS647.js.map +0 -1
  121. package/dist/cli/chunk-2R4QCDOZ.js.map +0 -1
  122. package/dist/cli/chunk-3BXRZFWS.js.map +0 -1
  123. package/dist/cli/chunk-3Z6IBU3D.js.map +0 -1
  124. package/dist/cli/chunk-45U62RI3.js.map +0 -1
  125. package/dist/cli/chunk-6AK4EY3D.js.map +0 -1
  126. package/dist/cli/chunk-6PZ3CXBP.js.map +0 -1
  127. package/dist/cli/chunk-H6PS7IUE.js.map +0 -1
  128. package/dist/cli/chunk-O52OLQL3.js.map +0 -1
  129. package/dist/cli/chunk-OSZC7C6F.js.map +0 -1
  130. package/dist/cli/chunk-P7EKE5ZQ.js.map +0 -1
  131. package/dist/cli/chunk-PQXPXJBJ.js.map +0 -1
  132. package/dist/cli/chunk-PV55UMTO.js +0 -200
  133. package/dist/cli/chunk-PV55UMTO.js.map +0 -1
  134. package/dist/cli/chunk-RE4RAVFF.js.map +0 -1
  135. package/dist/cli/chunk-XPDVG52A.js.map +0 -1
  136. package/dist/cli/chunk-YFGF5NKA.js.map +0 -1
  137. package/dist/cli/chunk-YQ6NTIIE.js.map +0 -1
  138. package/dist/cli/code-SMKEW6CD.js.map +0 -1
  139. package/dist/cli/desktop-Q7NDXCON.js.map +0 -1
  140. package/dist/cli/devtools-YECO25QO.js.map +0 -1
  141. package/dist/cli/doctor-OT7KH75K.js.map +0 -1
  142. package/dist/cli/mcp-inspect-REGLYBWT.js.map +0 -1
  143. package/dist/cli/prompt-UW6EFLVR.js.map +0 -1
  144. package/dist/cli/run-Q6BUXV66.js.map +0 -1
  145. package/dist/cli/server-XGDBRWMB.js.map +0 -1
  146. package/dist/cli/sessions-FH7QVYSY.js.map +0 -1
  147. package/dist/cli/stats-MQVI2XQH.js.map +0 -1
  148. /package/dist/cli/{.-3G6VX5S7.js.map → chat-TH7VNNCJ.js.map} +0 -0
  149. /package/dist/cli/{chunk-XCGGEJTI.js.map → chunk-4CTDEJUF.js.map} +0 -0
  150. /package/dist/cli/{chunk-7O5ALB4C.js.map → chunk-7CIGMZT3.js.map} +0 -0
  151. /package/dist/cli/{chunk-TJX6BFZZ.js.map → chunk-AB2RED3C.js.map} +0 -0
  152. /package/dist/cli/{chunk-FHOGSSCH.js.map → chunk-C53JQES5.js.map} +0 -0
  153. /package/dist/cli/{chunk-VK5HG73G.js.map → chunk-KM465GST.js.map} +0 -0
  154. /package/dist/cli/{chunk-DOYHN4KB.js.map → chunk-LIR2HBQH.js.map} +0 -0
  155. /package/dist/cli/{chunk-YYQAUTTN.js.map → chunk-MJ6W5UN3.js.map} +0 -0
  156. /package/dist/cli/{chunk-HFEAY5DT.js.map → chunk-R3CTO2HM.js.map} +0 -0
  157. /package/dist/cli/{chunk-32TIKD5U.js.map → chunk-TXJMRPIL.js.map} +0 -0
  158. /package/dist/cli/{chunk-F3PXYSNN.js.map → chunk-WK3UFQY3.js.map} +0 -0
  159. /package/dist/cli/{commands-FVVB5FZF.js.map → commands-OCU42XG4.js.map} +0 -0
  160. /package/dist/cli/{commit-HE4VSPZ7.js.map → commit-XCQIQCYG.js.map} +0 -0
  161. /package/dist/cli/{diff-435UTPC5.js.map → diff-NHANTNC3.js.map} +0 -0
  162. /package/dist/cli/{.-6YRPB2C7.js.map → doctor-CC5CLOGG.js.map} +0 -0
  163. /package/dist/cli/{mcp-WUL2WO75.js.map → mcp-MPVGBBJF.js.map} +0 -0
  164. /package/dist/cli/{mcp-browse-RR7R4XET.js.map → mcp-browse-4XOTC3FJ.js.map} +0 -0
  165. /package/dist/cli/{.-EYSVINK3.js.map → prompt-2D7ID24X.js.map} +0 -0
  166. /package/dist/cli/{replay-YOURXV4C.js.map → replay-SR44E6RS.js.map} +0 -0
  167. /package/dist/cli/{setup-VDS6SVEP.js.map → setup-TPAGSVXO.js.map} +0 -0
  168. /package/dist/cli/{chat-7ES4IBNH.js.map → stats-DPUBZNVX.js.map} +0 -0
  169. /package/dist/cli/{version-DAHGZY5N.js.map → version-2X3BHVVK.js.map} +0 -0
@@ -1755,15 +1755,126 @@ var require_picomatch2 = __commonJS({
1755
1755
  }
1756
1756
  });
1757
1757
 
1758
+ // src/mcp/shell-split.ts
1759
+ function shellSplit(input) {
1760
+ const tokens = [];
1761
+ let cur = "";
1762
+ let quote = null;
1763
+ let i = 0;
1764
+ const s = input;
1765
+ while (i < s.length) {
1766
+ const ch = s[i];
1767
+ if (quote) {
1768
+ if (ch === quote) {
1769
+ quote = null;
1770
+ i++;
1771
+ continue;
1772
+ }
1773
+ if (ch === "\\" && quote === '"' && i + 1 < s.length) {
1774
+ cur += s[i + 1];
1775
+ i += 2;
1776
+ continue;
1777
+ }
1778
+ cur += ch;
1779
+ i++;
1780
+ continue;
1781
+ }
1782
+ if (ch === '"' || ch === "'") {
1783
+ quote = ch;
1784
+ i++;
1785
+ continue;
1786
+ }
1787
+ if (ch === " " || ch === " ") {
1788
+ if (cur.length > 0) {
1789
+ tokens.push(cur);
1790
+ cur = "";
1791
+ }
1792
+ i++;
1793
+ continue;
1794
+ }
1795
+ cur += ch;
1796
+ i++;
1797
+ }
1798
+ if (quote) {
1799
+ throw new Error(
1800
+ `shellSplit: unterminated ${quote === '"' ? "double" : "single"} quote in input`
1801
+ );
1802
+ }
1803
+ if (cur.length > 0) tokens.push(cur);
1804
+ return tokens;
1805
+ }
1806
+
1807
+ // src/mcp/spec.ts
1808
+ function getMcpServerEnv(spec) {
1809
+ return spec.transport === "stdio" ? spec.env : void 0;
1810
+ }
1811
+ function getMcpServerHeaders(spec) {
1812
+ return spec.transport !== "stdio" ? spec.headers : void 0;
1813
+ }
1814
+ function overlayMatchedSpec(parsed, matched) {
1815
+ switch (parsed.transport) {
1816
+ case "stdio":
1817
+ return matched ? { ...parsed, disabled: matched.disabled, env: getMcpServerEnv(matched) } : { ...parsed };
1818
+ case "sse":
1819
+ return matched ? { ...parsed, disabled: matched.disabled, headers: getMcpServerHeaders(matched) } : { ...parsed };
1820
+ case "streamable-http":
1821
+ return matched ? { ...parsed, disabled: matched.disabled, headers: getMcpServerHeaders(matched) } : { ...parsed };
1822
+ }
1823
+ }
1824
+ function specToRaw(spec) {
1825
+ if (spec.transport === "stdio") {
1826
+ const args = spec.args.map((a) => {
1827
+ if (a.includes(" ") || a.includes('"') || a.includes(" ")) {
1828
+ return `"${a.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
1829
+ }
1830
+ return a;
1831
+ }).join(" ");
1832
+ const body = args ? `${spec.command} ${args}` : spec.command;
1833
+ return spec.name ? `${spec.name}=${body}` : body;
1834
+ }
1835
+ if (spec.transport === "sse") {
1836
+ return spec.name ? `${spec.name}=${spec.url}` : spec.url;
1837
+ }
1838
+ return spec.name ? `${spec.name}=streamable+${spec.url}` : `streamable+${spec.url}`;
1839
+ }
1840
+ var NAME_PREFIX = /^([a-zA-Z_][a-zA-Z0-9_-]*)=(.*)$/;
1841
+ var HTTP_URL = /^https?:\/\//i;
1842
+ var STREAMABLE_PREFIX = /^streamable\+(https?:\/\/.+)$/i;
1843
+ function parseMcpSpec(input) {
1844
+ const trimmed = input.trim();
1845
+ if (!trimmed) {
1846
+ throw new Error("empty MCP spec");
1847
+ }
1848
+ const nameMatch = NAME_PREFIX.exec(trimmed);
1849
+ const name = nameMatch ? nameMatch[1] : null;
1850
+ const body = (nameMatch ? nameMatch[2] : trimmed).trim();
1851
+ if (!body) {
1852
+ throw new Error(`MCP spec has name but no command: ${input}`);
1853
+ }
1854
+ const streamMatch = STREAMABLE_PREFIX.exec(body);
1855
+ if (streamMatch) {
1856
+ return { transport: "streamable-http", name, url: streamMatch[1] };
1857
+ }
1858
+ if (HTTP_URL.test(body)) {
1859
+ return { transport: "sse", name, url: body };
1860
+ }
1861
+ const argv = shellSplit(body);
1862
+ if (argv.length === 0) {
1863
+ throw new Error(`MCP spec has name but no command: ${input}`);
1864
+ }
1865
+ const [command, ...args] = argv;
1866
+ return { transport: "stdio", name, command, args };
1867
+ }
1868
+
1758
1869
  // src/config.ts
1759
1870
  import { chmodSync, mkdirSync, readFileSync, writeFileSync } from "fs";
1760
1871
  import { homedir } from "os";
1761
- import { dirname, join } from "path";
1872
+ import { dirname, isAbsolute, join, resolve } from "path";
1762
1873
 
1763
1874
  // src/cli/ui/theme/tokens.ts
1764
1875
  function card(fg, tone) {
1765
1876
  return {
1766
- user: { color: fg.meta, glyph: "\u25C7" },
1877
+ user: { color: tone.brand, glyph: "\u25C7" },
1767
1878
  reasoning: { color: tone.accent, glyph: "\u25C6" },
1768
1879
  streaming: { color: tone.brand, glyph: "\u25C8" },
1769
1880
  task: { color: tone.warn, glyph: "\u25B6" },
@@ -2216,6 +2327,13 @@ function memoryTypeDefaults(typeName, cfg = readConfig()) {
2216
2327
  if (found.expires) out.expires = found.expires;
2217
2328
  return out;
2218
2329
  }
2330
+ var DEFAULT_METASO_API_KEY = "mk-E384C1DD5E8501BB7EFE27C949AFDE5B";
2331
+ function loadMetasoApiKey(path = defaultConfigPath()) {
2332
+ if (process.env.METASO_API_KEY) return process.env.METASO_API_KEY;
2333
+ const cfg = readConfig(path).metasoApiKey;
2334
+ if (cfg && typeof cfg === "string" && cfg.trim()) return cfg.trim();
2335
+ return DEFAULT_METASO_API_KEY;
2336
+ }
2219
2337
  var DEFAULT_OLLAMA_URL = "http://localhost:11434";
2220
2338
  var DEFAULT_EMBED_MODEL = "nomic-embed-text";
2221
2339
  var DEFAULT_TIMEOUT_MS = 3e4;
@@ -2242,15 +2360,103 @@ function writeConfig(cfg, path = defaultConfigPath()) {
2242
2360
  function loadLanguage(path = defaultConfigPath()) {
2243
2361
  return readConfig(path).lang;
2244
2362
  }
2245
- function mcpEnvFor(serverName, cfg) {
2246
- if (!serverName) return void 0;
2247
- const entry = cfg.mcpEnv?.[serverName];
2248
- if (!entry) return void 0;
2249
- const filtered = {};
2250
- for (const [k, v] of Object.entries(entry)) {
2251
- if (typeof v === "string" && v.length > 0) filtered[k] = v;
2363
+ function inferMcpTransport(cfg) {
2364
+ if (cfg.transport) return cfg.transport;
2365
+ const url = cfg.url?.trim() ?? "";
2366
+ if (/^streamable\+https?:\/\//i.test(url)) return "streamable-http";
2367
+ if (/^https?:\/\//i.test(url)) return "sse";
2368
+ return "stdio";
2369
+ }
2370
+ function normalizeStringRecord(value) {
2371
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
2372
+ const out = {};
2373
+ for (const [k, v] of Object.entries(value)) {
2374
+ if (typeof v === "string" && v.length > 0) out[k] = v;
2375
+ }
2376
+ return Object.keys(out).length > 0 ? out : void 0;
2377
+ }
2378
+ function normalizeMcpConfig(cfg, extraLegacy) {
2379
+ const result = [];
2380
+ const seen = /* @__PURE__ */ new Set();
2381
+ const disabledFromLegacy = new Set(cfg.mcpDisabled ?? []);
2382
+ const legacySpecs = extraLegacy && extraLegacy.length > 0 ? extraLegacy : cfg.mcp ?? [];
2383
+ for (const raw of legacySpecs) {
2384
+ if (typeof raw !== "string") continue;
2385
+ try {
2386
+ const spec = parseMcpSpec(raw);
2387
+ const env = spec.name ? normalizeStringRecord(cfg.mcpEnv?.[spec.name]) : void 0;
2388
+ const disabled = spec.name ? disabledFromLegacy.has(spec.name) : false;
2389
+ if (spec.transport === "stdio") {
2390
+ result.push({ ...spec, env, disabled });
2391
+ } else if (spec.transport === "sse") {
2392
+ result.push({ ...spec, disabled });
2393
+ } else {
2394
+ result.push({ ...spec, disabled });
2395
+ }
2396
+ if (spec.name) seen.add(spec.name);
2397
+ } catch {
2398
+ }
2252
2399
  }
2253
- return Object.keys(filtered).length > 0 ? filtered : void 0;
2400
+ for (const [name, serverCfg] of Object.entries(cfg.mcpServers ?? {})) {
2401
+ if (!serverCfg || typeof serverCfg !== "object") continue;
2402
+ const transport = inferMcpTransport(serverCfg);
2403
+ const disabled = serverCfg.disabled === true;
2404
+ if (transport === "stdio") {
2405
+ const env = normalizeStringRecord(serverCfg.env);
2406
+ const spec = {
2407
+ transport: "stdio",
2408
+ name,
2409
+ command: serverCfg.command ?? "",
2410
+ args: serverCfg.args ?? [],
2411
+ env,
2412
+ disabled
2413
+ };
2414
+ if (seen.has(name)) {
2415
+ const idx = result.findIndex((s) => s.name === name);
2416
+ if (idx >= 0) result[idx] = spec;
2417
+ } else {
2418
+ seen.add(name);
2419
+ result.push(spec);
2420
+ }
2421
+ } else {
2422
+ let url = serverCfg.url ?? "";
2423
+ const streamMatch = /^streamable\+(https?:\/\/.+)$/i.exec(url);
2424
+ if (streamMatch) url = streamMatch[1];
2425
+ const headers = normalizeStringRecord(serverCfg.headers);
2426
+ if (transport === "sse") {
2427
+ const spec = {
2428
+ transport: "sse",
2429
+ name,
2430
+ url,
2431
+ headers,
2432
+ disabled
2433
+ };
2434
+ if (seen.has(name)) {
2435
+ const idx = result.findIndex((s) => s.name === name);
2436
+ if (idx >= 0) result[idx] = spec;
2437
+ } else {
2438
+ seen.add(name);
2439
+ result.push(spec);
2440
+ }
2441
+ } else {
2442
+ const spec = {
2443
+ transport: "streamable-http",
2444
+ name,
2445
+ url,
2446
+ headers,
2447
+ disabled
2448
+ };
2449
+ if (seen.has(name)) {
2450
+ const idx = result.findIndex((s) => s.name === name);
2451
+ if (idx >= 0) result[idx] = spec;
2452
+ } else {
2453
+ seen.add(name);
2454
+ result.push(spec);
2455
+ }
2456
+ }
2457
+ }
2458
+ }
2459
+ return result;
2254
2460
  }
2255
2461
  function saveLanguage(lang, path = defaultConfigPath()) {
2256
2462
  const cfg = readConfig(path);
@@ -2275,6 +2481,93 @@ function saveBaseUrl(url, path = defaultConfigPath()) {
2275
2481
  }
2276
2482
  writeConfig(cfg, path);
2277
2483
  }
2484
+ function resolveSkillPath(raw, baseDir) {
2485
+ const homeExpanded = expandCurrentUserHome(raw.trim());
2486
+ return resolve(isAbsolute(homeExpanded) ? homeExpanded : join(baseDir, homeExpanded));
2487
+ }
2488
+ function normalizeSkillPathEntries(paths, baseDir) {
2489
+ const out = [];
2490
+ const seen = /* @__PURE__ */ new Set();
2491
+ for (const value of paths) {
2492
+ if (typeof value !== "string") continue;
2493
+ const raw = value.trim();
2494
+ if (!raw) continue;
2495
+ const resolved = resolveSkillPath(raw, baseDir);
2496
+ const key = skillPathKey(resolved);
2497
+ if (seen.has(key)) continue;
2498
+ seen.add(key);
2499
+ out.push({ raw, resolved });
2500
+ }
2501
+ return out;
2502
+ }
2503
+ function normalizeSkillPaths(paths, baseDir) {
2504
+ return normalizeSkillPathEntries(paths, baseDir).map((entry) => entry.raw);
2505
+ }
2506
+ function resolveSkillPaths(paths, baseDir) {
2507
+ return normalizeSkillPathEntries(paths, baseDir).map((entry) => entry.resolved);
2508
+ }
2509
+ function skillPathKey(path) {
2510
+ return process.platform === "win32" ? path.toLowerCase() : path;
2511
+ }
2512
+ function expandCurrentUserHome(path) {
2513
+ if (path === "~") return homedir();
2514
+ if (path.startsWith("~/") || path.startsWith("~\\")) return join(homedir(), path.slice(2));
2515
+ return path;
2516
+ }
2517
+ function loadSkillPaths(baseDir = process.cwd(), path = defaultConfigPath()) {
2518
+ const raw = readConfig(path).skills?.paths;
2519
+ return Array.isArray(raw) ? normalizeSkillPaths(raw, baseDir) : [];
2520
+ }
2521
+ function loadResolvedSkillPaths(baseDir = process.cwd(), path = defaultConfigPath()) {
2522
+ const raw = readConfig(path).skills?.paths;
2523
+ return Array.isArray(raw) ? resolveSkillPaths(raw, baseDir) : [];
2524
+ }
2525
+ function saveSkillPaths(paths, baseDir = process.cwd(), path = defaultConfigPath()) {
2526
+ const cfg = readConfig(path);
2527
+ const normalized = normalizeSkillPaths(paths, baseDir);
2528
+ cfg.skills = { ...cfg.skills ?? {}, paths: normalized };
2529
+ writeConfig(cfg, path);
2530
+ return normalized;
2531
+ }
2532
+ function addSkillPath(skillPath, baseDir = process.cwd(), path = defaultConfigPath()) {
2533
+ const entry = normalizeSkillPathEntries([skillPath], baseDir)[0];
2534
+ if (!entry) return { error: "skill path is empty" };
2535
+ const existing = loadSkillPaths(baseDir, path);
2536
+ const seen = new Set(resolveSkillPaths(existing, baseDir).map(skillPathKey));
2537
+ const key = skillPathKey(entry.resolved);
2538
+ if (seen.has(key))
2539
+ return { added: false, path: entry.raw, resolved: entry.resolved, paths: existing };
2540
+ const paths = saveSkillPaths([...existing, entry.raw], baseDir, path);
2541
+ return { added: true, path: entry.raw, resolved: entry.resolved, paths };
2542
+ }
2543
+ function removeSkillPath(target, baseDir = process.cwd(), path = defaultConfigPath()) {
2544
+ const existing = loadSkillPaths(baseDir, path);
2545
+ const trimmed = target.trim();
2546
+ if (!trimmed) return { removed: false, paths: existing };
2547
+ const existingEntries = normalizeSkillPathEntries(existing, baseDir);
2548
+ const idx = /^\d+$/.test(trimmed) ? Number.parseInt(trimmed, 10) - 1 : -1;
2549
+ let removeAt = idx >= 0 && idx < existing.length ? idx : -1;
2550
+ if (removeAt < 0) {
2551
+ const targetEntry = normalizeSkillPathEntries([trimmed], baseDir)[0];
2552
+ const targetKey = targetEntry ? skillPathKey(targetEntry.resolved) : void 0;
2553
+ removeAt = existingEntries.findIndex(
2554
+ (entry) => entry.raw === trimmed || targetKey !== void 0 && skillPathKey(entry.resolved) === targetKey
2555
+ );
2556
+ }
2557
+ if (removeAt < 0) return { removed: false, paths: existing };
2558
+ const removed = existingEntries[removeAt];
2559
+ const paths = saveSkillPaths(
2560
+ existing.filter((_, i) => i !== removeAt),
2561
+ baseDir,
2562
+ path
2563
+ );
2564
+ return {
2565
+ removed: true,
2566
+ path: removed?.raw ?? existing[removeAt],
2567
+ resolved: removed?.resolved,
2568
+ paths
2569
+ };
2570
+ }
2278
2571
  function searchEnabled(path = defaultConfigPath()) {
2279
2572
  const env = process.env.REASONIX_SEARCH;
2280
2573
  if (env === "off" || env === "false" || env === "0") return false;
@@ -2285,6 +2578,7 @@ function searchEnabled(path = defaultConfigPath()) {
2285
2578
  function webSearchEngine(path = defaultConfigPath()) {
2286
2579
  const cfg = readConfig(path).webSearchEngine;
2287
2580
  if (cfg === "searxng") return "searxng";
2581
+ if (cfg === "metaso") return "metaso";
2288
2582
  return "mojeek";
2289
2583
  }
2290
2584
  function webSearchEndpoint(path = defaultConfigPath()) {
@@ -2447,6 +2741,20 @@ function pushRecentWorkspace(dir, path = defaultConfigPath()) {
2447
2741
  cfg.recentWorkspaces = list.slice(0, MAX_RECENT_WORKSPACES);
2448
2742
  writeConfig(cfg, path);
2449
2743
  }
2744
+ function loadDesktopOpenTabs(path = defaultConfigPath()) {
2745
+ const v = readConfig(path).desktopOpenTabs;
2746
+ return Array.isArray(v) ? v.filter((s) => typeof s === "string" && s.length > 0) : [];
2747
+ }
2748
+ function saveDesktopOpenTabs(dirs, path = defaultConfigPath()) {
2749
+ const cfg = readConfig(path);
2750
+ const cleaned = dirs.filter((s) => typeof s === "string" && s.length > 0);
2751
+ if (cleaned.length === 0) {
2752
+ cfg.desktopOpenTabs = void 0;
2753
+ } else {
2754
+ cfg.desktopOpenTabs = cleaned;
2755
+ }
2756
+ writeConfig(cfg, path);
2757
+ }
2450
2758
  function loadPreset(path = defaultConfigPath()) {
2451
2759
  return readConfig(path).preset;
2452
2760
  }
@@ -2573,6 +2881,31 @@ function isPlainObject(value) {
2573
2881
  const proto = Object.getPrototypeOf(value);
2574
2882
  return proto === Object.prototype || proto === null;
2575
2883
  }
2884
+ function loadQQConfig(path = defaultConfigPath()) {
2885
+ const envSandbox = process.env.QQ_SANDBOX;
2886
+ const fromEnv = {
2887
+ appId: process.env.QQ_APPID,
2888
+ appSecret: process.env.QQ_SECRET,
2889
+ sandbox: envSandbox === "1" ? true : envSandbox === "0" ? false : void 0
2890
+ };
2891
+ const fromCfg = readConfig(path).qq ?? {};
2892
+ return {
2893
+ appId: fromEnv.appId ?? fromCfg.appId,
2894
+ appSecret: fromEnv.appSecret ?? fromCfg.appSecret,
2895
+ sandbox: fromEnv.sandbox ?? fromCfg.sandbox ?? false,
2896
+ enabled: fromCfg.enabled === true
2897
+ };
2898
+ }
2899
+ function saveQQConfig(cfg, path = defaultConfigPath()) {
2900
+ const rootCfg = readConfig(path);
2901
+ rootCfg.qq = {
2902
+ appId: cfg.appId,
2903
+ appSecret: cfg.appSecret,
2904
+ sandbox: cfg.sandbox,
2905
+ enabled: cfg.enabled
2906
+ };
2907
+ writeConfig(rootCfg, path);
2908
+ }
2576
2909
 
2577
2910
  export {
2578
2911
  THEMES,
@@ -2596,17 +2929,28 @@ export {
2596
2929
  defaultIndexConfig,
2597
2930
  resolveIndexConfig,
2598
2931
  compileFilters,
2932
+ overlayMatchedSpec,
2933
+ specToRaw,
2934
+ parseMcpSpec,
2599
2935
  loadMemoryTypeRegistry,
2600
2936
  memoryTypeDefaults,
2937
+ loadMetasoApiKey,
2601
2938
  defaultConfigPath,
2602
2939
  readConfig,
2603
2940
  writeConfig,
2604
2941
  loadLanguage,
2605
- mcpEnvFor,
2942
+ normalizeMcpConfig,
2606
2943
  saveLanguage,
2607
2944
  loadApiKey,
2608
2945
  loadBaseUrl,
2609
2946
  saveBaseUrl,
2947
+ normalizeSkillPathEntries,
2948
+ normalizeSkillPaths,
2949
+ resolveSkillPaths,
2950
+ loadSkillPaths,
2951
+ loadResolvedSkillPaths,
2952
+ addSkillPath,
2953
+ removeSkillPath,
2610
2954
  searchEnabled,
2611
2955
  webSearchEngine,
2612
2956
  webSearchEndpoint,
@@ -2632,6 +2976,8 @@ export {
2632
2976
  saveEditor,
2633
2977
  loadRecentWorkspaces,
2634
2978
  pushRecentWorkspace,
2979
+ loadDesktopOpenTabs,
2980
+ saveDesktopOpenTabs,
2635
2981
  loadPreset,
2636
2982
  savePreset,
2637
2983
  loadIndexUserConfig,
@@ -2643,6 +2989,8 @@ export {
2643
2989
  markEditModeHintShown,
2644
2990
  markMouseClipboardHintShown,
2645
2991
  isPlausibleKey,
2646
- redactKey
2992
+ redactKey,
2993
+ loadQQConfig,
2994
+ saveQQConfig
2647
2995
  };
2648
- //# sourceMappingURL=chunk-XPDVG52A.js.map
2996
+ //# sourceMappingURL=chunk-AVFXO2EZ.js.map