reasonix 0.41.0 → 0.43.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 (186) hide show
  1. package/README.md +26 -3
  2. package/dashboard/dist/app.js +98 -3
  3. package/dashboard/dist/app.js.map +1 -1
  4. package/dist/cli/{acp-64VQZLDJ.js → acp-DAGPCVFZ.js} +33 -28
  5. package/dist/cli/acp-DAGPCVFZ.js.map +1 -0
  6. package/dist/cli/chat-7ES4IBNH.js +50 -0
  7. package/dist/cli/{chunk-E46ECXJD.js → chunk-2425HK6U.js} +2 -1
  8. package/dist/cli/{chunk-E46ECXJD.js.map → chunk-2425HK6U.js.map} +1 -1
  9. package/dist/cli/chunk-25T6CVUP.js +172 -0
  10. package/dist/cli/chunk-25T6CVUP.js.map +1 -0
  11. package/dist/cli/{chunk-CD4SCQL4.js → chunk-2K65GZBT.js} +11 -2
  12. package/dist/cli/chunk-2K65GZBT.js.map +1 -0
  13. package/dist/cli/{chunk-H4OLWRSX.js → chunk-2KDUS647.js} +5 -4
  14. package/dist/cli/chunk-2KDUS647.js.map +1 -0
  15. package/dist/cli/chunk-2R4QCDOZ.js +11392 -0
  16. package/dist/cli/chunk-2R4QCDOZ.js.map +1 -0
  17. package/dist/cli/{chunk-3Q3C4W66.js → chunk-2UQP6H6T.js} +2 -1
  18. package/dist/cli/{chunk-3Q3C4W66.js.map → chunk-2UQP6H6T.js.map} +1 -1
  19. package/dist/cli/chunk-2Z35JOA4.js +96 -0
  20. package/dist/cli/chunk-2Z35JOA4.js.map +1 -0
  21. package/dist/cli/chunk-32TIKD5U.js +54 -0
  22. package/dist/cli/{chunk-L7W3HJZQ.js.map → chunk-32TIKD5U.js.map} +1 -1
  23. package/dist/cli/{chunk-A3LL4XDV.js → chunk-3BXRZFWS.js} +59 -3
  24. package/dist/cli/chunk-3BXRZFWS.js.map +1 -0
  25. package/dist/cli/{chunk-SXLJBFIV.js → chunk-3Z6IBU3D.js} +11 -7
  26. package/dist/cli/chunk-3Z6IBU3D.js.map +1 -0
  27. package/dist/cli/{chunk-A7VHMMDE.js → chunk-45U62RI3.js} +12 -5
  28. package/dist/cli/chunk-45U62RI3.js.map +1 -0
  29. package/dist/cli/{chunk-7VFNPMKG.js → chunk-4QUNBQQ2.js} +3 -2
  30. package/dist/cli/{chunk-7VFNPMKG.js.map → chunk-4QUNBQQ2.js.map} +1 -1
  31. package/dist/cli/{chunk-ARF3N2SY.js → chunk-5JJRUIPA.js} +4 -3
  32. package/dist/cli/{chunk-ARF3N2SY.js.map → chunk-5JJRUIPA.js.map} +1 -1
  33. package/dist/cli/{chunk-CFY2XLY6.js → chunk-6AK4EY3D.js} +7 -5
  34. package/dist/cli/{chunk-CFY2XLY6.js.map → chunk-6AK4EY3D.js.map} +1 -1
  35. package/dist/cli/chunk-6G3CUUFG.js +34320 -0
  36. package/dist/cli/chunk-6G3CUUFG.js.map +1 -0
  37. package/dist/cli/{chunk-YJFKFTAL.js → chunk-6PBZN4VI.js} +15 -3
  38. package/dist/cli/chunk-6PBZN4VI.js.map +1 -0
  39. package/dist/cli/{chunk-4W2CICFQ.js → chunk-6PZ3CXBP.js} +71 -60
  40. package/dist/cli/chunk-6PZ3CXBP.js.map +1 -0
  41. package/dist/cli/chunk-74EX7SUH.js +25293 -0
  42. package/dist/cli/chunk-74EX7SUH.js.map +1 -0
  43. package/dist/cli/{chunk-WE3YZULK.js → chunk-7O5ALB4C.js} +3 -2
  44. package/dist/cli/{chunk-WE3YZULK.js.map → chunk-7O5ALB4C.js.map} +1 -1
  45. package/dist/cli/{chunk-2CXPDAWX.js → chunk-DOYHN4KB.js} +3 -2
  46. package/dist/cli/{chunk-2CXPDAWX.js.map → chunk-DOYHN4KB.js.map} +1 -1
  47. package/dist/cli/{chunk-VFG4GIT3.js → chunk-F3PXYSNN.js} +3 -2
  48. package/dist/cli/{chunk-VFG4GIT3.js.map → chunk-F3PXYSNN.js.map} +1 -1
  49. package/dist/cli/{chunk-7SPOFTMT.js → chunk-FHOGSSCH.js} +4 -3
  50. package/dist/cli/{chunk-7SPOFTMT.js.map → chunk-FHOGSSCH.js.map} +1 -1
  51. package/dist/cli/{chunk-LTXADNCO.js → chunk-H6PS7IUE.js} +3 -2
  52. package/dist/cli/{chunk-LTXADNCO.js.map → chunk-H6PS7IUE.js.map} +1 -1
  53. package/dist/cli/{chunk-ZTLZO42A.js → chunk-HFEAY5DT.js} +3 -2
  54. package/dist/cli/{chunk-ZTLZO42A.js.map → chunk-HFEAY5DT.js.map} +1 -1
  55. package/dist/cli/{chunk-FWGEHRB7.js → chunk-J5XJHLWM.js} +2 -1
  56. package/dist/cli/{chunk-FWGEHRB7.js.map → chunk-J5XJHLWM.js.map} +1 -1
  57. package/dist/cli/{chunk-Y5XNV3NX.js → chunk-JMBMLOBP.js} +2 -1
  58. package/dist/cli/{chunk-Y5XNV3NX.js.map → chunk-JMBMLOBP.js.map} +1 -1
  59. package/dist/cli/{chunk-BYZGO3BX.js → chunk-O52OLQL3.js} +11 -3
  60. package/dist/cli/chunk-O52OLQL3.js.map +1 -0
  61. package/dist/cli/{chunk-4DCHFFEY.js → chunk-OSZC7C6F.js} +3 -2
  62. package/dist/cli/{chunk-4DCHFFEY.js.map → chunk-OSZC7C6F.js.map} +1 -1
  63. package/dist/cli/chunk-P7EKE5ZQ.js +60641 -0
  64. package/dist/cli/chunk-P7EKE5ZQ.js.map +1 -0
  65. package/dist/cli/{chunk-FM57FNPJ.js → chunk-PLHAZOLZ.js} +2 -1
  66. package/dist/cli/{chunk-FM57FNPJ.js.map → chunk-PLHAZOLZ.js.map} +1 -1
  67. package/dist/cli/{chunk-BOFL3T45.js → chunk-PQXPXJBJ.js} +12 -11
  68. package/dist/cli/chunk-PQXPXJBJ.js.map +1 -0
  69. package/dist/cli/{chunk-DAEAAVDF.js → chunk-PV55UMTO.js} +2 -1
  70. package/dist/cli/{chunk-DAEAAVDF.js.map → chunk-PV55UMTO.js.map} +1 -1
  71. package/dist/cli/{chunk-MHGPBJ2T.js → chunk-RE4RAVFF.js} +45 -10
  72. package/dist/cli/chunk-RE4RAVFF.js.map +1 -0
  73. package/dist/cli/chunk-S4XVGLRW.js +499 -0
  74. package/dist/cli/chunk-S4XVGLRW.js.map +1 -0
  75. package/dist/cli/{chunk-WJ3YX4PZ.js → chunk-SZ5XES2N.js} +3 -2
  76. package/dist/cli/{chunk-WJ3YX4PZ.js.map → chunk-SZ5XES2N.js.map} +1 -1
  77. package/dist/cli/{chunk-UV7XJUJH.js → chunk-TJX6BFZZ.js} +16 -9
  78. package/dist/cli/{chunk-UV7XJUJH.js.map → chunk-TJX6BFZZ.js.map} +1 -1
  79. package/dist/cli/chunk-TUK7OWJA.js +51 -0
  80. package/dist/cli/{chunk-KZYLMMU5.js → chunk-VK5HG73G.js} +13 -12
  81. package/dist/cli/{chunk-KZYLMMU5.js.map → chunk-VK5HG73G.js.map} +1 -1
  82. package/dist/cli/{chunk-4H3ZRJ2U.js → chunk-XCGGEJTI.js} +4 -3
  83. package/dist/cli/{chunk-4H3ZRJ2U.js.map → chunk-XCGGEJTI.js.map} +1 -1
  84. package/dist/cli/{chunk-SOZE7V7V.js → chunk-XJXDHAES.js} +3 -2
  85. package/dist/cli/{chunk-SOZE7V7V.js.map → chunk-XJXDHAES.js.map} +1 -1
  86. package/dist/cli/chunk-XPDVG52A.js +2648 -0
  87. package/dist/cli/chunk-XPDVG52A.js.map +1 -0
  88. package/dist/cli/{chunk-CRPQUBP6.js → chunk-XXC2BYTV.js} +2 -1
  89. package/dist/cli/{chunk-CRPQUBP6.js.map → chunk-XXC2BYTV.js.map} +1 -1
  90. package/dist/cli/{chunk-AT6GGIBV.js → chunk-YFGF5NKA.js} +17 -14
  91. package/dist/cli/{chunk-AT6GGIBV.js.map → chunk-YFGF5NKA.js.map} +1 -1
  92. package/dist/cli/{chunk-ORM6PK57.js → chunk-YQ6NTIIE.js} +2 -1
  93. package/dist/cli/{chunk-ORM6PK57.js.map → chunk-YQ6NTIIE.js.map} +1 -1
  94. package/dist/cli/{chunk-RAUPWSYA.js → chunk-YYQAUTTN.js} +3 -2
  95. package/dist/cli/{chunk-RAUPWSYA.js.map → chunk-YYQAUTTN.js.map} +1 -1
  96. package/dist/cli/chunk-ZZM6QJ4W.js +109 -0
  97. package/dist/cli/chunk-ZZM6QJ4W.js.map +1 -0
  98. package/dist/cli/{code-X3M6ENTQ.js → code-SMKEW6CD.js} +60 -56
  99. package/dist/cli/code-SMKEW6CD.js.map +1 -0
  100. package/dist/cli/{commands-QY7MSQG7.js → commands-FVVB5FZF.js} +7 -5
  101. package/dist/cli/{commands-QY7MSQG7.js.map → commands-FVVB5FZF.js.map} +1 -1
  102. package/dist/cli/{commit-BRCQ3OQO.js → commit-HE4VSPZ7.js} +7 -4
  103. package/dist/cli/{commit-BRCQ3OQO.js.map → commit-HE4VSPZ7.js.map} +1 -1
  104. package/dist/cli/{desktop-ZTMHQR2Y.js → desktop-Q7NDXCON.js} +162 -74
  105. package/dist/cli/desktop-Q7NDXCON.js.map +1 -0
  106. package/dist/cli/devtools-YECO25QO.js +3719 -0
  107. package/dist/cli/devtools-YECO25QO.js.map +1 -0
  108. package/dist/cli/diff-435UTPC5.js +165 -0
  109. package/dist/cli/{diff-YASCB7PU.js.map → diff-435UTPC5.js.map} +1 -1
  110. package/dist/cli/doctor-OT7KH75K.js +27 -0
  111. package/dist/cli/{events-2AJTXR7I.js → events-XEFAD5VX.js} +6 -4
  112. package/dist/cli/{events-2AJTXR7I.js.map → events-XEFAD5VX.js.map} +1 -1
  113. package/dist/cli/index.js +3209 -133
  114. package/dist/cli/index.js.map +1 -1
  115. package/dist/cli/{mcp-YMWBLRR7.js → mcp-WUL2WO75.js} +6 -4
  116. package/dist/cli/{mcp-YMWBLRR7.js.map → mcp-WUL2WO75.js.map} +1 -1
  117. package/dist/cli/{mcp-browse-XLDUE6SB.js → mcp-browse-RR7R4XET.js} +32 -21
  118. package/dist/cli/{mcp-browse-XLDUE6SB.js.map → mcp-browse-RR7R4XET.js.map} +1 -1
  119. package/dist/cli/{mcp-inspect-H4D2HSJP.js → mcp-inspect-REGLYBWT.js} +8 -5
  120. package/dist/cli/{mcp-inspect-H4D2HSJP.js.map → mcp-inspect-REGLYBWT.js.map} +1 -1
  121. package/dist/cli/package.json +3 -0
  122. package/dist/cli/prompt-UW6EFLVR.js +16 -0
  123. package/dist/cli/{prune-sessions-4N3BVST2.js → prune-sessions-3RWUBYRS.js} +4 -2
  124. package/dist/cli/{prune-sessions-4N3BVST2.js.map → prune-sessions-3RWUBYRS.js.map} +1 -1
  125. package/dist/cli/{replay-3GTWM75X.js → replay-YOURXV4C.js} +42 -30
  126. package/dist/cli/{replay-3GTWM75X.js.map → replay-YOURXV4C.js.map} +1 -1
  127. package/dist/cli/{run-BLZPTRDX.js → run-Q6BUXV66.js} +24 -21
  128. package/dist/cli/{run-BLZPTRDX.js.map → run-Q6BUXV66.js.map} +1 -1
  129. package/dist/cli/{server-DRFPXXSH.js → server-XGDBRWMB.js} +40 -43
  130. package/dist/cli/server-XGDBRWMB.js.map +1 -0
  131. package/dist/cli/{sessions-BOWFPTXT.js → sessions-FH7QVYSY.js} +22 -19
  132. package/dist/cli/{sessions-BOWFPTXT.js.map → sessions-FH7QVYSY.js.map} +1 -1
  133. package/dist/cli/setup-VDS6SVEP.js +618 -0
  134. package/dist/cli/setup-VDS6SVEP.js.map +1 -0
  135. package/dist/cli/stats-MQVI2XQH.js +14 -0
  136. package/dist/cli/update-6ITLPRDV.js +15 -0
  137. package/dist/cli/update-6ITLPRDV.js.map +1 -0
  138. package/dist/cli/version-DAHGZY5N.js +33 -0
  139. package/dist/cli/{version-XQXYSJ5L.js.map → version-DAHGZY5N.js.map} +1 -1
  140. package/dist/index.d.ts +12 -3
  141. package/dist/index.js +182 -97
  142. package/dist/index.js.map +1 -1
  143. package/package.json +1 -1
  144. package/dist/cli/acp-64VQZLDJ.js.map +0 -1
  145. package/dist/cli/chat-ZAGX52RV.js +0 -46
  146. package/dist/cli/chunk-4W2CICFQ.js.map +0 -1
  147. package/dist/cli/chunk-5X7LZJDE.js +0 -36
  148. package/dist/cli/chunk-5X7LZJDE.js.map +0 -1
  149. package/dist/cli/chunk-65Q5HQ26.js +0 -892
  150. package/dist/cli/chunk-65Q5HQ26.js.map +0 -1
  151. package/dist/cli/chunk-A3LL4XDV.js.map +0 -1
  152. package/dist/cli/chunk-A7VHMMDE.js.map +0 -1
  153. package/dist/cli/chunk-AFFZF3MW.js +0 -36
  154. package/dist/cli/chunk-AFFZF3MW.js.map +0 -1
  155. package/dist/cli/chunk-BOFL3T45.js.map +0 -1
  156. package/dist/cli/chunk-BYZGO3BX.js.map +0 -1
  157. package/dist/cli/chunk-CD4SCQL4.js.map +0 -1
  158. package/dist/cli/chunk-CPOV2O73.js +0 -39
  159. package/dist/cli/chunk-CPOV2O73.js.map +0 -1
  160. package/dist/cli/chunk-F2AV2QDK.js +0 -16514
  161. package/dist/cli/chunk-F2AV2QDK.js.map +0 -1
  162. package/dist/cli/chunk-H4OLWRSX.js.map +0 -1
  163. package/dist/cli/chunk-IEA6JOIP.js +0 -5430
  164. package/dist/cli/chunk-IEA6JOIP.js.map +0 -1
  165. package/dist/cli/chunk-L7W3HJZQ.js +0 -46
  166. package/dist/cli/chunk-LN27AKV3.js +0 -26
  167. package/dist/cli/chunk-LN27AKV3.js.map +0 -1
  168. package/dist/cli/chunk-MHGPBJ2T.js.map +0 -1
  169. package/dist/cli/chunk-SXLJBFIV.js.map +0 -1
  170. package/dist/cli/chunk-YJFKFTAL.js.map +0 -1
  171. package/dist/cli/code-X3M6ENTQ.js.map +0 -1
  172. package/dist/cli/desktop-ZTMHQR2Y.js.map +0 -1
  173. package/dist/cli/diff-YASCB7PU.js +0 -153
  174. package/dist/cli/doctor-XCN5ETVP.js +0 -24
  175. package/dist/cli/prompt-RSIHN62V.js +0 -14
  176. package/dist/cli/server-DRFPXXSH.js.map +0 -1
  177. package/dist/cli/setup-FQL2JJC2.js +0 -516
  178. package/dist/cli/setup-FQL2JJC2.js.map +0 -1
  179. package/dist/cli/stats-5RJCATCE.js +0 -12
  180. package/dist/cli/update-GUCWB4UN.js +0 -13
  181. package/dist/cli/version-XQXYSJ5L.js +0 -30
  182. /package/dist/cli/{chat-ZAGX52RV.js.map → chat-7ES4IBNH.js.map} +0 -0
  183. /package/dist/cli/{doctor-XCN5ETVP.js.map → chunk-TUK7OWJA.js.map} +0 -0
  184. /package/dist/cli/{prompt-RSIHN62V.js.map → doctor-OT7KH75K.js.map} +0 -0
  185. /package/dist/cli/{stats-5RJCATCE.js.map → prompt-UW6EFLVR.js.map} +0 -0
  186. /package/dist/cli/{update-GUCWB4UN.js.map → stats-MQVI2XQH.js.map} +0 -0
