@samanhappy/mcphub 1.0.0 → 1.0.1

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 (116) hide show
  1. package/README.fr.md +6 -4
  2. package/README.md +24 -4
  3. package/README.zh.md +25 -4
  4. package/bin/cli.js +64 -50
  5. package/dist/cli/call-arguments.js +81 -0
  6. package/dist/cli/call-arguments.js.map +1 -0
  7. package/dist/cli/commands/call.js +75 -0
  8. package/dist/cli/commands/call.js.map +1 -0
  9. package/dist/cli/commands/config.js +132 -0
  10. package/dist/cli/commands/config.js.map +1 -0
  11. package/dist/cli/commands/discover.js +127 -0
  12. package/dist/cli/commands/discover.js.map +1 -0
  13. package/dist/cli/commands/export.js +20 -0
  14. package/dist/cli/commands/export.js.map +1 -0
  15. package/dist/cli/commands/groups.js +107 -0
  16. package/dist/cli/commands/groups.js.map +1 -0
  17. package/dist/cli/commands/install.js +173 -0
  18. package/dist/cli/commands/install.js.map +1 -0
  19. package/dist/cli/commands/keys.js +91 -0
  20. package/dist/cli/commands/keys.js.map +1 -0
  21. package/dist/cli/commands/login.js +70 -0
  22. package/dist/cli/commands/login.js.map +1 -0
  23. package/dist/cli/commands/servers.js +142 -0
  24. package/dist/cli/commands/servers.js.map +1 -0
  25. package/dist/cli/commands/tools.js +162 -0
  26. package/dist/cli/commands/tools.js.map +1 -0
  27. package/dist/cli/context.js +44 -0
  28. package/dist/cli/context.js.map +1 -0
  29. package/dist/cli/errors.js +19 -0
  30. package/dist/cli/errors.js.map +1 -0
  31. package/dist/cli/help.js +157 -0
  32. package/dist/cli/help.js.map +1 -0
  33. package/dist/cli/http.js +93 -0
  34. package/dist/cli/http.js.map +1 -0
  35. package/dist/cli/main.js +81 -0
  36. package/dist/cli/main.js.map +1 -0
  37. package/dist/cli/output.js +47 -0
  38. package/dist/cli/output.js.map +1 -0
  39. package/dist/cli/parse-args.js +103 -0
  40. package/dist/cli/parse-args.js.map +1 -0
  41. package/dist/cli/profile.js +109 -0
  42. package/dist/cli/profile.js.map +1 -0
  43. package/dist/cli/prompts.js +56 -0
  44. package/dist/cli/prompts.js.map +1 -0
  45. package/dist/controllers/oauthServerController.js +37 -1
  46. package/dist/controllers/oauthServerController.js.map +1 -1
  47. package/dist/dao/ServerDaoDbImpl.js +3 -0
  48. package/dist/dao/ServerDaoDbImpl.js.map +1 -1
  49. package/dist/db/connection.js +48 -4
  50. package/dist/db/connection.js.map +1 -1
  51. package/dist/db/entities/Server.js +4 -0
  52. package/dist/db/entities/Server.js.map +1 -1
  53. package/dist/db/entities/VectorEmbedding.js +2 -5
  54. package/dist/db/entities/VectorEmbedding.js.map +1 -1
  55. package/dist/db/repositories/VectorEmbeddingRepository.js +100 -34
  56. package/dist/db/repositories/VectorEmbeddingRepository.js.map +1 -1
  57. package/dist/services/dataService.js +10 -1
  58. package/dist/services/dataService.js.map +1 -1
  59. package/dist/services/mcpService.js +5 -0
  60. package/dist/services/mcpService.js.map +1 -1
  61. package/dist/services/vectorSearchService.js +16 -3
  62. package/dist/services/vectorSearchService.js.map +1 -1
  63. package/dist/utils/migration.js +1 -0
  64. package/dist/utils/migration.js.map +1 -1
  65. package/dist/utils/serverConfigPersistence.js +5 -0
  66. package/dist/utils/serverConfigPersistence.js.map +1 -1
  67. package/frontend/dist/assets/{ActivityPage-VwilVMvp.js → ActivityPage-DwzGiMh_.js} +2 -2
  68. package/frontend/dist/assets/{ActivityPage-VwilVMvp.js.map → ActivityPage-DwzGiMh_.js.map} +1 -1
  69. package/frontend/dist/assets/Dashboard-BUCJcvk-.js +2 -0
  70. package/frontend/dist/assets/Dashboard-BUCJcvk-.js.map +1 -0
  71. package/frontend/dist/assets/{EndpointCopy-C59moJ3Y.js → EndpointCopy-D5NjDdYi.js} +2 -2
  72. package/frontend/dist/assets/{EndpointCopy-C59moJ3Y.js.map → EndpointCopy-D5NjDdYi.js.map} +1 -1
  73. package/frontend/dist/assets/{GroupsPage-Bhg51kbu.js → GroupsPage-DfLlww4U.js} +2 -2
  74. package/frontend/dist/assets/{GroupsPage-Bhg51kbu.js.map → GroupsPage-DfLlww4U.js.map} +1 -1
  75. package/frontend/dist/assets/{LoginPage-C8RkMoJN.js → LoginPage-DCjqYw_8.js} +2 -2
  76. package/frontend/dist/assets/{LoginPage-C8RkMoJN.js.map → LoginPage-DCjqYw_8.js.map} +1 -1
  77. package/frontend/dist/assets/{LogsPage-HBGNLtyN.js → LogsPage-CTa8kuDf.js} +2 -2
  78. package/frontend/dist/assets/{LogsPage-HBGNLtyN.js.map → LogsPage-CTa8kuDf.js.map} +1 -1
  79. package/frontend/dist/assets/{MarketPage-C5ATZ4WS.js → MarketPage-C2Rh4WJB.js} +2 -2
  80. package/frontend/dist/assets/{MarketPage-C5ATZ4WS.js.map → MarketPage-C2Rh4WJB.js.map} +1 -1
  81. package/frontend/dist/assets/{PromptsPage-DUge8OO4.js → PromptsPage-Dh3qjX3x.js} +2 -2
  82. package/frontend/dist/assets/{PromptsPage-DUge8OO4.js.map → PromptsPage-Dh3qjX3x.js.map} +1 -1
  83. package/frontend/dist/assets/{ResourcesPage-5J3JYGVC.js → ResourcesPage-Bc5ZpCIh.js} +2 -2
  84. package/frontend/dist/assets/{ResourcesPage-5J3JYGVC.js.map → ResourcesPage-Bc5ZpCIh.js.map} +1 -1
  85. package/frontend/dist/assets/ServersPage-hgCbCglG.js +37 -0
  86. package/frontend/dist/assets/ServersPage-hgCbCglG.js.map +1 -0
  87. package/frontend/dist/assets/{SettingsPage-BeLZKC1d.js → SettingsPage-BzNX8mXv.js} +2 -2
  88. package/frontend/dist/assets/{SettingsPage-BeLZKC1d.js.map → SettingsPage-BzNX8mXv.js.map} +1 -1
  89. package/frontend/dist/assets/{StatusDot-DR803YdX.js → StatusDot-CQzailBQ.js} +2 -2
  90. package/frontend/dist/assets/{StatusDot-DR803YdX.js.map → StatusDot-CQzailBQ.js.map} +1 -1
  91. package/frontend/dist/assets/{ToggleGroup-DE8t8Ni4.js → ToggleGroup-CNBBvo3C.js} +2 -2
  92. package/frontend/dist/assets/{ToggleGroup-DE8t8Ni4.js.map → ToggleGroup-CNBBvo3C.js.map} +1 -1
  93. package/frontend/dist/assets/{UsersPage-CMscqAmn.js → UsersPage-C33b7LCM.js} +2 -2
  94. package/frontend/dist/assets/{UsersPage-CMscqAmn.js.map → UsersPage-C33b7LCM.js.map} +1 -1
  95. package/frontend/dist/assets/index-BGiKkKzj.js +3 -0
  96. package/frontend/dist/assets/index-BGiKkKzj.js.map +1 -0
  97. package/frontend/dist/assets/index-D0OIBhmN.css +1 -0
  98. package/frontend/dist/assets/{resourceService-BFMkDDIh.js → resourceService-C6umWRgq.js} +2 -2
  99. package/frontend/dist/assets/{resourceService-BFMkDDIh.js.map → resourceService-C6umWRgq.js.map} +1 -1
  100. package/frontend/dist/assets/{useServerData-BnLmpLAC.js → useServerData-P5In98R4.js} +2 -2
  101. package/frontend/dist/assets/{useServerData-BnLmpLAC.js.map → useServerData-P5In98R4.js.map} +1 -1
  102. package/frontend/dist/assets/useSettingsData-Cz7vKGLE.js +2 -0
  103. package/frontend/dist/assets/{useSettingsData-Cqi9d7Ug.js.map → useSettingsData-Cz7vKGLE.js.map} +1 -1
  104. package/frontend/dist/assets/{variableDetection-BigiltQM.js → variableDetection-DsYuiOB_.js} +3 -3
  105. package/frontend/dist/assets/variableDetection-DsYuiOB_.js.map +1 -0
  106. package/frontend/dist/index.html +2 -2
  107. package/package.json +2 -1
  108. package/frontend/dist/assets/Dashboard-DuBJTbbA.js +0 -2
  109. package/frontend/dist/assets/Dashboard-DuBJTbbA.js.map +0 -1
  110. package/frontend/dist/assets/ServersPage-DtnlfwJF.js +0 -37
  111. package/frontend/dist/assets/ServersPage-DtnlfwJF.js.map +0 -1
  112. package/frontend/dist/assets/index-B9cW2F0H.js +0 -3
  113. package/frontend/dist/assets/index-B9cW2F0H.js.map +0 -1
  114. package/frontend/dist/assets/index-Crcbkt8x.css +0 -1
  115. package/frontend/dist/assets/useSettingsData-Cqi9d7Ug.js +0 -2
  116. package/frontend/dist/assets/variableDetection-BigiltQM.js.map +0 -1