@@ -1,20 +1,22 @@
1
1
  #!/usr/bin/env node
2
+ import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
2
3
  import {
3
4
  fetchSmitheryDetail,
4
5
  handleToFetchResult,
5
6
  loadMorePages,
6
7
  openRegistry,
7
8
  specStringFor
8
- } from "./chunk-SOZE7V7V.js";
9
+ } from "./chunk-XJXDHAES.js";
9
10
  import {
10
11
  MCP_CATALOG,
11
12
  mcpCommandFor
12
- } from "./chunk-FM57FNPJ.js";
13
+ } from "./chunk-PLHAZOLZ.js";
13
14
  import {
14
15
  defaultConfigPath,
15
16
  readConfig,
16
17
  writeConfig
17
- } from "./chunk-65Q5HQ26.js";
18
+ } from "./chunk-XPDVG52A.js";
19
+ import "./chunk-TUK7OWJA.js";
18
20
 
19
21
  // src/cli/commands/mcp.ts
20
22
  var DEFAULT_LIST_LIMIT = 30;
@@ -272,4 +274,4 @@ export {
272
274
  mcpListCommand,
273
275
  mcpSearchCommand
274
276
  };
275
- //# sourceMappingURL=mcp-YMWBLRR7.js.map
277
+ //# sourceMappingURL=mcp-WUL2WO75.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/commands/mcp.ts"],"sourcesContent":["import { defaultConfigPath, readConfig, writeConfig } from \"../../config.js\";\nimport { MCP_CATALOG, mcpCommandFor } from \"../../mcp/catalog.js\";\nimport {\n type FetchProgress,\n fetchSmitheryDetail,\n handleToFetchResult,\n loadMorePages,\n openRegistry,\n specStringFor,\n} from \"../../mcp/registry-fetch.js\";\nimport type { RegistryEntry } from \"../../mcp/registry-types.js\";\n\nconst DEFAULT_LIST_LIMIT = 30;\n/** Soft cap on how far `search` walks the registry on first run. */\nconst SEARCH_PAGE_CAP = 20;\n/** Soft cap on how far `install` walks looking for a name. */\nconst INSTALL_PAGE_CAP = 30;\n\nconst progressToStderr: FetchProgress = ({ source, page, entries }) => {\n if (page === 1 || page % 5 === 0) {\n process.stderr.write(`\\r▸ fetching ${source} registry · page ${page} · ${entries} entries`);\n }\n};\n\nfunction finishProgressLine(): void {\n if (process.stderr.isTTY) process.stderr.write(\"\\r\\x1b[K\");\n else process.stderr.write(\"\\n\");\n}\n\nexport interface McpListOptions {\n json?: boolean;\n /** Skip network — only show the bundled MCP_CATALOG entries. */\n local?: boolean;\n /** Bypass cache TTL. */\n refresh?: boolean;\n /** How many entries to show. Default 30. */\n limit?: number;\n /** Eagerly load this many pages before showing. Default 1. */\n pages?: number;\n /** Walk all pages of the registry (slow on first run). */\n all?: boolean;\n}\n\nexport interface McpSearchOptions {\n json?: boolean;\n refresh?: boolean;\n limit?: number;\n /** Cap how many pages to walk while searching. Default 20. */\n maxPages?: number;\n}\n\nexport interface McpInstallOptions {\n refresh?: boolean;\n /** Cap how many pages to walk while looking for the name. Default 30. */\n maxPages?: number;\n}\n\nfunction rankEntries(entries: RegistryEntry[]): RegistryEntry[] {\n return [...entries].sort((a, b) => {\n const ap = a.popularity ?? -1;\n const bp = b.popularity ?? -1;\n if (ap !== bp) return bp - ap;\n return a.name.localeCompare(b.name);\n });\n}\n\nfunction pad(s: string, width: number): string {\n return s.length >= width ? s : s + \" \".repeat(width - s.length);\n}\n\nfunction fmtAge(ms: number): string {\n const sec = Math.floor(ms / 1000);\n if (sec < 60) return `${sec}s ago`;\n if (sec < 3600) return `${Math.floor(sec / 60)}m ago`;\n if (sec < 86400) return `${Math.floor(sec / 3600)}h ago`;\n return `${Math.floor(sec / 86400)}d ago`;\n}\n\nfunction printEntry(e: RegistryEntry, indent = \" \"): void {\n const tag =\n e.source === \"official\" ? \"[official]\" : e.source === \"smithery\" ? \"[smithery]\" : \"[local]\";\n const pop = e.popularity !== undefined ? ` · ${e.popularity.toLocaleString()} uses` : \"\";\n console.log(`${indent}${pad(e.name, 36)} ${tag}${pop}`);\n if (e.description) console.log(`${indent} ${e.description}`);\n if (e.install?.requiredEnv?.length) {\n console.log(`${indent} needs: ${e.install.requiredEnv.join(\", \")}`);\n } else if (!e.install) {\n console.log(`${indent} (smithery listing — install detail fetched lazily on install)`);\n }\n}\n\nexport async function mcpListCommand(opts: McpListOptions = {}): Promise<void> {\n if (opts.local) {\n if (opts.json) {\n console.log(JSON.stringify(MCP_CATALOG, null, 2));\n return;\n }\n console.log(\"Bundled MCP servers (offline catalog):\");\n console.log(\"\");\n for (const entry of MCP_CATALOG) {\n console.log(` ${pad(entry.name, 12)} ${entry.summary}`);\n console.log(` ${mcpCommandFor(entry)}`);\n if (entry.note) console.log(` · ${entry.note}`);\n console.log(\"\");\n }\n return;\n }\n\n const handle = await openRegistry({ noCache: opts.refresh, onProgress: progressToStderr });\n const wantedPages = opts.all ? Number.POSITIVE_INFINITY : (opts.pages ?? 1);\n const additional = Math.max(0, wantedPages - handle.cache.pagination.pagesLoaded);\n if (additional > 0) {\n await loadMorePages(handle, {\n pages: additional,\n onProgress: progressToStderr,\n });\n }\n finishProgressLine();\n\n const result = handleToFetchResult(handle);\n const ranked = rankEntries(result.entries);\n const limit = opts.limit ?? DEFAULT_LIST_LIMIT;\n const shown = ranked.slice(0, limit);\n\n if (opts.json) {\n console.log(\n JSON.stringify(\n {\n source: result.source,\n fromCache: result.fromCache,\n fetchedAt: result.fetchedAt,\n loaded: result.entries.length,\n hasMore: result.hasMore,\n entries: shown,\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n const ageStr = result.fromCache\n ? `cached, ${fmtAge(Date.now() - result.fetchedAt)}`\n : \"just fetched\";\n const moreStr = result.hasMore ? \"more available\" : \"all loaded\";\n console.log(\n `MCP servers from ${result.source} registry (${result.entries.length} loaded, ${moreStr}, ${ageStr}):`,\n );\n if (result.errors.length > 0) {\n for (const e of result.errors) console.error(` warn: ${e}`);\n }\n console.log(\"\");\n for (const e of shown) printEntry(e);\n if (ranked.length > limit) {\n console.log(\n ` … ${ranked.length - limit} more loaded — use \\`reasonix mcp search <query>\\` to filter`,\n );\n }\n if (result.hasMore) {\n console.log(\" ▸ more pages available — `reasonix mcp list --pages <n>` or --all\");\n }\n console.log(\"\");\n console.log(\"Install: reasonix mcp install <name>\");\n}\n\nfunction matchFilter(query: string): (e: RegistryEntry) => boolean {\n const q = query.toLowerCase();\n return (e) => `${e.name} ${e.title} ${e.description}`.toLowerCase().includes(q);\n}\n\nexport async function mcpSearchCommand(query: string, opts: McpSearchOptions = {}): Promise<void> {\n const q = query.trim();\n if (!q) {\n console.error(\"usage: reasonix mcp search <query>\");\n process.exit(1);\n }\n const handle = await openRegistry({ noCache: opts.refresh, onProgress: progressToStderr });\n const filter = matchFilter(q);\n const limit = opts.limit ?? DEFAULT_LIST_LIMIT;\n const cap = opts.maxPages ?? SEARCH_PAGE_CAP;\n\n await loadMorePages(handle, {\n pages: Math.max(0, cap - handle.cache.pagination.pagesLoaded),\n matchTarget: limit,\n filter,\n onProgress: progressToStderr,\n });\n finishProgressLine();\n\n const result = handleToFetchResult(handle);\n const matches = rankEntries(result.entries.filter(filter));\n const shown = matches.slice(0, limit);\n\n if (opts.json) {\n console.log(\n JSON.stringify(\n {\n query: q,\n source: result.source,\n loaded: result.entries.length,\n hasMore: result.hasMore,\n matches: matches.length,\n entries: shown,\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n if (shown.length === 0) {\n console.log(\n `No matches for \"${q}\" across ${result.entries.length} loaded entries (${result.source}${\n result.hasMore ? \", more pages exist — try --refresh or `mcp list --all`\" : \"\"\n }).`,\n );\n return;\n }\n console.log(\n `${matches.length} match(es) for \"${q}\" in ${result.source} registry (${result.entries.length} entries scanned):`,\n );\n console.log(\"\");\n for (const e of shown) printEntry(e);\n if (matches.length > limit) console.log(` … ${matches.length - limit} more matches`);\n}\n\nfunction findEntry(entries: RegistryEntry[], name: string): RegistryEntry | null {\n const exact = entries.find((e) => e.name === name);\n if (exact) return exact;\n const lower = name.toLowerCase();\n const ci = entries.find((e) => e.name.toLowerCase() === lower);\n if (ci) return ci;\n const tail = entries.find((e) => e.name.toLowerCase().endsWith(`/${lower}`));\n if (tail) return tail;\n return null;\n}\n\nexport async function mcpInstallCommand(name: string, opts: McpInstallOptions = {}): Promise<void> {\n const target = name.trim();\n if (!target) {\n console.error(\"usage: reasonix mcp install <name>\");\n process.exit(1);\n }\n\n const handle = await openRegistry({ noCache: opts.refresh, onProgress: progressToStderr });\n const lower = target.toLowerCase();\n const filter = (e: RegistryEntry): boolean => {\n const n = e.name.toLowerCase();\n return n === lower || n.endsWith(`/${lower}`) || n.includes(lower);\n };\n const cap = opts.maxPages ?? INSTALL_PAGE_CAP;\n\n await loadMorePages(handle, {\n pages: Math.max(0, cap - handle.cache.pagination.pagesLoaded),\n matchTarget: 1,\n filter,\n onProgress: progressToStderr,\n });\n finishProgressLine();\n\n const entry = findEntry(handle.cache.entries, target);\n if (!entry) {\n console.error(\n `No MCP server named \"${target}\" found after walking ${handle.cache.pagination.pagesLoaded} page(s) of the ${handle.source} registry.`,\n );\n if (handle.cache.pagination.nextCursor !== null) {\n console.error(`Try: reasonix mcp install ${target} --max-pages 100`);\n }\n process.exit(1);\n }\n\n if (!entry.install && entry.source === \"smithery\") {\n process.stderr.write(`▸ fetching smithery install detail for ${entry.name}…\\n`);\n const fetched = await fetchSmitheryDetail(entry.name);\n if (fetched) entry.install = fetched;\n }\n\n if (!entry.install) {\n console.error(\n `Could not derive install metadata for \"${entry.name}\" — try \\`npx -y @smithery/cli install ${entry.name}\\` directly.`,\n );\n process.exit(1);\n }\n\n let spec: string;\n try {\n spec = specStringFor(entry.name, entry.install);\n } catch (err) {\n console.error(`Cannot build install spec for ${entry.name}: ${(err as Error).message}`);\n process.exit(1);\n }\n\n const cfg = readConfig();\n const existing = cfg.mcp ?? [];\n if (existing.includes(spec)) {\n console.log(`Already installed: ${spec}`);\n return;\n }\n const next = { ...cfg, mcp: [...existing, spec] };\n writeConfig(next);\n\n console.log(`Installed: ${entry.name}`);\n console.log(` spec: ${spec}`);\n const installedName = parseInstalledName(spec);\n if (entry.install.requiredEnv?.length) {\n console.log(` needs: ${entry.install.requiredEnv.join(\", \")}`);\n console.log(\" Either export these before launching, or add them to config:\");\n console.log(` mcpEnv.${installedName ?? entry.name} = { ... }`);\n console.log(\n ` (edit ${defaultConfigPath()} — values merge over process.env at spawn)`,\n );\n }\n console.log(\"\");\n console.log(\n \"Use it: reasonix chat (or `reasonix code`) — the server will be bridged automatically.\",\n );\n}\n\nfunction parseInstalledName(spec: string): string | null {\n const match = /^([a-zA-Z_][a-zA-Z0-9_-]*)=/.exec(spec);\n return match ? match[1]! : null;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/cli/commands/mcp.ts"],"sourcesContent":["import { defaultConfigPath, readConfig, writeConfig } from \"../../config.js\";\nimport { MCP_CATALOG, mcpCommandFor } from \"../../mcp/catalog.js\";\nimport {\n type FetchProgress,\n fetchSmitheryDetail,\n handleToFetchResult,\n loadMorePages,\n openRegistry,\n specStringFor,\n} from \"../../mcp/registry-fetch.js\";\nimport type { RegistryEntry } from \"../../mcp/registry-types.js\";\n\nconst DEFAULT_LIST_LIMIT = 30;\n/** Soft cap on how far `search` walks the registry on first run. */\nconst SEARCH_PAGE_CAP = 20;\n/** Soft cap on how far `install` walks looking for a name. */\nconst INSTALL_PAGE_CAP = 30;\n\nconst progressToStderr: FetchProgress = ({ source, page, entries }) => {\n if (page === 1 || page % 5 === 0) {\n process.stderr.write(`\\r▸ fetching ${source} registry · page ${page} · ${entries} entries`);\n }\n};\n\nfunction finishProgressLine(): void {\n if (process.stderr.isTTY) process.stderr.write(\"\\r\\x1b[K\");\n else process.stderr.write(\"\\n\");\n}\n\nexport interface McpListOptions {\n json?: boolean;\n /** Skip network — only show the bundled MCP_CATALOG entries. */\n local?: boolean;\n /** Bypass cache TTL. */\n refresh?: boolean;\n /** How many entries to show. Default 30. */\n limit?: number;\n /** Eagerly load this many pages before showing. Default 1. */\n pages?: number;\n /** Walk all pages of the registry (slow on first run). */\n all?: boolean;\n}\n\nexport interface McpSearchOptions {\n json?: boolean;\n refresh?: boolean;\n limit?: number;\n /** Cap how many pages to walk while searching. Default 20. */\n maxPages?: number;\n}\n\nexport interface McpInstallOptions {\n refresh?: boolean;\n /** Cap how many pages to walk while looking for the name. Default 30. */\n maxPages?: number;\n}\n\nfunction rankEntries(entries: RegistryEntry[]): RegistryEntry[] {\n return [...entries].sort((a, b) => {\n const ap = a.popularity ?? -1;\n const bp = b.popularity ?? -1;\n if (ap !== bp) return bp - ap;\n return a.name.localeCompare(b.name);\n });\n}\n\nfunction pad(s: string, width: number): string {\n return s.length >= width ? s : s + \" \".repeat(width - s.length);\n}\n\nfunction fmtAge(ms: number): string {\n const sec = Math.floor(ms / 1000);\n if (sec < 60) return `${sec}s ago`;\n if (sec < 3600) return `${Math.floor(sec / 60)}m ago`;\n if (sec < 86400) return `${Math.floor(sec / 3600)}h ago`;\n return `${Math.floor(sec / 86400)}d ago`;\n}\n\nfunction printEntry(e: RegistryEntry, indent = \" \"): void {\n const tag =\n e.source === \"official\" ? \"[official]\" : e.source === \"smithery\" ? \"[smithery]\" : \"[local]\";\n const pop = e.popularity !== undefined ? ` · ${e.popularity.toLocaleString()} uses` : \"\";\n console.log(`${indent}${pad(e.name, 36)} ${tag}${pop}`);\n if (e.description) console.log(`${indent} ${e.description}`);\n if (e.install?.requiredEnv?.length) {\n console.log(`${indent} needs: ${e.install.requiredEnv.join(\", \")}`);\n } else if (!e.install) {\n console.log(`${indent} (smithery listing — install detail fetched lazily on install)`);\n }\n}\n\nexport async function mcpListCommand(opts: McpListOptions = {}): Promise<void> {\n if (opts.local) {\n if (opts.json) {\n console.log(JSON.stringify(MCP_CATALOG, null, 2));\n return;\n }\n console.log(\"Bundled MCP servers (offline catalog):\");\n console.log(\"\");\n for (const entry of MCP_CATALOG) {\n console.log(` ${pad(entry.name, 12)} ${entry.summary}`);\n console.log(` ${mcpCommandFor(entry)}`);\n if (entry.note) console.log(` · ${entry.note}`);\n console.log(\"\");\n }\n return;\n }\n\n const handle = await openRegistry({ noCache: opts.refresh, onProgress: progressToStderr });\n const wantedPages = opts.all ? Number.POSITIVE_INFINITY : (opts.pages ?? 1);\n const additional = Math.max(0, wantedPages - handle.cache.pagination.pagesLoaded);\n if (additional > 0) {\n await loadMorePages(handle, {\n pages: additional,\n onProgress: progressToStderr,\n });\n }\n finishProgressLine();\n\n const result = handleToFetchResult(handle);\n const ranked = rankEntries(result.entries);\n const limit = opts.limit ?? DEFAULT_LIST_LIMIT;\n const shown = ranked.slice(0, limit);\n\n if (opts.json) {\n console.log(\n JSON.stringify(\n {\n source: result.source,\n fromCache: result.fromCache,\n fetchedAt: result.fetchedAt,\n loaded: result.entries.length,\n hasMore: result.hasMore,\n entries: shown,\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n const ageStr = result.fromCache\n ? `cached, ${fmtAge(Date.now() - result.fetchedAt)}`\n : \"just fetched\";\n const moreStr = result.hasMore ? \"more available\" : \"all loaded\";\n console.log(\n `MCP servers from ${result.source} registry (${result.entries.length} loaded, ${moreStr}, ${ageStr}):`,\n );\n if (result.errors.length > 0) {\n for (const e of result.errors) console.error(` warn: ${e}`);\n }\n console.log(\"\");\n for (const e of shown) printEntry(e);\n if (ranked.length > limit) {\n console.log(\n ` … ${ranked.length - limit} more loaded — use \\`reasonix mcp search <query>\\` to filter`,\n );\n }\n if (result.hasMore) {\n console.log(\" ▸ more pages available — `reasonix mcp list --pages <n>` or --all\");\n }\n console.log(\"\");\n console.log(\"Install: reasonix mcp install <name>\");\n}\n\nfunction matchFilter(query: string): (e: RegistryEntry) => boolean {\n const q = query.toLowerCase();\n return (e) => `${e.name} ${e.title} ${e.description}`.toLowerCase().includes(q);\n}\n\nexport async function mcpSearchCommand(query: string, opts: McpSearchOptions = {}): Promise<void> {\n const q = query.trim();\n if (!q) {\n console.error(\"usage: reasonix mcp search <query>\");\n process.exit(1);\n }\n const handle = await openRegistry({ noCache: opts.refresh, onProgress: progressToStderr });\n const filter = matchFilter(q);\n const limit = opts.limit ?? DEFAULT_LIST_LIMIT;\n const cap = opts.maxPages ?? SEARCH_PAGE_CAP;\n\n await loadMorePages(handle, {\n pages: Math.max(0, cap - handle.cache.pagination.pagesLoaded),\n matchTarget: limit,\n filter,\n onProgress: progressToStderr,\n });\n finishProgressLine();\n\n const result = handleToFetchResult(handle);\n const matches = rankEntries(result.entries.filter(filter));\n const shown = matches.slice(0, limit);\n\n if (opts.json) {\n console.log(\n JSON.stringify(\n {\n query: q,\n source: result.source,\n loaded: result.entries.length,\n hasMore: result.hasMore,\n matches: matches.length,\n entries: shown,\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n if (shown.length === 0) {\n console.log(\n `No matches for \"${q}\" across ${result.entries.length} loaded entries (${result.source}${\n result.hasMore ? \", more pages exist — try --refresh or `mcp list --all`\" : \"\"\n }).`,\n );\n return;\n }\n console.log(\n `${matches.length} match(es) for \"${q}\" in ${result.source} registry (${result.entries.length} entries scanned):`,\n );\n console.log(\"\");\n for (const e of shown) printEntry(e);\n if (matches.length > limit) console.log(` … ${matches.length - limit} more matches`);\n}\n\nfunction findEntry(entries: RegistryEntry[], name: string): RegistryEntry | null {\n const exact = entries.find((e) => e.name === name);\n if (exact) return exact;\n const lower = name.toLowerCase();\n const ci = entries.find((e) => e.name.toLowerCase() === lower);\n if (ci) return ci;\n const tail = entries.find((e) => e.name.toLowerCase().endsWith(`/${lower}`));\n if (tail) return tail;\n return null;\n}\n\nexport async function mcpInstallCommand(name: string, opts: McpInstallOptions = {}): Promise<void> {\n const target = name.trim();\n if (!target) {\n console.error(\"usage: reasonix mcp install <name>\");\n process.exit(1);\n }\n\n const handle = await openRegistry({ noCache: opts.refresh, onProgress: progressToStderr });\n const lower = target.toLowerCase();\n const filter = (e: RegistryEntry): boolean => {\n const n = e.name.toLowerCase();\n return n === lower || n.endsWith(`/${lower}`) || n.includes(lower);\n };\n const cap = opts.maxPages ?? INSTALL_PAGE_CAP;\n\n await loadMorePages(handle, {\n pages: Math.max(0, cap - handle.cache.pagination.pagesLoaded),\n matchTarget: 1,\n filter,\n onProgress: progressToStderr,\n });\n finishProgressLine();\n\n const entry = findEntry(handle.cache.entries, target);\n if (!entry) {\n console.error(\n `No MCP server named \"${target}\" found after walking ${handle.cache.pagination.pagesLoaded} page(s) of the ${handle.source} registry.`,\n );\n if (handle.cache.pagination.nextCursor !== null) {\n console.error(`Try: reasonix mcp install ${target} --max-pages 100`);\n }\n process.exit(1);\n }\n\n if (!entry.install && entry.source === \"smithery\") {\n process.stderr.write(`▸ fetching smithery install detail for ${entry.name}…\\n`);\n const fetched = await fetchSmitheryDetail(entry.name);\n if (fetched) entry.install = fetched;\n }\n\n if (!entry.install) {\n console.error(\n `Could not derive install metadata for \"${entry.name}\" — try \\`npx -y @smithery/cli install ${entry.name}\\` directly.`,\n );\n process.exit(1);\n }\n\n let spec: string;\n try {\n spec = specStringFor(entry.name, entry.install);\n } catch (err) {\n console.error(`Cannot build install spec for ${entry.name}: ${(err as Error).message}`);\n process.exit(1);\n }\n\n const cfg = readConfig();\n const existing = cfg.mcp ?? [];\n if (existing.includes(spec)) {\n console.log(`Already installed: ${spec}`);\n return;\n }\n const next = { ...cfg, mcp: [...existing, spec] };\n writeConfig(next);\n\n console.log(`Installed: ${entry.name}`);\n console.log(` spec: ${spec}`);\n const installedName = parseInstalledName(spec);\n if (entry.install.requiredEnv?.length) {\n console.log(` needs: ${entry.install.requiredEnv.join(\", \")}`);\n console.log(\" Either export these before launching, or add them to config:\");\n console.log(` mcpEnv.${installedName ?? entry.name} = { ... }`);\n console.log(\n ` (edit ${defaultConfigPath()} — values merge over process.env at spawn)`,\n );\n }\n console.log(\"\");\n console.log(\n \"Use it: reasonix chat (or `reasonix code`) — the server will be bridged automatically.\",\n );\n}\n\nfunction parseInstalledName(spec: string): string | null {\n const match = /^([a-zA-Z_][a-zA-Z0-9_-]*)=/.exec(spec);\n return match ? match[1]! : null;\n}\n"],"mappings":"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","names":[]}
@@ -1,24 +1,35 @@
1
1
  #!/usr/bin/env node
2
+ import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
2
3
  import {
3
4
  loadOverlay
4
- } from "./chunk-Y5XNV3NX.js";
5
+ } from "./chunk-JMBMLOBP.js";
6
+ import {
7
+ Box_default,
8
+ Text,
9
+ render_default,
10
+ require_react,
11
+ use_app_default,
12
+ use_input_default
13
+ } from "./chunk-6G3CUUFG.js";
5
14
  import {
6
15
  loadDotenv
7
- } from "./chunk-3Q3C4W66.js";
16
+ } from "./chunk-2UQP6H6T.js";
8
17
  import {
9
18
  loadMorePages,
10
19
  openRegistry,
11
20
  specStringFor
12
- } from "./chunk-SOZE7V7V.js";
13
- import "./chunk-FM57FNPJ.js";
21
+ } from "./chunk-XJXDHAES.js";
22
+ import "./chunk-PLHAZOLZ.js";
14
23
  import {
15
24
  readConfig,
16
25
  writeConfig
17
- } from "./chunk-65Q5HQ26.js";
26
+ } from "./chunk-XPDVG52A.js";
27
+ import {
28
+ __toESM
29
+ } from "./chunk-TUK7OWJA.js";
18
30
 
19
31
  // src/cli/commands/mcp-browse.tsx