package/README.fr.md CHANGED
@@ -15,6 +15,7 @@ MCPHub facilite la gestion et la mise à l'échelle de plusieurs serveurs MCP (M
15
15
 
16
16
  - **Gestion centralisée** - Surveillez et contrôlez tous les serveurs MCP depuis un tableau de bord unifié
17
17
  - **Routage flexible** - Accédez à tous les serveurs, groupes spécifiques ou serveurs individuels via HTTP/SSE
18
+ - **Visibilité granulaire par groupe** - Contrôlez indépendamment la visibilité des Tools, Prompts et Resources de chaque serveur dans un groupe
18
19
  - **Routage intelligent** - Découverte d'outils propulsée par IA utilisant la recherche sémantique vectorielle ([En savoir plus](https://docs.mcphub.app/features/smart-routing))
19
20
  - **Configuration à chaud** - Ajoutez, supprimez ou mettez à jour les serveurs sans temps d'arrêt
20
21
  - **Support OAuth 2.0** - Modes client et serveur pour une authentification sécurisée ([En savoir plus](https://docs.mcphub.app/features/oauth))
@@ -51,8 +52,8 @@ Créez un fichier `mcp_settings.json` :
51
52
  # Exécutez avec une configuration personnalisée (recommandé)
52
53
  docker run -p 3000:3000 -v ./mcp_settings.json:/app/mcp_settings.json -v ./data:/app/data samanhappy/mcphub
53
54
 
54
- # Ou exécutez avec les paramètres par défaut
55
- docker run -p 3000:3000 samanhappy/mcphub
55
+ # Ou exécutez avec les paramètres par défaut (montez ./data pour préserver l'état entre redémarrages)
56
+ docker run -p 3000:3000 -v ./data:/app/data samanhappy/mcphub
56
57
  ```
57
58
 
58
59
  ### Accéder au tableau de bord
@@ -110,9 +111,10 @@ pnpm dev
110
111
 
111
112
  ## 🔍 Stack technique
112
113
 
113
- - **Backend** : Node.js, Express, TypeScript
114
+ - **Backend** : Node.js, Express, TypeScript (ESM)
114
115
  - **Frontend** : React, Vite, Tailwind CSS
115
- - **Authentification** : JWT & bcrypt
116
+ - **Stockage** : `mcp_settings.json` (par défaut) ; PostgreSQL via TypeORM avec pgvector pour le Smart Routing
117
+ - **Authentification** : JWT + bcrypt pour les comptes locaux ; bearer keys ; serveur OAuth 2.0 intégré (`@node-oauth/oauth2-server`) ; Better Auth optionnel pour GitHub/Google
116
118
  - **Protocole** : Model Context Protocol SDK
117
119
 
118
120
  ## 👥 Contribuer
package/README.md CHANGED
@@ -52,8 +52,8 @@ Create a `mcp_settings.json` file:
52
52
  # Run with custom config (recommended)
53
53
  docker run -p 3000:3000 -v ./mcp_settings.json:/app/mcp_settings.json -v ./data:/app/data samanhappy/mcphub
54
54
 
55
- # Or run with default settings
56
- docker run -p 3000:3000 samanhappy/mcphub
55
+ # Or run with default settings (also mount ./data so credentials and state survive restarts)
56
+ docker run -p 3000:3000 -v ./data:/app/data samanhappy/mcphub
57
57
  ```
58
58
 
59
59
  ### Access Dashboard
@@ -85,6 +85,24 @@ http://localhost:3000/mcp/$smart/{group} # Smart routing within group
85
85
 
86
86
  📖 See [API Reference](https://docs.mcphub.app/api-reference) for detailed endpoint documentation.
87
87
 
88
+ ### Manage From the Terminal
89
+
90
+ The same `mcphub` binary doubles as a CLI for the running hub — no extra install needed.
91
+
92
+ ```bash
93
+ mcphub login --url http://localhost:3000 --username admin
94
+ mcphub servers list
95
+ mcphub servers add fetch --type stdio --command uvx --arg mcp-server-fetch
96
+ mcphub tools list # discover what tools are available
97
+ mcphub tools get fetch_url # see required params + sample command
98
+ mcphub call fetch_url url=https://example.com --json
99
+ mcphub keys create --name ci --access-type all
100
+ ```
101
+
102
+ It also speaks the public marketplace API (`mcphub discover`, `mcphub install ...`) so server lookup and one-command install work against any hub with discovery enabled.
103
+
104
+ 📖 See [CLI Guide](https://docs.mcphub.app/features/cli) for every subcommand, profiles, and CI usage.
105
+
88
106
  ## 📚 Documentation
89
107
 
90
108
  | Topic | Description |
@@ -94,6 +112,7 @@ http://localhost:3000/mcp/$smart/{group} # Smart routing within group
94
112
  | [Database Mode](https://docs.mcphub.app/configuration/database-configuration) | PostgreSQL setup for production |
95
113
  | [OAuth](https://docs.mcphub.app/features/oauth) | OAuth 2.0 client and server setup |
96
114
  | [Smart Routing](https://docs.mcphub.app/features/smart-routing) | AI-powered tool discovery |
115
+ | [CLI Guide](https://docs.mcphub.app/features/cli) | Manage and call the hub from a terminal |
97
116
  | [Docker Setup](https://docs.mcphub.app/configuration/docker-setup) | Docker deployment guide |
98
117
 
99
118
  ## 🧑‍💻 Local Development
@@ -111,9 +130,10 @@ pnpm dev
111
130
 
112
131
  ## 🔍 Tech Stack
113
132
 
114
- - **Backend**: Node.js, Express, TypeScript
133
+ - **Backend**: Node.js, Express, TypeScript (ESM)
115
134
  - **Frontend**: React, Vite, Tailwind CSS
116
- - **Auth**: JWT & bcrypt
135
+ - **Storage**: file-based `mcp_settings.json` by default; PostgreSQL via TypeORM with pgvector for Smart Routing
136
+ - **Auth**: JWT + bcrypt for local accounts; bearer keys; built-in OAuth 2.0 server (`@node-oauth/oauth2-server`); optional Better Auth for GitHub/Google login
117
137
  - **Protocol**: Model Context Protocol SDK
118
138
 
119
139
  ## 👥 Contributing
package/README.zh.md CHANGED
@@ -15,6 +15,7 @@ MCPHub 通过将多个 MCP(Model Context Protocol)服务器组织为灵活
15
15
 
16
16
  - **集中式管理** - 在统一控制台中监控和管理所有 MCP 服务器
17
17
  - **灵活路由** - 通过 HTTP/SSE 访问所有服务器、特定分组或单个服务器
18
+ - **细粒度分组可见性** - 在分组中可独立控制每个服务器的 Tool、Prompt 与 Resource 是否对外暴露
18
19
  - **智能路由** - 基于向量语义搜索的 AI 工具发现 ([了解更多](https://docs.mcphub.app/zh/features/smart-routing))
19
20
  - **热插拔配置** - 无需停机即可添加、移除或更新服务器
20
21
  - **OAuth 2.0 支持** - 客户端和服务端模式,实现安全认证 ([了解更多](https://docs.mcphub.app/zh/features/oauth))
@@ -51,8 +52,8 @@ MCPHub 通过将多个 MCP(Model Context Protocol)服务器组织为灵活
51
52
  # 挂载自定义配置运行(推荐)
52
53
  docker run -p 3000:3000 -v ./mcp_settings.json:/app/mcp_settings.json -v ./data:/app/data samanhappy/mcphub
53
54
 
54
- # 或使用默认配置运行
55
- docker run -p 3000:3000 samanhappy/mcphub
55
+ # 或使用默认配置运行(仍建议挂载 ./data,避免容器删除后数据丢失)
56
+ docker run -p 3000:3000 -v ./data:/app/data samanhappy/mcphub
56
57
  ```
57
58
 
58
59
  ### 访问控制台
@@ -84,6 +85,24 @@ http://localhost:3000/mcp/$smart/{group} # 智能路由(特定分组)
84
85
 
85
86
  📖 查看 [API 参考](https://docs.mcphub.app/zh/api-reference)了解详细的端点文档。
86
87
 
88
+ ### 终端管理
89
+
90
+ `mcphub` 同一个二进制兼任 CLI,无需额外安装。
91
+
92
+ ```bash
93
+ mcphub login --url http://localhost:3000 --username admin
94
+ mcphub servers list
95
+ mcphub servers add fetch --type stdio --command uvx --arg mcp-server-fetch
96
+ mcphub tools list # 看有哪些 tool 可调
97
+ mcphub tools get fetch_url # 看必填参数和样例命令
98
+ mcphub call fetch_url url=https://example.com --json
99
+ mcphub keys create --name ci --access-type all
100
+ ```
101
+
102
+ CLI 同样对接公共市场接口(`mcphub discover`、`mcphub install ...`),可对任意开启了 discovery 的 hub 做检索与一键安装。
103
+
104
+ 📖 查看 [CLI 指南](https://docs.mcphub.app/zh/features/cli)了解全部子命令、profile 管理与 CI 用法。
105
+
87
106
  ## 📚 文档
88
107
 
89
108
  | 主题 | 描述 |
@@ -93,6 +112,7 @@ http://localhost:3000/mcp/$smart/{group} # 智能路由(特定分组)
93
112
  | [数据库模式](https://docs.mcphub.app/zh/configuration/database-configuration) | PostgreSQL 生产环境配置 |
94
113
  | [OAuth](https://docs.mcphub.app/zh/features/oauth) | OAuth 2.0 客户端和服务端配置 |
95
114
  | [智能路由](https://docs.mcphub.app/zh/features/smart-routing) | AI 驱动的工具发现 |
115
+ | [CLI 指南](https://docs.mcphub.app/zh/features/cli) | 终端管理与工具调用 |
96
116
  | [Docker 部署](https://docs.mcphub.app/zh/configuration/docker-setup) | Docker 部署指南 |
97
117
 
98
118
  ## 🧑‍💻 本地开发
@@ -110,9 +130,10 @@ pnpm dev
110
130
 
111
131
  ## 🔍 技术栈
112
132
 
113
- - **后端**:Node.js、Express、TypeScript
133
+ - **后端**:Node.js、Express、TypeScript(ESM)
114
134
  - **前端**:React、Vite、Tailwind CSS
115
- - **认证**:JWT & bcrypt
135
+ - **存储**:默认基于文件的 `mcp_settings.json`;可选 PostgreSQL(TypeORM + pgvector,用于智能路由)
136
+ - **认证**:本地账号使用 JWT + bcrypt;支持 Bearer Key、内置 OAuth 2.0 服务端(`@node-oauth/oauth2-server`),以及可选的 Better Auth(GitHub/Google 一键登录)
116
137
  - **协议**:Model Context Protocol SDK
117
138
 
118
139
  ## 👥 贡献指南
package/bin/cli.js CHANGED
@@ -4,44 +4,51 @@ import path from 'path';
4
4
  import { fileURLToPath, pathToFileURL } from 'url';
5
5
  import fs from 'fs';
6
6
 
7
- // Enable debug logging if needed
8
- // process.env.DEBUG = 'true';
9
-
10
7
  const __filename = fileURLToPath(import.meta.url);
11
8
  const __dirname = path.dirname(__filename);
12
9
 
13
- // Start with more debug information
14
- console.log('📋 MCPHub CLI');
15
- console.log(`📁 CLI script location: ${__dirname}`);
10
+ // Subcommands routed to the CLI dispatcher in dist/cli/main.js. Anything else
11
+ // (including no args) falls through to the legacy server bootstrap so
12
+ // `npx @samanhappy/mcphub` keeps working exactly as before.
13
+ const CLI_COMMANDS = new Set([
14
+ 'login',
15
+ 'logout',
16
+ 'config',
17
+ 'servers',
18
+ 'groups',
19
+ 'keys',
20
+ 'tools',
21
+ 'call',
22
+ 'export',
23
+ 'discover',
24
+ 'install',
25
+ 'help',
26
+ '--help',
27
+ '-h',
28
+ '--version',
29
+ '-v',
30
+ ]);
16
31
 
17
- // The npm package directory structure when installed is:
18
- // node_modules/@samanhappy/mcphub/
19
- // - dist/
20
- // - bin/
21
- // - frontend/dist/
32
+ const argv = process.argv.slice(2);
33
+ const isCliCommand = argv.length > 0 && CLI_COMMANDS.has(argv[0]);
22
34
 
23
- // Get the package root - this is where package.json is located
24
35
  function findPackageRoot() {
25
36
  const isDebug = process.env.DEBUG === 'true';
26
-
27
- // Possible locations for package.json
37
+
28
38
  const possibleRoots = [
29
- // Standard npm package location
30
39
  path.resolve(__dirname, '..'),
31
- // When installed via npx
32
- path.resolve(__dirname, '..', '..', '..')
40
+ path.resolve(__dirname, '..', '..', '..'),
33
41
  ];
34
-
35
- // Special handling for npx
42
+
36
43
  if (process.argv[1] && process.argv[1].includes('_npx')) {
37
44
  const npxDir = path.dirname(process.argv[1]);
38
45
  possibleRoots.unshift(path.resolve(npxDir, '..'));
39
46
  }
40
-
47
+
41
48
  if (isDebug) {
42
49
  console.log('DEBUG: Checking for package.json in:', possibleRoots);
43
50
  }
44
-
51
+
45
52
  for (const root of possibleRoots) {
46
53
  const packageJsonPath = path.join(root, 'package.json');
47
54
  if (fs.existsSync(packageJsonPath)) {
@@ -58,41 +65,48 @@ function findPackageRoot() {
58
65
  }
59
66
  }
60
67
  }
61
-
62
- console.log('⚠️ Could not find package.json, using default path');
68
+
69
+ if (!isCliCommand) {
70
+ console.log('⚠️ Could not find package.json, using default path');
71
+ }
63
72
  return path.resolve(__dirname, '..');
64
73
  }
65
74
 
66
- // Locate and check the frontend distribution
67
- function checkFrontend(packageRoot) {
68
- const isDebug = process.env.DEBUG === 'true';
69
- const frontendDistPath = path.join(packageRoot, 'frontend', 'dist');
70
-
71
- if (isDebug) {
72
- console.log(`DEBUG: Checking frontend at: ${frontendDistPath}`);
75
+ const projectRoot = findPackageRoot();
76
+
77
+ if (isCliCommand) {
78
+ // CLI subcommand path keep stdout clean for --json / pipes.
79
+ const cliEntryPath = path.join(projectRoot, 'dist', 'cli', 'main.js');
80
+ if (!fs.existsSync(cliEntryPath)) {
81
+ console.error('❌ CLI build missing: ' + cliEntryPath);
82
+ console.error('Run "pnpm backend:build" (or "pnpm build") and retry.');
83
+ process.exit(1);
73
84
  }
74
-
75
- if (fs.existsSync(frontendDistPath) && fs.existsSync(path.join(frontendDistPath, 'index.html'))) {
85
+ const cliEntryUrl = pathToFileURL(cliEntryPath).href;
86
+ const mod = await import(cliEntryUrl);
87
+ await mod.runCli(argv);
88
+ } else {
89
+ // Legacy: server bootstrap. Existing console.log banner preserved here so it
90
+ // never leaks into CLI subcommand output.
91
+ console.log('📋 MCPHub CLI');
92
+ console.log(`📁 CLI script location: ${__dirname}`);
93
+ console.log(`📦 Using package root: ${projectRoot}`);
94
+
95
+ const frontendDistPath = path.join(projectRoot, 'frontend', 'dist');
96
+ if (
97
+ fs.existsSync(frontendDistPath) &&
98
+ fs.existsSync(path.join(frontendDistPath, 'index.html'))
99
+ ) {
76
100
  console.log('✅ Frontend distribution found');
77
- return true;
78
101
  } else {
79
102
  console.log('⚠️ Frontend distribution not found at', frontendDistPath);
80
- return false;
81
103
  }
82
- }
83
104
 
84
- const projectRoot = findPackageRoot();
85
- console.log(`📦 Using package root: ${projectRoot}`);
86
-
87
- // Check if frontend exists
88
- checkFrontend(projectRoot);
89
-
90
- // Start the server
91
- console.log('🚀 Starting MCPHub server...');
92
- const entryPath = path.join(projectRoot, 'dist', 'index.js');
93
- // Convert to file:// URL for cross-platform ESM compatibility (required on Windows)
94
- const entryUrl = pathToFileURL(entryPath).href;
95
- import(entryUrl).catch(err => {
96
- console.error('Failed to start MCPHub:', err);
97
- process.exit(1);
98
- });
105
+ console.log('🚀 Starting MCPHub server...');
106
+ const entryPath = path.join(projectRoot, 'dist', 'index.js');
107
+ const entryUrl = pathToFileURL(entryPath).href;
108
+ import(entryUrl).catch((err) => {
109
+ console.error('Failed to start MCPHub:', err);
110
+ process.exit(1);
111
+ });
112
+ }
@@ -0,0 +1,81 @@
1
+ import fs from 'node:fs';
2
+ import { CliUsageError } from './errors.js';
3
+ export function parseCallArguments(argv, options = {}) {
4
+ const args = {};
5
+ const extra = [];
6
+ const reader = options.fs ?? fs;
7
+ for (const token of argv) {
8
+ const eq = token.indexOf('=');
9
+ if (eq <= 0) {
10
+ extra.push(token);
11
+ continue;
12
+ }
13
+ const key = token.slice(0, eq);
14
+ const raw = token.slice(eq + 1);
15
+ if (options.noCoerce) {
16
+ args[key] = raw;
17
+ continue;
18
+ }
19
+ args[key] = coerce(raw, reader);
20
+ }
21
+ return { args, extra };
22
+ }
23
+ function coerce(raw, reader) {
24
+ if (raw === 'null')
25
+ return null;
26
+ if (raw === 'true')
27
+ return true;
28
+ if (raw === 'false')
29
+ return false;
30
+ if (raw.startsWith('@')) {
31
+ const path = raw.slice(1);
32
+ if (!path)
33
+ throw new CliUsageError('@ prefix requires a file path');
34
+ let content;
35
+ try {
36
+ content = reader.readFileSync(path, 'utf8');
37
+ }
38
+ catch (e) {
39
+ throw new CliUsageError(`Failed to read file ${path}: ${e.message}`);
40
+ }
41
+ try {
42
+ return JSON.parse(content);
43
+ }
44
+ catch (e) {
45
+ throw new CliUsageError(`Failed to parse JSON from ${path}: ${e.message}`);
46
+ }
47
+ }
48
+ if (raw.length > 1 &&
49
+ ((raw.startsWith('{') && raw.endsWith('}')) || (raw.startsWith('[') && raw.endsWith(']')))) {
50
+ try {
51
+ return JSON.parse(raw);
52
+ }
53
+ catch {
54
+ // fall through and keep as string — a value that happens to start with
55
+ // a brace but isn't valid JSON is more likely meant literally.
56
+ }
57
+ }
58
+ if (raw.startsWith('"') && raw.endsWith('"') && raw.length >= 2) {
59
+ // Explicit JSON string form — preserve the inner text without coercion.
60
+ try {
61
+ return JSON.parse(raw);
62
+ }
63
+ catch {
64
+ return raw.slice(1, -1);
65
+ }
66
+ }
67
+ if (isNumeric(raw)) {
68
+ return Number(raw);
69
+ }
70
+ return raw;
71
+ }
72
+ function isNumeric(s) {
73
+ if (s === '' || s === '-' || s === '.')
74
+ return false;
75
+ // Preserve identifier-like strings such as zip codes and phone numbers:
76
+ // a leading zero on a multi-digit integer keeps the value as a string.
77
+ if (/^-?0\d/.test(s))
78
+ return false;
79
+ return /^-?(?:\d+\.?\d*|\.\d+)(?:[eE][-+]?\d+)?$/.test(s);
80
+ }
81
+ //# sourceMappingURL=call-arguments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call-arguments.js","sourceRoot":"","sources":["../../src/cli/call-arguments.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ import { CliUsageError } from '../errors.js';
2
+ import { buildClient, resolveTarget } from '../context.js';
3
+ import { extractFlags } from '../parse-args.js';
4
+ import { parseCallArguments } from '../call-arguments.js';
5
+ import { printJson, printLine } from '../output.js';
6
+ export async function run(args, globals, deps = {}) {
7
+ const { positional, flags } = extractFlags(args, {
8
+ valued: ['--group', '--server', '--params-json'],
9
+ boolean: ['--smart', '--no-coerce'],
10
+ });
11
+ const tool = positional.shift();
12
+ if (!tool) {
13
+ throw new CliUsageError('Usage: mcphub call <tool> [key=value ...] [--group <g>|--server <s>|--smart] [--params-json <json>]');
14
+ }
15
+ let params;
16
+ if (flags['--params-json']) {
17
+ try {
18
+ params = JSON.parse(flags['--params-json']);
19
+ }
20
+ catch (e) {
21
+ throw new CliUsageError(`--params-json is not valid JSON: ${e.message}`);
22
+ }
23
+ }
24
+ else {
25
+ const parsed = parseCallArguments(positional, { noCoerce: flags['--no-coerce'] === true });
26
+ params = parsed.args;
27
+ }
28
+ // Routing precedence: --smart > --server > --group > default ($smart).
29
+ // /mcp/:slug? accepts a group name, a server name, or $smart, so --server
30
+ // and --group are different names for the same wire surface. --server is
31
+ // the natural pair for `mcphub tools list`/`tools get` output.
32
+ const group = flags['--smart'] === true
33
+ ? '$smart'
34
+ : flags['--server'] ??
35
+ flags['--group'] ??
36
+ '$smart';
37
+ const client = deps.client ?? buildClient(resolveTarget(globals));
38
+ const body = {
39
+ jsonrpc: '2.0',
40
+ id: 1,
41
+ method: 'tools/call',
42
+ params: { name: tool, arguments: params },
43
+ };
44
+ const response = await client.mcpCall(group, body);
45
+ if (globals.json) {
46
+ printJson(response);
47
+ return;
48
+ }
49
+ if (response.error) {
50
+ throw new CliUsageError(`MCP error ${response.error.code}: ${response.error.message}`);
51
+ }
52
+ printToolResult(response.result);
53
+ }
54
+ function printToolResult(result) {
55
+ if (!result) {
56
+ printLine('(no result)');
57
+ return;
58
+ }
59
+ if (result.isError) {
60
+ printLine('(tool reported an error)');
61
+ }
62
+ if (!Array.isArray(result.content)) {
63
+ printLine(JSON.stringify(result, null, 2));
64
+ return;
65
+ }
66
+ for (const piece of result.content) {
67
+ if (piece.type === 'text' && typeof piece.text === 'string') {
68
+ printLine(piece.text);
69
+ }
70
+ else {
71
+ printLine(JSON.stringify(piece, null, 2));
72
+ }
73
+ }
74
+ }
75
+ //# sourceMappingURL=call.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call.js","sourceRoot":"","sources":["../../../src/cli/commands/call.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,132 @@
1
+ import { CliUsageError } from '../errors.js';
2
+ import { extractFlags } from '../parse-args.js';
3
+ import { deleteProfile, loadCredentials, saveCredentials, setCurrentProfile, setProfile, } from '../profile.js';
4
+ import { bold, dim, green, maskToken, printJson, printLine, printTable } from '../output.js';
5
+ export async function run(args, globals, deps = {}) {
6
+ const sub = args.shift();
7
+ switch (sub) {
8
+ case undefined:
9
+ case 'show':
10
+ return showActive(globals, deps);
11
+ case 'list':
12
+ return list(globals, deps);
13
+ case 'use':
14
+ return use(args, deps);
15
+ case 'set-url':
16
+ return setUrl(args, globals, deps);
17
+ case 'set-token':
18
+ return setToken(args, globals, deps);
19
+ case 'remove':
20
+ return remove(args, deps);
21
+ default:
22
+ throw new CliUsageError(`Unknown config subcommand: ${sub}`);
23
+ }
24
+ }
25
+ function showActive(globals, deps) {
26
+ const creds = (deps.loadCreds ?? loadCredentials)();
27
+ const name = globals.profile || creds.current;
28
+ if (!name || !creds.profiles[name]) {
29
+ printLine(dim('No active profile. Run `mcphub login` to create one.'));
30
+ return;
31
+ }
32
+ const profile = creds.profiles[name];
33
+ if (globals.json) {
34
+ printJson({
35
+ name,
36
+ url: profile.url,
37
+ tokenKind: profile.tokenKind ?? 'jwt',
38
+ tokenMasked: maskToken(profile.token),
39
+ username: profile.username ?? null,
40
+ savedAt: profile.savedAt ?? null,
41
+ });
42
+ return;
43
+ }
44
+ printLine(`${bold('profile')} ${name}`);
45
+ printLine(`${bold('url')} ${profile.url}`);
46
+ printLine(`${bold('tokenKind')} ${profile.tokenKind ?? 'jwt'}`);
47
+ printLine(`${bold('token')} ${maskToken(profile.token)}`);
48
+ if (profile.username)
49
+ printLine(`${bold('username')} ${profile.username}`);
50
+ if (profile.savedAt)
51
+ printLine(`${bold('savedAt')} ${profile.savedAt}`);
52
+ }
53
+ function list(globals, deps) {
54
+ const creds = (deps.loadCreds ?? loadCredentials)();
55
+ const rows = Object.entries(creds.profiles).map(([name, p]) => ({
56
+ name,
57
+ current: name === creds.current ? '*' : '',
58
+ url: p.url,
59
+ tokenKind: p.tokenKind ?? 'jwt',
60
+ token: maskToken(p.token),
61
+ username: p.username ?? '',
62
+ }));
63
+ if (globals.json) {
64
+ printJson({ current: creds.current, profiles: rows });
65
+ return;
66
+ }
67
+ printTable(rows, ['name', 'current', 'url', 'tokenKind', 'token', 'username']);
68
+ }
69
+ function use(args, deps) {
70
+ const name = args[0];
71
+ if (!name)
72
+ throw new CliUsageError('Usage: mcphub config use <name>');
73
+ const load = deps.loadCreds ?? loadCredentials;
74
+ const save = deps.saveCreds ?? saveCredentials;
75
+ const next = setCurrentProfile(load(), name);
76
+ save(next);
77
+ printLine(green(`Active profile set to "${name}".`));
78
+ }
79
+ function setUrl(args, globals, deps) {
80
+ const url = args[0];
81
+ if (!url)
82
+ throw new CliUsageError('Usage: mcphub config set-url <url>');
83
+ const load = deps.loadCreds ?? loadCredentials;
84
+ const save = deps.saveCreds ?? saveCredentials;
85
+ const creds = load();
86
+ const target = globals.profile || creds.current || 'default';
87
+ const existing = creds.profiles[target];
88
+ const next = setProfile(creds, target, {
89
+ url,
90
+ tokenKind: existing?.tokenKind,
91
+ token: existing?.token,
92
+ username: existing?.username,
93
+ });
94
+ save(next);
95
+ printLine(green(`Set url for profile "${target}" to ${url}.`));
96
+ }
97
+ function setToken(args, globals, deps) {
98
+ const { positional, flags } = extractFlags(args, { boolean: ['--bearer'] });
99
+ const token = positional[0];
100
+ if (!token)
101
+ throw new CliUsageError('Usage: mcphub config set-token <token> [--bearer]');
102
+ const load = deps.loadCreds ?? loadCredentials;
103
+ const save = deps.saveCreds ?? saveCredentials;
104
+ const creds = load();
105
+ const target = globals.profile || creds.current;
106
+ if (!target || !creds.profiles[target]) {
107
+ throw new CliUsageError('No profile to update. Run `mcphub login` first or pass --profile.');
108
+ }
109
+ const existing = creds.profiles[target];
110
+ const next = setProfile(creds, target, {
111
+ url: existing.url,
112
+ tokenKind: flags['--bearer'] ? 'bearer' : 'jwt',
113
+ token,
114
+ username: existing.username,
115
+ });
116
+ save(next);
117
+ printLine(green(`Set token for profile "${target}" (${flags['--bearer'] ? 'bearer' : 'jwt'}).`));
118
+ }
119
+ function remove(args, deps) {
120
+ const name = args[0];
121
+ if (!name)
122
+ throw new CliUsageError('Usage: mcphub config remove <name>');
123
+ const load = deps.loadCreds ?? loadCredentials;
124
+ const save = deps.saveCreds ?? saveCredentials;
125
+ const creds = load();
126
+ if (!creds.profiles[name]) {
127
+ throw new CliUsageError(`Profile not found: ${name}`);
128
+ }
129
+ save(deleteProfile(creds, name));
130
+ printLine(green(`Removed profile "${name}".`));
131
+ }
132
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/cli/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAEL,aAAa,EACb,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,UAAU,GACX,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAO7F,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,IAAc,EAAE,OAAoB,EAAE,OAAmB,EAAE;IACnF,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;IACzB,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,SAAS,CAAC;QACf,KAAK,MAAM;YACT,OAAO,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACnC,KAAK,MAAM;YACT,OAAO,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC7B,KAAK,KAAK;YACR,OAAO,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACzB,KAAK,SAAS;YACZ,OAAO,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QACrC,KAAK,WAAW;YACd,OAAO,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QACvC,KAAK,QAAQ;YACX,OAAO,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC5B;YACE,MAAM,IAAI,aAAa,CAAC,8BAA8B,GAAG,EAAE,CAAC,CAAC;IACjE,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,OAAoB,EAAE,IAAgB;IACxD,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,eAAe,CAAC,EAAE,CAAC;IACpD,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC;IAC9C,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,SAAS,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC,CAAC;QACvE,OAAO;IACT,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,SAAS,CAAC;YACR,IAAI;YACJ,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,KAAK;YACrC,WAAW,EAAE,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC;YACrC,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,IAAI;YAClC,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,IAAI;SACjC,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IACD,SAAS,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IAC3C,SAAS,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAClD,SAAS,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,OAAO,CAAC,SAAS,IAAI,KAAK,EAAE,CAAC,CAAC;IACjE,SAAS,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC/D,IAAI,OAAO,CAAC,QAAQ;QAAE,SAAS,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC7E,IAAI,OAAO,CAAC,OAAO;QAAE,SAAS,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;AAC7E,CAAC;AAED,SAAS,IAAI,CAAC,OAAoB,EAAE,IAAgB;IAClD,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,eAAe,CAAC,EAAE,CAAC;IACpD,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9D,IAAI;QACJ,OAAO,EAAE,IAAI,KAAK,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;QAC1C,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,KAAK;QAC/B,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;QACzB,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,EAAE;KAC3B,CAAC,CAAC,CAAC;IACJ,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,OAAO;IACT,CAAC;IACD,UAAU,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC;AACjF,CAAC;AAED,SAAS,GAAG,CAAC,IAAc,EAAE,IAAgB;IAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACrB,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,aAAa,CAAC,iCAAiC,CAAC,CAAC;IACtE,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,IAAI,eAAe,CAAC;IAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,IAAI,eAAe,CAAC;IAC/C,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;IAC7C,IAAI,CAAC,IAAI,CAAC,CAAC;IACX,SAAS,CAAC,KAAK,CAAC,0BAA0B,IAAI,IAAI,CAAC,CAAC,CAAC;AACvD,CAAC;AAED,SAAS,MAAM,CAAC,IAAc,EAAE,OAAoB,EAAE,IAAgB;IACpE,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,aAAa,CAAC,oCAAoC,CAAC,CAAC;IACxE,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,IAAI,eAAe,CAAC;IAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,IAAI,eAAe,CAAC;IAC/C,MAAM,KAAK,GAAG,IAAI,EAAE,CAAC;IACrB,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,IAAI,SAAS,CAAC;IAC7D,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE;QACrC,GAAG;QACH,SAAS,EAAE,QAAQ,EAAE,SAAS;QAC9B,KAAK,EAAE,QAAQ,EAAE,KAAK;QACtB,QAAQ,EAAE,QAAQ,EAAE,QAAQ;KAC7B,CAAC,CAAC;IACH,IAAI,CAAC,IAAI,CAAC,CAAC;IACX,SAAS,CAAC,KAAK,CAAC,wBAAwB,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,QAAQ,CAAC,IAAc,EAAE,OAAoB,EAAE,IAAgB;IACtE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,YAAY,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC5E,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;IAC5B,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,aAAa,CAAC,mDAAmD,CAAC,CAAC;IACzF,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,IAAI,eAAe,CAAC;IAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,IAAI,eAAe,CAAC;IAC/C,MAAM,KAAK,GAAG,IAAI,EAAE,CAAC;IACrB,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC;IAChD,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,aAAa,CAAC,mEAAmE,CAAC,CAAC;IAC/F,CAAC;IACD,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE;QACrC,GAAG,EAAE,QAAQ,CAAC,GAAG;QACjB,SAAS,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK;QAC/C,KAAK;QACL,QAAQ,EAAE,QAAQ,CAAC,QAAQ;KAC5B,CAAC,CAAC;IACH,IAAI,CAAC,IAAI,CAAC,CAAC;IACX,SAAS,CAAC,KAAK,CAAC,0BAA0B,MAAM,MAAM,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;AACnG,CAAC;AAED,SAAS,MAAM,CAAC,IAAc,EAAE,IAAgB;IAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACrB,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,aAAa,CAAC,oCAAoC,CAAC,CAAC;IACzE,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,IAAI,eAAe,CAAC;IAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,IAAI,eAAe,CAAC;IAC/C,MAAM,KAAK,GAAG,IAAI,EAAE,CAAC;IACrB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,aAAa,CAAC,sBAAsB,IAAI,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;IACjC,SAAS,CAAC,KAAK,CAAC,oBAAoB,IAAI,IAAI,CAAC,CAAC,CAAC;AACjD,CAAC"}