20
- import { Box, Text, render, useApp, useInput } from "ink";
21
- import React, { useCallback, useEffect, useMemo, useState } from "react";
32
+ var import_react = __toESM(require_react(), 1);
22
33
  var VISIBLE_ROWS = 12;
23
34
  function rankAndFilter(entries, query) {
24
35
  const q = query.trim().toLowerCase();
@@ -31,18 +42,18 @@ function rankAndFilter(entries, query) {
31
42
  });
32
43
  }
33
44
  function McpBrowseApp() {
34
- const app = useApp();
35
- const [state, setState] = useState({
45
+ const app = use_app_default();
46
+ const [state, setState] = (0, import_react.useState)({
36
47
  handle: null,
37
48
  loading: true,
38
49
  query: "",
39
50
  selected: 0,
40
51
  status: "opening registry\u2026"
41
52
  });
42
- const setStatus = useCallback((status) => {
53
+ const setStatus = (0, import_react.useCallback)((status) => {
43
54
  setState((s) => ({ ...s, status }));
44
55
  }, []);
45
- useEffect(() => {
56
+ (0, import_react.useEffect)(() => {
46
57
  let cancelled = false;
47
58
  (async () => {
48
59
  try {
@@ -65,12 +76,12 @@ function McpBrowseApp() {
65
76
  cancelled = true;
66
77
  };
67
78
  }, []);
68
- const filtered = useMemo(() => {
79
+ const filtered = (0, import_react.useMemo)(() => {
69
80
  if (!state.handle) return [];
70
81
  return rankAndFilter(state.handle.cache.entries, state.query);
71
82
  }, [state.handle, state.query]);
72
83
  const selected = filtered[state.selected];
73
- const fetchMore = useCallback(async () => {
84
+ const fetchMore = (0, import_react.useCallback)(async () => {
74
85
  if (!state.handle || state.loading) return;
75
86
  if (state.handle.cache.pagination.nextCursor === null) {
76
87
  setStatus("no more pages \u2014 registry exhausted");
@@ -88,7 +99,7 @@ function McpBrowseApp() {
88
99
  setState((s) => ({ ...s, loading: false, status: `error: ${err.message}` }));
89
100
  }
90
101
  }, [state.handle, state.loading, setStatus]);
91
- const install = useCallback(
102
+ const install = (0, import_react.useCallback)(
92
103
  (entry) => {
93
104
  if (!entry.install) {
94
105
  setStatus(`${entry.name} has no install info (smithery listing)`);
@@ -110,7 +121,7 @@ function McpBrowseApp() {
110
121
  },
111
122
  [setStatus]
112
123
  );
113
- useInput((input, key) => {
124
+ use_input_default((input, key) => {
114
125
  if (key.escape || key.ctrl && input === "c") {
115
126
  app.exit();
116
127
  return;
@@ -139,23 +150,23 @@ function McpBrowseApp() {
139
150
  setState((s) => ({ ...s, query: s.query + input, selected: 0 }));
140
151
  }
141
152
  });
142
- const overlay = useMemo(() => loadOverlay("zh-CN"), []);
153
+ const overlay = (0, import_react.useMemo)(() => loadOverlay("zh-CN"), []);
143
154
  const start = Math.max(
144
155
  0,
145
156
  Math.min(state.selected - Math.floor(VISIBLE_ROWS / 2), filtered.length - VISIBLE_ROWS)
146
157
  );
147
158
  const window = filtered.slice(Math.max(0, start), Math.max(0, start) + VISIBLE_ROWS);
148
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { bold: true, color: "cyan" }, "\u25C8 MCP marketplace"), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, ` \xB7 ${state.status}`)), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, "search: "), /* @__PURE__ */ React.createElement(Text, { color: "white" }, state.query || "(type to filter)"), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, ` ${filtered.length} match${filtered.length === 1 ? "" : "es"}`)), /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, window.length === 0 ? /* @__PURE__ */ React.createElement(Text, { dimColor: true }, state.loading ? "loading\u2026" : "no entries") : window.map((e, i) => {
159
+ return /* @__PURE__ */ import_react.default.createElement(Box_default, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ import_react.default.createElement(Box_default, null, /* @__PURE__ */ import_react.default.createElement(Text, { bold: true, color: "cyan" }, "\u25C8 MCP marketplace"), /* @__PURE__ */ import_react.default.createElement(Text, { dimColor: true }, ` \xB7 ${state.status}`)), /* @__PURE__ */ import_react.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react.default.createElement(Text, null, "search: "), /* @__PURE__ */ import_react.default.createElement(Text, { color: "white" }, state.query || "(type to filter)"), /* @__PURE__ */ import_react.default.createElement(Text, { dimColor: true }, ` ${filtered.length} match${filtered.length === 1 ? "" : "es"}`)), /* @__PURE__ */ import_react.default.createElement(Box_default, { marginTop: 1, flexDirection: "column" }, window.length === 0 ? /* @__PURE__ */ import_react.default.createElement(Text, { dimColor: true }, state.loading ? "loading\u2026" : "no entries") : window.map((e, i) => {
149
160
  const idx = (start || 0) + i;
150
161
  const active = idx === state.selected;
151
162
  const tag = e.source === "official" ? "[off]" : e.source === "smithery" ? "[smt]" : "[loc]";
152
163
  const pop = e.popularity !== void 0 ? ` \xB7 ${e.popularity.toLocaleString()}` : "";
153
- return /* @__PURE__ */ React.createElement(Box, { key: e.name }, /* @__PURE__ */ React.createElement(Text, { color: active ? "cyan" : void 0 }, active ? "\u25B8 " : " "), /* @__PURE__ */ React.createElement(Text, { bold: active }, e.name.padEnd(40).slice(0, 40)), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, ` ${tag}${pop}`));
154
- })), selected ? /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: "white" }, overlay?.[selected.name]?.title ?? selected.title, overlay?.[selected.name] ? /* @__PURE__ */ React.createElement(Text, { dimColor: true }, ` \xB7 ${selected.title}`) : null), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, overlay?.[selected.name]?.description ?? selected.description?.slice(0, 160) ?? null), selected.install ? /* @__PURE__ */ React.createElement(Text, { dimColor: true }, `spec: ${selected.install.runtime} ${selected.install.packageId ?? selected.install.url ?? "\u2014"} \xB7 ${selected.install.transport}`) : /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "(smithery listing \u2014 install info not exposed)"), selected.install?.requiredEnv?.length ? /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, `needs: ${selected.install.requiredEnv.join(", ")}`) : null) : null, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "type to filter \xB7 \u2191\u2193 pick \xB7 enter install \xB7 tab load more \xB7 esc quit")));
164
+ return /* @__PURE__ */ import_react.default.createElement(Box_default, { key: e.name }, /* @__PURE__ */ import_react.default.createElement(Text, { color: active ? "cyan" : void 0 }, active ? "\u25B8 " : " "), /* @__PURE__ */ import_react.default.createElement(Text, { bold: active }, e.name.padEnd(40).slice(0, 40)), /* @__PURE__ */ import_react.default.createElement(Text, { dimColor: true }, ` ${tag}${pop}`));
165
+ })), selected ? /* @__PURE__ */ import_react.default.createElement(Box_default, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ import_react.default.createElement(Text, { bold: true, color: "white" }, overlay?.[selected.name]?.title ?? selected.title, overlay?.[selected.name] ? /* @__PURE__ */ import_react.default.createElement(Text, { dimColor: true }, ` \xB7 ${selected.title}`) : null), /* @__PURE__ */ import_react.default.createElement(Text, { dimColor: true }, overlay?.[selected.name]?.description ?? selected.description?.slice(0, 160) ?? null), selected.install ? /* @__PURE__ */ import_react.default.createElement(Text, { dimColor: true }, `spec: ${selected.install.runtime} ${selected.install.packageId ?? selected.install.url ?? "\u2014"} \xB7 ${selected.install.transport}`) : /* @__PURE__ */ import_react.default.createElement(Text, { dimColor: true }, "(smithery listing \u2014 install info not exposed)"), selected.install?.requiredEnv?.length ? /* @__PURE__ */ import_react.default.createElement(Text, { color: "yellow" }, `needs: ${selected.install.requiredEnv.join(", ")}`) : null) : null, /* @__PURE__ */ import_react.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react.default.createElement(Text, { dimColor: true }, "type to filter \xB7 \u2191\u2193 pick \xB7 enter install \xB7 tab load more \xB7 esc quit")));
155
166
  }
156
167
  async function mcpBrowseCommand(_opts = {}) {
157
168
  loadDotenv();
158
- const { waitUntilExit } = render(/* @__PURE__ */ React.createElement(McpBrowseApp, null), {
169
+ const { waitUntilExit } = render_default(/* @__PURE__ */ import_react.default.createElement(McpBrowseApp, null), {
159
170
  exitOnCtrlC: true,
160
171
  patchConsole: false
161
172
  });
@@ -164,4 +175,4 @@ async function mcpBrowseCommand(_opts = {}) {
164
175
  export {
165
176
  mcpBrowseCommand
166
177
  };
167
- //# sourceMappingURL=mcp-browse-XLDUE6SB.js.map
178
+ //# sourceMappingURL=mcp-browse-RR7R4XET.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/commands/mcp-browse.tsx"],"sourcesContent":["/** `reasonix mcp browse` — Ink TUI for the MCP marketplace. Lazy-loads pages on scroll. */\n\nimport { Box, Text, render, useApp, useInput } from \"ink\";\nimport React, { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { readConfig, writeConfig } from \"../../config.js\";\nimport { loadDotenv } from \"../../env.js\";\nimport { loadOverlay } from \"../../mcp/marketplace-overlay/loader.js\";\nimport {\n type RegistryHandle,\n loadMorePages,\n openRegistry,\n specStringFor,\n} from \"../../mcp/registry-fetch.js\";\nimport type { RegistryEntry } from \"../../mcp/registry-types.js\";\n\nconst VISIBLE_ROWS = 12;\n\ninterface State {\n handle: RegistryHandle | null;\n loading: boolean;\n query: string;\n selected: number;\n status: string;\n}\n\nfunction rankAndFilter(entries: RegistryEntry[], query: string): RegistryEntry[] {\n const q = query.trim().toLowerCase();\n const list = q\n ? entries.filter((e) => `${e.name} ${e.title} ${e.description}`.toLowerCase().includes(q))\n : entries;\n return [...list].sort((a, b) => {\n const ap = a.popularity ?? -1;\n const bp = b.popularity ?? -1;\n if (ap !== bp) return bp - ap;\n return a.name.localeCompare(b.name);\n });\n}\n\nfunction McpBrowseApp() {\n const app = useApp();\n const [state, setState] = useState<State>({\n handle: null,\n loading: true,\n query: \"\",\n selected: 0,\n status: \"opening registry…\",\n });\n\n const setStatus = useCallback((status: string) => {\n setState((s) => ({ ...s, status }));\n }, []);\n\n useEffect(() => {\n let cancelled = false;\n (async () => {\n try {\n const handle = await openRegistry({});\n if (cancelled) return;\n const ageMs = Date.now() - handle.fetchedAt;\n const ageStr =\n ageMs < 60_000 ? `${Math.floor(ageMs / 1000)}s` : `${Math.floor(ageMs / 60_000)}m`;\n setState((s) => ({\n ...s,\n handle,\n loading: false,\n status: `${handle.source} · ${handle.cache.entries.length} entries${\n handle.fromCache ? ` · cached ${ageStr} ago` : \"\"\n }`,\n }));\n } catch (err) {\n if (cancelled) return;\n setState((s) => ({ ...s, loading: false, status: `error: ${(err as Error).message}` }));\n }\n })();\n return () => {\n cancelled = true;\n };\n }, []);\n\n const filtered = useMemo(() => {\n if (!state.handle) return [];\n return rankAndFilter(state.handle.cache.entries, state.query);\n }, [state.handle, state.query]);\n\n const selected = filtered[state.selected];\n\n const fetchMore = useCallback(async () => {\n if (!state.handle || state.loading) return;\n if (state.handle.cache.pagination.nextCursor === null) {\n setStatus(\"no more pages — registry exhausted\");\n return;\n }\n setState((s) => ({ ...s, loading: true, status: \"loading more…\" }));\n try {\n const r = await loadMorePages(state.handle, { pages: 5 });\n setState((s) => ({\n ...s,\n loading: false,\n status: `+${r.newEntries} entries (${state.handle?.cache.entries.length ?? 0} total)${\n r.exhausted ? \" · exhausted\" : \"\"\n }`,\n }));\n } catch (err) {\n setState((s) => ({ ...s, loading: false, status: `error: ${(err as Error).message}` }));\n }\n }, [state.handle, state.loading, setStatus]);\n\n const install = useCallback(\n (entry: RegistryEntry) => {\n if (!entry.install) {\n setStatus(`${entry.name} has no install info (smithery listing)`);\n return;\n }\n try {\n const spec = specStringFor(entry.name, entry.install);\n const cfg = readConfig();\n const existing = cfg.mcp ?? [];\n if (existing.includes(spec)) {\n setStatus(`already installed: ${spec}`);\n return;\n }\n writeConfig({ ...cfg, mcp: [...existing, spec] });\n setStatus(`installed → ${spec}`);\n } catch (err) {\n setStatus(`install failed: ${(err as Error).message}`);\n }\n },\n [setStatus],\n );\n\n useInput((input, key) => {\n if (key.escape || (key.ctrl && input === \"c\")) {\n app.exit();\n return;\n }\n if (key.upArrow) {\n setState((s) => ({ ...s, selected: Math.max(0, s.selected - 1) }));\n return;\n }\n if (key.downArrow) {\n setState((s) => ({ ...s, selected: Math.min(filtered.length - 1, s.selected + 1) }));\n return;\n }\n if (key.return) {\n if (selected) install(selected);\n return;\n }\n if (key.tab || (key.ctrl && input === \"n\")) {\n void fetchMore();\n return;\n }\n if (key.backspace || key.delete) {\n setState((s) => ({ ...s, query: s.query.slice(0, -1), selected: 0 }));\n return;\n }\n if (input && !key.ctrl && !key.meta) {\n setState((s) => ({ ...s, query: s.query + input, selected: 0 }));\n }\n });\n\n const overlay = useMemo(() => loadOverlay(\"zh-CN\"), []);\n\n const start = Math.max(\n 0,\n Math.min(state.selected - Math.floor(VISIBLE_ROWS / 2), filtered.length - VISIBLE_ROWS),\n );\n const window = filtered.slice(Math.max(0, start), Math.max(0, start) + VISIBLE_ROWS);\n\n return (\n <Box flexDirection=\"column\" paddingX={1}>\n <Box>\n <Text bold color=\"cyan\">\n ◈ MCP marketplace\n </Text>\n <Text dimColor>{` · ${state.status}`}</Text>\n </Box>\n <Box marginTop={1}>\n <Text>search: </Text>\n <Text color=\"white\">{state.query || \"(type to filter)\"}</Text>\n <Text dimColor>{` ${filtered.length} match${filtered.length === 1 ? \"\" : \"es\"}`}</Text>\n </Box>\n <Box marginTop={1} flexDirection=\"column\">\n {window.length === 0 ? (\n <Text dimColor>{state.loading ? \"loading…\" : \"no entries\"}</Text>\n ) : (\n window.map((e, i) => {\n const idx = (start || 0) + i;\n const active = idx === state.selected;\n const tag =\n e.source === \"official\" ? \"[off]\" : e.source === \"smithery\" ? \"[smt]\" : \"[loc]\";\n const pop = e.popularity !== undefined ? ` · ${e.popularity.toLocaleString()}` : \"\";\n return (\n <Box key={e.name}>\n <Text color={active ? \"cyan\" : undefined}>{active ? \"▸ \" : \" \"}</Text>\n <Text bold={active}>{e.name.padEnd(40).slice(0, 40)}</Text>\n <Text dimColor>{` ${tag}${pop}`}</Text>\n </Box>\n );\n })\n )}\n </Box>\n {selected ? (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold color=\"white\">\n {overlay?.[selected.name]?.title ?? selected.title}\n {overlay?.[selected.name] ? (\n <Text dimColor>{` \\u00b7 ${selected.title}`}</Text>\n ) : null}\n </Text>\n <Text dimColor>\n {overlay?.[selected.name]?.description ?? selected.description?.slice(0, 160) ?? null}\n </Text>\n {selected.install ? (\n <Text dimColor>\n {`spec: ${selected.install.runtime} ${selected.install.packageId ?? selected.install.url ?? \"—\"} · ${selected.install.transport}`}\n </Text>\n ) : (\n <Text dimColor>(smithery listing — install info not exposed)</Text>\n )}\n {selected.install?.requiredEnv?.length ? (\n <Text color=\"yellow\">{`needs: ${selected.install.requiredEnv.join(\", \")}`}</Text>\n ) : null}\n </Box>\n ) : null}\n <Box marginTop={1}>\n <Text dimColor>type to filter · ↑↓ pick · enter install · tab load more · esc quit</Text>\n </Box>\n </Box>\n );\n}\n\nexport interface McpBrowseOptions {\n /** Reserved — currently unused, kept for symmetry with other commands. */\n _unused?: never;\n}\n\nexport async function mcpBrowseCommand(_opts: McpBrowseOptions = {}): Promise<void> {\n loadDotenv();\n const { waitUntilExit } = render(<McpBrowseApp />, {\n exitOnCtrlC: true,\n patchConsole: false,\n });\n await waitUntilExit();\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/cli/commands/mcp-browse.tsx"],"sourcesContent":["/** `reasonix mcp browse` — Ink TUI for the MCP marketplace. Lazy-loads pages on scroll. */\n\nimport { Box, Text, render, useApp, useInput } from \"ink\";\nimport React, { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { readConfig, writeConfig } from \"../../config.js\";\nimport { loadDotenv } from \"../../env.js\";\nimport { loadOverlay } from \"../../mcp/marketplace-overlay/loader.js\";\nimport {\n type RegistryHandle,\n loadMorePages,\n openRegistry,\n specStringFor,\n} from \"../../mcp/registry-fetch.js\";\nimport type { RegistryEntry } from \"../../mcp/registry-types.js\";\n\nconst VISIBLE_ROWS = 12;\n\ninterface State {\n handle: RegistryHandle | null;\n loading: boolean;\n query: string;\n selected: number;\n status: string;\n}\n\nfunction rankAndFilter(entries: RegistryEntry[], query: string): RegistryEntry[] {\n const q = query.trim().toLowerCase();\n const list = q\n ? entries.filter((e) => `${e.name} ${e.title} ${e.description}`.toLowerCase().includes(q))\n : entries;\n return [...list].sort((a, b) => {\n const ap = a.popularity ?? -1;\n const bp = b.popularity ?? -1;\n if (ap !== bp) return bp - ap;\n return a.name.localeCompare(b.name);\n });\n}\n\nfunction McpBrowseApp() {\n const app = useApp();\n const [state, setState] = useState<State>({\n handle: null,\n loading: true,\n query: \"\",\n selected: 0,\n status: \"opening registry…\",\n });\n\n const setStatus = useCallback((status: string) => {\n setState((s) => ({ ...s, status }));\n }, []);\n\n useEffect(() => {\n let cancelled = false;\n (async () => {\n try {\n const handle = await openRegistry({});\n if (cancelled) return;\n const ageMs = Date.now() - handle.fetchedAt;\n const ageStr =\n ageMs < 60_000 ? `${Math.floor(ageMs / 1000)}s` : `${Math.floor(ageMs / 60_000)}m`;\n setState((s) => ({\n ...s,\n handle,\n loading: false,\n status: `${handle.source} · ${handle.cache.entries.length} entries${\n handle.fromCache ? ` · cached ${ageStr} ago` : \"\"\n }`,\n }));\n } catch (err) {\n if (cancelled) return;\n setState((s) => ({ ...s, loading: false, status: `error: ${(err as Error).message}` }));\n }\n })();\n return () => {\n cancelled = true;\n };\n }, []);\n\n const filtered = useMemo(() => {\n if (!state.handle) return [];\n return rankAndFilter(state.handle.cache.entries, state.query);\n }, [state.handle, state.query]);\n\n const selected = filtered[state.selected];\n\n const fetchMore = useCallback(async () => {\n if (!state.handle || state.loading) return;\n if (state.handle.cache.pagination.nextCursor === null) {\n setStatus(\"no more pages — registry exhausted\");\n return;\n }\n setState((s) => ({ ...s, loading: true, status: \"loading more…\" }));\n try {\n const r = await loadMorePages(state.handle, { pages: 5 });\n setState((s) => ({\n ...s,\n loading: false,\n status: `+${r.newEntries} entries (${state.handle?.cache.entries.length ?? 0} total)${\n r.exhausted ? \" · exhausted\" : \"\"\n }`,\n }));\n } catch (err) {\n setState((s) => ({ ...s, loading: false, status: `error: ${(err as Error).message}` }));\n }\n }, [state.handle, state.loading, setStatus]);\n\n const install = useCallback(\n (entry: RegistryEntry) => {\n if (!entry.install) {\n setStatus(`${entry.name} has no install info (smithery listing)`);\n return;\n }\n try {\n const spec = specStringFor(entry.name, entry.install);\n const cfg = readConfig();\n const existing = cfg.mcp ?? [];\n if (existing.includes(spec)) {\n setStatus(`already installed: ${spec}`);\n return;\n }\n writeConfig({ ...cfg, mcp: [...existing, spec] });\n setStatus(`installed → ${spec}`);\n } catch (err) {\n setStatus(`install failed: ${(err as Error).message}`);\n }\n },\n [setStatus],\n );\n\n useInput((input, key) => {\n if (key.escape || (key.ctrl && input === \"c\")) {\n app.exit();\n return;\n }\n if (key.upArrow) {\n setState((s) => ({ ...s, selected: Math.max(0, s.selected - 1) }));\n return;\n }\n if (key.downArrow) {\n setState((s) => ({ ...s, selected: Math.min(filtered.length - 1, s.selected + 1) }));\n return;\n }\n if (key.return) {\n if (selected) install(selected);\n return;\n }\n if (key.tab || (key.ctrl && input === \"n\")) {\n void fetchMore();\n return;\n }\n if (key.backspace || key.delete) {\n setState((s) => ({ ...s, query: s.query.slice(0, -1), selected: 0 }));\n return;\n }\n if (input && !key.ctrl && !key.meta) {\n setState((s) => ({ ...s, query: s.query + input, selected: 0 }));\n }\n });\n\n const overlay = useMemo(() => loadOverlay(\"zh-CN\"), []);\n\n const start = Math.max(\n 0,\n Math.min(state.selected - Math.floor(VISIBLE_ROWS / 2), filtered.length - VISIBLE_ROWS),\n );\n const window = filtered.slice(Math.max(0, start), Math.max(0, start) + VISIBLE_ROWS);\n\n return (\n <Box flexDirection=\"column\" paddingX={1}>\n <Box>\n <Text bold color=\"cyan\">\n ◈ MCP marketplace\n </Text>\n <Text dimColor>{` · ${state.status}`}</Text>\n </Box>\n <Box marginTop={1}>\n <Text>search: </Text>\n <Text color=\"white\">{state.query || \"(type to filter)\"}</Text>\n <Text dimColor>{` ${filtered.length} match${filtered.length === 1 ? \"\" : \"es\"}`}</Text>\n </Box>\n <Box marginTop={1} flexDirection=\"column\">\n {window.length === 0 ? (\n <Text dimColor>{state.loading ? \"loading…\" : \"no entries\"}</Text>\n ) : (\n window.map((e, i) => {\n const idx = (start || 0) + i;\n const active = idx === state.selected;\n const tag =\n e.source === \"official\" ? \"[off]\" : e.source === \"smithery\" ? \"[smt]\" : \"[loc]\";\n const pop = e.popularity !== undefined ? ` · ${e.popularity.toLocaleString()}` : \"\";\n return (\n <Box key={e.name}>\n <Text color={active ? \"cyan\" : undefined}>{active ? \"▸ \" : \" \"}</Text>\n <Text bold={active}>{e.name.padEnd(40).slice(0, 40)}</Text>\n <Text dimColor>{` ${tag}${pop}`}</Text>\n </Box>\n );\n })\n )}\n </Box>\n {selected ? (\n <Box marginTop={1} flexDirection=\"column\">\n <Text bold color=\"white\">\n {overlay?.[selected.name]?.title ?? selected.title}\n {overlay?.[selected.name] ? (\n <Text dimColor>{` \\u00b7 ${selected.title}`}</Text>\n ) : null}\n </Text>\n <Text dimColor>\n {overlay?.[selected.name]?.description ?? selected.description?.slice(0, 160) ?? null}\n </Text>\n {selected.install ? (\n <Text dimColor>\n {`spec: ${selected.install.runtime} ${selected.install.packageId ?? selected.install.url ?? \"—\"} · ${selected.install.transport}`}\n </Text>\n ) : (\n <Text dimColor>(smithery listing — install info not exposed)</Text>\n )}\n {selected.install?.requiredEnv?.length ? (\n <Text color=\"yellow\">{`needs: ${selected.install.requiredEnv.join(\", \")}`}</Text>\n ) : null}\n </Box>\n ) : null}\n <Box marginTop={1}>\n <Text dimColor>type to filter · ↑↓ pick · enter install · tab load more · esc quit</Text>\n </Box>\n </Box>\n );\n}\n\nexport interface McpBrowseOptions {\n /** Reserved — currently unused, kept for symmetry with other commands. */\n _unused?: never;\n}\n\nexport async function mcpBrowseCommand(_opts: McpBrowseOptions = {}): Promise<void> {\n loadDotenv();\n const { waitUntilExit } = render(<McpBrowseApp />, {\n exitOnCtrlC: true,\n patchConsole: false,\n });\n await waitUntilExit();\n}\n"],"mappings":"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","names":["React"]}
@@ -1,18 +1,21 @@
1
1
  #!/usr/bin/env node
2
+ import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
2
3
  import {
3
4
  buildTransportFromSpec,
4
5
  preflightStdioSpec
5
- } from "./chunk-BOFL3T45.js";
6
+ } from "./chunk-PQXPXJBJ.js";
6
7
  import {
7
8
  McpClient,
8
9
  inspectMcpServer,
9
10
  parseMcpSpec
10
- } from "./chunk-CFY2XLY6.js";
11
+ } from "./chunk-6AK4EY3D.js";
12
+ import "./chunk-25T6CVUP.js";
11
13
  import {
12
14
  mcpEnvFor,
13
15
  readConfig
14
- } from "./chunk-65Q5HQ26.js";
15
- import "./chunk-CRPQUBP6.js";
16
+ } from "./chunk-XPDVG52A.js";
17
+ import "./chunk-XXC2BYTV.js";
18
+ import "./chunk-TUK7OWJA.js";
16
19
 
17
20
  // src/cli/commands/mcp-inspect.ts
18
21
  async function mcpInspectCommand(opts) {
@@ -137,4 +140,4 @@ export {
137
140
  formatMcpInspectFailure,
138
141
  mcpInspectCommand
139
142
  };
140
- //# sourceMappingURL=mcp-inspect-H4D2HSJP.js.map
143
+ //# sourceMappingURL=mcp-inspect-REGLYBWT.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/commands/mcp-inspect.ts"],"sourcesContent":["import { mcpEnvFor, readConfig } from \"../../config.js\";\nimport { McpClient } from \"../../mcp/client.js\";\nimport { inspectMcpServer } from \"../../mcp/inspect.js\";\nimport type { InspectionReport } from \"../../mcp/inspect.js\";\nimport { preflightStdioSpec } from \"../../mcp/preflight.js\";\nimport { parseMcpSpec } from \"../../mcp/spec.js\";\nimport { buildTransportFromSpec } from \"../../mcp/transport-from-spec.js\";\n\nexport interface McpInspectOptions {\n /** The raw --mcp spec string (e.g. `fs=npx -y @modelcontextprotocol/server-filesystem .`). */\n spec: string;\n /** Emit JSON on stdout instead of the human-readable table. */\n json?: boolean;\n}\n\nexport async function mcpInspectCommand(opts: McpInspectOptions): Promise<void> {\n const spec = parseMcpSpec(opts.spec);\n if (spec.transport === \"stdio\") preflightStdioSpec(spec);\n const transport = buildTransportFromSpec(spec, { env: mcpEnvFor(spec.name, readConfig()) });\n const client = new McpClient({ transport });\n try {\n await client.initialize();\n const report = await inspectMcpServer(client);\n if (opts.json) {\n console.log(JSON.stringify(report, null, 2));\n } else {\n console.log(formatReport(spec.name ?? \"(anon)\", report));\n }\n } finally {\n await client.close();\n }\n}\n\nexport function formatMcpInspectFailure(err: unknown): string {\n const error = err instanceof Error ? err : new Error(String(err));\n const message = error.message;\n const code = (error as NodeJS.ErrnoException).code;\n\n if (code === \"ENOENT\") {\n const command = message.match(/^spawn\\s+([^\\s]+)\\s+ENOENT$/)?.[1] ?? \"the command\";\n return `${message} — try: install or verify \\`${command}\\`, then check the MCP spec's command spelling`;\n }\n\n if (code === \"ECONNREFUSED\") {\n const target = message.match(/\\b(https?:\\/\\/\\S+|\\d+\\.\\d+\\.\\d+\\.\\d+:\\d+|localhost:\\d+)\\b/i)?.[1];\n return `${message} — try: confirm ${target ?? \"the MCP server\"} is running and the host/port match the spec`;\n }\n\n if (code === \"ENOTFOUND\" || code === \"EAI_AGAIN\") {\n return `${message} — try: confirm the hostname is spelled correctly and DNS resolution is working (check your network/VPN)`;\n }\n\n if (code === \"ECONNRESET\") {\n return `${message} — try: retry the request; if it keeps happening, check the server's logs for crashes or rate limits`;\n }\n\n if (code === \"ETIMEDOUT\") {\n return `${message} — try: confirm the host is reachable and no firewall/proxy is blocking the port`;\n }\n\n if (\n code === \"CERT_HAS_EXPIRED\" ||\n code === \"DEPTH_ZERO_SELF_SIGNED_CERT\" ||\n code === \"UNABLE_TO_VERIFY_LEAF_SIGNATURE\" ||\n code === \"SELF_SIGNED_CERT_IN_CHAIN\"\n ) {\n return `${message} — try: renew or trust the server's TLS certificate, or point the spec at an endpoint with a valid cert`;\n }\n\n // HTTP non-2xx from SSE / Streamable HTTP transports. Match the three\n // exact shapes those transports emit and surface an auth/endpoint hint.\n const httpStatus = matchTransportHttpStatus(message);\n if (httpStatus !== null) {\n return `${message}${hintForHttpStatus(httpStatus)}`;\n }\n\n if (/^MCP request initialize \\(id=\\d+\\) timed out after \\d+ms$/.test(message)) {\n return `${message} — try: confirm the target speaks MCP and completes the handshake before the request timeout`;\n }\n\n if (/^(empty MCP spec|MCP spec \".*\" has name but no command)/.test(message)) {\n return `${message} — try: pass \\`name=command args\\` or an http(s):// URL`;\n }\n\n return message;\n}\n\nfunction matchTransportHttpStatus(message: string): number | null {\n // src/mcp/sse.ts: `SSE handshake <url> → <status> <statusText>`\n // src/mcp/sse.ts: `MCP SSE POST <url> failed: <status> <statusText>`\n // src/mcp/streamable-http.ts: `MCP Streamable HTTP POST <url> → <status> <statusText>...`\n const m =\n message.match(/^SSE handshake \\S+ → (\\d{3})\\b/) ??\n message.match(/^MCP SSE POST \\S+ failed: (\\d{3})\\b/) ??\n message.match(/^MCP Streamable HTTP POST \\S+ → (\\d{3})\\b/);\n return m ? Number(m[1]) : null;\n}\n\nfunction hintForHttpStatus(status: number): string {\n if (status === 401) {\n return \" — try: check the spec's auth header (e.g. `Authorization: Bearer …`) or confirm the token isn't expired\";\n }\n if (status === 403) {\n return \" — try: confirm the credentials have permission to reach this MCP endpoint\";\n }\n if (status === 404) {\n return \" — try: confirm the endpoint path in the spec matches what the server actually exposes\";\n }\n if (status >= 500 && status <= 599) {\n return \" — try: retry shortly; if the failure persists, check the MCP server's logs\";\n }\n return \"\";\n}\n\nfunction formatReport(nsName: string, r: InspectionReport): string {\n const lines: string[] = [];\n lines.push(`MCP server [${nsName}]`);\n lines.push(\n ` server ${r.serverInfo.name || \"(unknown)\"}${r.serverInfo.version ? ` v${r.serverInfo.version}` : \"\"}`,\n );\n lines.push(` protocol ${r.protocolVersion}`);\n const capKeys = Object.keys(r.capabilities);\n lines.push(` caps ${capKeys.length > 0 ? capKeys.join(\", \") : \"(none advertised)\"}`);\n if (r.instructions) {\n lines.push(` notes ${r.instructions.trim().slice(0, 200)}`);\n }\n lines.push(\"\");\n lines.push(formatSection(\"Tools\", r.tools, toolLine));\n lines.push(formatSection(\"Resources\", r.resources, resourceLine));\n lines.push(formatSection(\"Prompts\", r.prompts, promptLine));\n return lines.join(\"\\n\");\n}\n\nfunction formatSection<T>(\n title: string,\n section: { supported: true; items: T[] } | { supported: false; reason: string },\n render: (item: T) => string,\n): string {\n if (!section.supported) {\n return `${title}: (not supported — ${section.reason})`;\n }\n if (section.items.length === 0) {\n return `${title}: (none)`;\n }\n const lines = [`${title} (${section.items.length}):`];\n for (const item of section.items) lines.push(` ${render(item)}`);\n return lines.join(\"\\n\");\n}\n\nfunction toolLine(t: { name: string; description?: string }): string {\n const desc = t.description ? ` — ${oneLine(t.description, 80)}` : \"\";\n return `· ${t.name}${desc}`;\n}\n\nfunction resourceLine(r: { uri: string; name: string; mimeType?: string }): string {\n const mime = r.mimeType ? ` [${r.mimeType}]` : \"\";\n return `· ${r.name}${mime} ${r.uri}`;\n}\n\nfunction promptLine(p: {\n name: string;\n description?: string;\n arguments?: Array<{ name: string; required?: boolean }>;\n}): string {\n const argPart =\n p.arguments && p.arguments.length > 0\n ? ` (${p.arguments.map((a) => (a.required ? a.name : `${a.name}?`)).join(\", \")})`\n : \"\";\n const desc = p.description ? ` — ${oneLine(p.description, 80)}` : \"\";\n return `· ${p.name}${argPart}${desc}`;\n}\n\nfunction oneLine(s: string, max: number): string {\n const flat = s.replace(/\\s+/g, \" \").trim();\n return flat.length <= max ? flat : `${flat.slice(0, max - 1)}…`;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/cli/commands/mcp-inspect.ts"],"sourcesContent":["import { mcpEnvFor, readConfig } from \"../../config.js\";\nimport { McpClient } from \"../../mcp/client.js\";\nimport { inspectMcpServer } from \"../../mcp/inspect.js\";\nimport type { InspectionReport } from \"../../mcp/inspect.js\";\nimport { preflightStdioSpec } from \"../../mcp/preflight.js\";\nimport { parseMcpSpec } from \"../../mcp/spec.js\";\nimport { buildTransportFromSpec } from \"../../mcp/transport-from-spec.js\";\n\nexport interface McpInspectOptions {\n /** The raw --mcp spec string (e.g. `fs=npx -y @modelcontextprotocol/server-filesystem .`). */\n spec: string;\n /** Emit JSON on stdout instead of the human-readable table. */\n json?: boolean;\n}\n\nexport async function mcpInspectCommand(opts: McpInspectOptions): Promise<void> {\n const spec = parseMcpSpec(opts.spec);\n if (spec.transport === \"stdio\") preflightStdioSpec(spec);\n const transport = buildTransportFromSpec(spec, { env: mcpEnvFor(spec.name, readConfig()) });\n const client = new McpClient({ transport });\n try {\n await client.initialize();\n const report = await inspectMcpServer(client);\n if (opts.json) {\n console.log(JSON.stringify(report, null, 2));\n } else {\n console.log(formatReport(spec.name ?? \"(anon)\", report));\n }\n } finally {\n await client.close();\n }\n}\n\nexport function formatMcpInspectFailure(err: unknown): string {\n const error = err instanceof Error ? err : new Error(String(err));\n const message = error.message;\n const code = (error as NodeJS.ErrnoException).code;\n\n if (code === \"ENOENT\") {\n const command = message.match(/^spawn\\s+([^\\s]+)\\s+ENOENT$/)?.[1] ?? \"the command\";\n return `${message} — try: install or verify \\`${command}\\`, then check the MCP spec's command spelling`;\n }\n\n if (code === \"ECONNREFUSED\") {\n const target = message.match(/\\b(https?:\\/\\/\\S+|\\d+\\.\\d+\\.\\d+\\.\\d+:\\d+|localhost:\\d+)\\b/i)?.[1];\n return `${message} — try: confirm ${target ?? \"the MCP server\"} is running and the host/port match the spec`;\n }\n\n if (code === \"ENOTFOUND\" || code === \"EAI_AGAIN\") {\n return `${message} — try: confirm the hostname is spelled correctly and DNS resolution is working (check your network/VPN)`;\n }\n\n if (code === \"ECONNRESET\") {\n return `${message} — try: retry the request; if it keeps happening, check the server's logs for crashes or rate limits`;\n }\n\n if (code === \"ETIMEDOUT\") {\n return `${message} — try: confirm the host is reachable and no firewall/proxy is blocking the port`;\n }\n\n if (\n code === \"CERT_HAS_EXPIRED\" ||\n code === \"DEPTH_ZERO_SELF_SIGNED_CERT\" ||\n code === \"UNABLE_TO_VERIFY_LEAF_SIGNATURE\" ||\n code === \"SELF_SIGNED_CERT_IN_CHAIN\"\n ) {\n return `${message} — try: renew or trust the server's TLS certificate, or point the spec at an endpoint with a valid cert`;\n }\n\n // HTTP non-2xx from SSE / Streamable HTTP transports. Match the three\n // exact shapes those transports emit and surface an auth/endpoint hint.\n const httpStatus = matchTransportHttpStatus(message);\n if (httpStatus !== null) {\n return `${message}${hintForHttpStatus(httpStatus)}`;\n }\n\n if (/^MCP request initialize \\(id=\\d+\\) timed out after \\d+ms$/.test(message)) {\n return `${message} — try: confirm the target speaks MCP and completes the handshake before the request timeout`;\n }\n\n if (/^(empty MCP spec|MCP spec \".*\" has name but no command)/.test(message)) {\n return `${message} — try: pass \\`name=command args\\` or an http(s):// URL`;\n }\n\n return message;\n}\n\nfunction matchTransportHttpStatus(message: string): number | null {\n // src/mcp/sse.ts: `SSE handshake <url> → <status> <statusText>`\n // src/mcp/sse.ts: `MCP SSE POST <url> failed: <status> <statusText>`\n // src/mcp/streamable-http.ts: `MCP Streamable HTTP POST <url> → <status> <statusText>...`\n const m =\n message.match(/^SSE handshake \\S+ → (\\d{3})\\b/) ??\n message.match(/^MCP SSE POST \\S+ failed: (\\d{3})\\b/) ??\n message.match(/^MCP Streamable HTTP POST \\S+ → (\\d{3})\\b/);\n return m ? Number(m[1]) : null;\n}\n\nfunction hintForHttpStatus(status: number): string {\n if (status === 401) {\n return \" — try: check the spec's auth header (e.g. `Authorization: Bearer …`) or confirm the token isn't expired\";\n }\n if (status === 403) {\n return \" — try: confirm the credentials have permission to reach this MCP endpoint\";\n }\n if (status === 404) {\n return \" — try: confirm the endpoint path in the spec matches what the server actually exposes\";\n }\n if (status >= 500 && status <= 599) {\n return \" — try: retry shortly; if the failure persists, check the MCP server's logs\";\n }\n return \"\";\n}\n\nfunction formatReport(nsName: string, r: InspectionReport): string {\n const lines: string[] = [];\n lines.push(`MCP server [${nsName}]`);\n lines.push(\n ` server ${r.serverInfo.name || \"(unknown)\"}${r.serverInfo.version ? ` v${r.serverInfo.version}` : \"\"}`,\n );\n lines.push(` protocol ${r.protocolVersion}`);\n const capKeys = Object.keys(r.capabilities);\n lines.push(` caps ${capKeys.length > 0 ? capKeys.join(\", \") : \"(none advertised)\"}`);\n if (r.instructions) {\n lines.push(` notes ${r.instructions.trim().slice(0, 200)}`);\n }\n lines.push(\"\");\n lines.push(formatSection(\"Tools\", r.tools, toolLine));\n lines.push(formatSection(\"Resources\", r.resources, resourceLine));\n lines.push(formatSection(\"Prompts\", r.prompts, promptLine));\n return lines.join(\"\\n\");\n}\n\nfunction formatSection<T>(\n title: string,\n section: { supported: true; items: T[] } | { supported: false; reason: string },\n render: (item: T) => string,\n): string {\n if (!section.supported) {\n return `${title}: (not supported — ${section.reason})`;\n }\n if (section.items.length === 0) {\n return `${title}: (none)`;\n }\n const lines = [`${title} (${section.items.length}):`];\n for (const item of section.items) lines.push(` ${render(item)}`);\n return lines.join(\"\\n\");\n}\n\nfunction toolLine(t: { name: string; description?: string }): string {\n const desc = t.description ? ` — ${oneLine(t.description, 80)}` : \"\";\n return `· ${t.name}${desc}`;\n}\n\nfunction resourceLine(r: { uri: string; name: string; mimeType?: string }): string {\n const mime = r.mimeType ? ` [${r.mimeType}]` : \"\";\n return `· ${r.name}${mime} ${r.uri}`;\n}\n\nfunction promptLine(p: {\n name: string;\n description?: string;\n arguments?: Array<{ name: string; required?: boolean }>;\n}): string {\n const argPart =\n p.arguments && p.arguments.length > 0\n ? ` (${p.arguments.map((a) => (a.required ? a.name : `${a.name}?`)).join(\", \")})`\n : \"\";\n const desc = p.description ? ` — ${oneLine(p.description, 80)}` : \"\";\n return `· ${p.name}${argPart}${desc}`;\n}\n\nfunction oneLine(s: string, max: number): string {\n const flat = s.replace(/\\s+/g, \" \").trim();\n return flat.length <= max ? flat : `${flat.slice(0, max - 1)}…`;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
3
+ import {
4
+ CODE_SYSTEM_PROMPT,
5
+ codeSystemBase,
6
+ codeSystemPrompt
7
+ } from "./chunk-5JJRUIPA.js";
8
+ import "./chunk-2K65GZBT.js";
9
+ import "./chunk-XPDVG52A.js";
10
+ import "./chunk-TUK7OWJA.js";
11
+ export {
12
+ CODE_SYSTEM_PROMPT,
13
+ codeSystemBase,
14
+ codeSystemPrompt
15
+ };
16
+ //# sourceMappingURL=prompt-UW6EFLVR.js.map
@@ -1,8 +1,10 @@
1
1
  #!/usr/bin/env node
2
+ import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
2
3
  import {
3
4
  listSessions,
4
5
  pruneStaleSessions
5
- } from "./chunk-YJFKFTAL.js";
6
+ } from "./chunk-6PBZN4VI.js";
7
+ import "./chunk-TUK7OWJA.js";
6
8
 
7
9
  // src/cli/commands/prune-sessions.ts
8
10
  function pruneSessionsCommand(opts) {
@@ -39,4 +41,4 @@ function pruneSessionsCommand(opts) {
39
41
  export {
40
42
  pruneSessionsCommand
41
43
  };
42
- //# sourceMappingURL=prune-sessions-4N3BVST2.js.map
44
+ //# sourceMappingURL=prune-sessions-3RWUBYRS.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/commands/prune-sessions.ts"],"sourcesContent":["import { listSessions, pruneStaleSessions } from \"../../memory/session.js\";\n\nexport interface PruneSessionsOptions {\n days?: number;\n dryRun?: boolean;\n}\n\nexport function pruneSessionsCommand(opts: PruneSessionsOptions): void {\n const days = opts.days ?? 90;\n if (!Number.isFinite(days) || days < 1) {\n console.error(`--days must be a positive integer (got ${days}).`);\n process.exit(1);\n }\n if (opts.dryRun) {\n const cutoff = Date.now() - days * 24 * 60 * 60 * 1000;\n const stale = listSessions().filter((s) => s.mtime.getTime() < cutoff);\n if (stale.length === 0) {\n console.log(`no sessions idle ≥${days} days. Nothing would be pruned.`);\n return;\n }\n console.log(`would prune ${stale.length} session(s) idle ≥${days} days:`);\n for (const s of stale) {\n console.log(` ${s.name}`);\n }\n console.log(\"\");\n console.log(\"re-run without --dry-run to actually delete.\");\n return;\n }\n const removed = pruneStaleSessions(days);\n if (removed.length === 0) {\n console.log(`no sessions idle ≥${days} days. Nothing pruned.`);\n return;\n }\n console.log(`pruned ${removed.length} session(s) idle ≥${days} days:`);\n for (const name of removed) {\n console.log(` ${name}`);\n }\n}\n"],"mappings":";;;;;;;AAOO,SAAS,qBAAqB,MAAkC;AACrE,QAAM,OAAO,KAAK,QAAQ;AAC1B,MAAI,CAAC,OAAO,SAAS,IAAI,KAAK,OAAO,GAAG;AACtC,YAAQ,MAAM,0CAA0C,IAAI,IAAI;AAChE,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,MAAI,KAAK,QAAQ;AACf,UAAM,SAAS,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,KAAK;AAClD,UAAM,QAAQ,aAAa,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,QAAQ,IAAI,MAAM;AACrE,QAAI,MAAM,WAAW,GAAG;AACtB,cAAQ,IAAI,0BAAqB,IAAI,iCAAiC;AACtE;AAAA,IACF;AACA,YAAQ,IAAI,eAAe,MAAM,MAAM,0BAAqB,IAAI,QAAQ;AACxE,eAAW,KAAK,OAAO;AACrB,cAAQ,IAAI,KAAK,EAAE,IAAI,EAAE;AAAA,IAC3B;AACA,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,8CAA8C;AAC1D;AAAA,EACF;AACA,QAAM,UAAU,mBAAmB,IAAI;AACvC,MAAI,QAAQ,WAAW,GAAG;AACxB,YAAQ,IAAI,0BAAqB,IAAI,wBAAwB;AAC7D;AAAA,EACF;AACA,UAAQ,IAAI,UAAU,QAAQ,MAAM,0BAAqB,IAAI,QAAQ;AACrE,aAAW,QAAQ,SAAS;AAC1B,YAAQ,IAAI,KAAK,IAAI,EAAE;AAAA,EACzB;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/cli/commands/prune-sessions.ts"],"sourcesContent":["import { listSessions, pruneStaleSessions } from \"../../memory/session.js\";\n\nexport interface PruneSessionsOptions {\n days?: number;\n dryRun?: boolean;\n}\n\nexport function pruneSessionsCommand(opts: PruneSessionsOptions): void {\n const days = opts.days ?? 90;\n if (!Number.isFinite(days) || days < 1) {\n console.error(`--days must be a positive integer (got ${days}).`);\n process.exit(1);\n }\n if (opts.dryRun) {\n const cutoff = Date.now() - days * 24 * 60 * 60 * 1000;\n const stale = listSessions().filter((s) => s.mtime.getTime() < cutoff);\n if (stale.length === 0) {\n console.log(`no sessions idle ≥${days} days. Nothing would be pruned.`);\n return;\n }\n console.log(`would prune ${stale.length} session(s) idle ≥${days} days:`);\n for (const s of stale) {\n console.log(` ${s.name}`);\n }\n console.log(\"\");\n console.log(\"re-run without --dry-run to actually delete.\");\n return;\n }\n const removed = pruneStaleSessions(days);\n if (removed.length === 0) {\n console.log(`no sessions idle ≥${days} days. Nothing pruned.`);\n return;\n }\n console.log(`pruned ${removed.length} session(s) idle ≥${days} days:`);\n for (const name of removed) {\n console.log(` ${name}`);\n }\n}\n"],"mappings":";;;;;;;;;AAOO,SAAS,qBAAqB,MAAkC;AACrE,QAAM,OAAO,KAAK,QAAQ;AAC1B,MAAI,CAAC,OAAO,SAAS,IAAI,KAAK,OAAO,GAAG;AACtC,YAAQ,MAAM,0CAA0C,IAAI,IAAI;AAChE,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,MAAI,KAAK,QAAQ;AACf,UAAM,SAAS,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,KAAK;AAClD,UAAM,QAAQ,aAAa,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,QAAQ,IAAI,MAAM;AACrE,QAAI,MAAM,WAAW,GAAG;AACtB,cAAQ,IAAI,0BAAqB,IAAI,iCAAiC;AACtE;AAAA,IACF;AACA,YAAQ,IAAI,eAAe,MAAM,MAAM,0BAAqB,IAAI,QAAQ;AACxE,eAAW,KAAK,OAAO;AACrB,cAAQ,IAAI,KAAK,EAAE,IAAI,EAAE;AAAA,IAC3B;AACA,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,8CAA8C;AAC1D;AAAA,EACF;AACA,QAAM,UAAU,mBAAmB,IAAI;AACvC,MAAI,QAAQ,WAAW,GAAG;AACxB,YAAQ,IAAI,0BAAqB,IAAI,wBAAwB;AAC7D;AAAA,EACF;AACA,UAAQ,IAAI,UAAU,QAAQ,MAAM,0BAAqB,IAAI,QAAQ;AACrE,aAAW,QAAQ,SAAS;AAC1B,YAAQ,IAAI,KAAK,IAAI,EAAE;AAAA,EACzB;AACF;","names":[]}