modular-studio 0.2.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 (187) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +261 -0
  3. package/dist/assets/graphPopulator-C6jg83nL.js +1 -0
  4. package/dist/assets/index-CXhIX28x.js +634 -0
  5. package/dist/assets/index-CeNF0r-K.css +1 -0
  6. package/dist/assets/jszip.min-BlpRodxc.js +2 -0
  7. package/dist/index.html +16 -0
  8. package/dist/vite.svg +1 -0
  9. package/dist-server/bin/modular-mcp.d.ts +8 -0
  10. package/dist-server/bin/modular-mcp.d.ts.map +1 -0
  11. package/dist-server/bin/modular-mcp.js +158 -0
  12. package/dist-server/bin/modular-mcp.js.map +1 -0
  13. package/dist-server/bin/modular-studio.d.ts +3 -0
  14. package/dist-server/bin/modular-studio.d.ts.map +1 -0
  15. package/dist-server/bin/modular-studio.js +63 -0
  16. package/dist-server/bin/modular-studio.js.map +1 -0
  17. package/dist-server/server/config.d.ts +4 -0
  18. package/dist-server/server/config.d.ts.map +1 -0
  19. package/dist-server/server/config.js +33 -0
  20. package/dist-server/server/config.js.map +1 -0
  21. package/dist-server/server/data/mcp-clients.json +5 -0
  22. package/dist-server/server/index.d.ts +3 -0
  23. package/dist-server/server/index.d.ts.map +1 -0
  24. package/dist-server/server/index.js +174 -0
  25. package/dist-server/server/index.js.map +1 -0
  26. package/dist-server/server/mcp/manager.d.ts +47 -0
  27. package/dist-server/server/mcp/manager.d.ts.map +1 -0
  28. package/dist-server/server/mcp/manager.js +203 -0
  29. package/dist-server/server/mcp/manager.js.map +1 -0
  30. package/dist-server/server/mcp/modular-server.d.ts +55 -0
  31. package/dist-server/server/mcp/modular-server.d.ts.map +1 -0
  32. package/dist-server/server/mcp/modular-server.js +492 -0
  33. package/dist-server/server/mcp/modular-server.js.map +1 -0
  34. package/dist-server/server/mcp/transport.d.ts +29 -0
  35. package/dist-server/server/mcp/transport.d.ts.map +1 -0
  36. package/dist-server/server/mcp/transport.js +61 -0
  37. package/dist-server/server/mcp/transport.js.map +1 -0
  38. package/dist-server/server/routes/agent-sdk.d.ts +3 -0
  39. package/dist-server/server/routes/agent-sdk.d.ts.map +1 -0
  40. package/dist-server/server/routes/agent-sdk.js +99 -0
  41. package/dist-server/server/routes/agent-sdk.js.map +1 -0
  42. package/dist-server/server/routes/agents.d.ts +10 -0
  43. package/dist-server/server/routes/agents.d.ts.map +1 -0
  44. package/dist-server/server/routes/agents.js +61 -0
  45. package/dist-server/server/routes/agents.js.map +1 -0
  46. package/dist-server/server/routes/auth-codex.d.ts +3 -0
  47. package/dist-server/server/routes/auth-codex.d.ts.map +1 -0
  48. package/dist-server/server/routes/auth-codex.js +51 -0
  49. package/dist-server/server/routes/auth-codex.js.map +1 -0
  50. package/dist-server/server/routes/capabilities.d.ts +3 -0
  51. package/dist-server/server/routes/capabilities.d.ts.map +1 -0
  52. package/dist-server/server/routes/capabilities.js +32 -0
  53. package/dist-server/server/routes/capabilities.js.map +1 -0
  54. package/dist-server/server/routes/claude-config.d.ts +3 -0
  55. package/dist-server/server/routes/claude-config.d.ts.map +1 -0
  56. package/dist-server/server/routes/claude-config.js +146 -0
  57. package/dist-server/server/routes/claude-config.js.map +1 -0
  58. package/dist-server/server/routes/connectors.d.ts +12 -0
  59. package/dist-server/server/routes/connectors.d.ts.map +1 -0
  60. package/dist-server/server/routes/connectors.js +325 -0
  61. package/dist-server/server/routes/connectors.js.map +1 -0
  62. package/dist-server/server/routes/embeddings.d.ts +6 -0
  63. package/dist-server/server/routes/embeddings.d.ts.map +1 -0
  64. package/dist-server/server/routes/embeddings.js +130 -0
  65. package/dist-server/server/routes/embeddings.js.map +1 -0
  66. package/dist-server/server/routes/health.d.ts +9 -0
  67. package/dist-server/server/routes/health.d.ts.map +1 -0
  68. package/dist-server/server/routes/health.js +284 -0
  69. package/dist-server/server/routes/health.js.map +1 -0
  70. package/dist-server/server/routes/knowledge.d.ts +3 -0
  71. package/dist-server/server/routes/knowledge.d.ts.map +1 -0
  72. package/dist-server/server/routes/knowledge.js +534 -0
  73. package/dist-server/server/routes/knowledge.js.map +1 -0
  74. package/dist-server/server/routes/llm.d.ts +3 -0
  75. package/dist-server/server/routes/llm.d.ts.map +1 -0
  76. package/dist-server/server/routes/llm.js +200 -0
  77. package/dist-server/server/routes/llm.js.map +1 -0
  78. package/dist-server/server/routes/mcp-oauth.d.ts +12 -0
  79. package/dist-server/server/routes/mcp-oauth.d.ts.map +1 -0
  80. package/dist-server/server/routes/mcp-oauth.js +137 -0
  81. package/dist-server/server/routes/mcp-oauth.js.map +1 -0
  82. package/dist-server/server/routes/mcp.d.ts +3 -0
  83. package/dist-server/server/routes/mcp.d.ts.map +1 -0
  84. package/dist-server/server/routes/mcp.js +177 -0
  85. package/dist-server/server/routes/mcp.js.map +1 -0
  86. package/dist-server/server/routes/pipeline.d.ts +45 -0
  87. package/dist-server/server/routes/pipeline.d.ts.map +1 -0
  88. package/dist-server/server/routes/pipeline.js +483 -0
  89. package/dist-server/server/routes/pipeline.js.map +1 -0
  90. package/dist-server/server/routes/providers.d.ts +3 -0
  91. package/dist-server/server/routes/providers.d.ts.map +1 -0
  92. package/dist-server/server/routes/providers.js +204 -0
  93. package/dist-server/server/routes/providers.js.map +1 -0
  94. package/dist-server/server/routes/qualification.d.ts +3 -0
  95. package/dist-server/server/routes/qualification.d.ts.map +1 -0
  96. package/dist-server/server/routes/qualification.js +105 -0
  97. package/dist-server/server/routes/qualification.js.map +1 -0
  98. package/dist-server/server/routes/repo-index.d.ts +4 -0
  99. package/dist-server/server/routes/repo-index.d.ts.map +1 -0
  100. package/dist-server/server/routes/repo-index.js +318 -0
  101. package/dist-server/server/routes/repo-index.js.map +1 -0
  102. package/dist-server/server/routes/runtime.d.ts +3 -0
  103. package/dist-server/server/routes/runtime.d.ts.map +1 -0
  104. package/dist-server/server/routes/runtime.js +122 -0
  105. package/dist-server/server/routes/runtime.js.map +1 -0
  106. package/dist-server/server/routes/skills-search.d.ts +3 -0
  107. package/dist-server/server/routes/skills-search.d.ts.map +1 -0
  108. package/dist-server/server/routes/skills-search.js +198 -0
  109. package/dist-server/server/routes/skills-search.js.map +1 -0
  110. package/dist-server/server/routes/worktrees.d.ts +3 -0
  111. package/dist-server/server/routes/worktrees.d.ts.map +1 -0
  112. package/dist-server/server/routes/worktrees.js +70 -0
  113. package/dist-server/server/routes/worktrees.js.map +1 -0
  114. package/dist-server/server/services/__tests__/embeddingService.test.d.ts +5 -0
  115. package/dist-server/server/services/__tests__/embeddingService.test.d.ts.map +1 -0
  116. package/dist-server/server/services/__tests__/embeddingService.test.js +233 -0
  117. package/dist-server/server/services/__tests__/embeddingService.test.js.map +1 -0
  118. package/dist-server/server/services/agentRunner.d.ts +46 -0
  119. package/dist-server/server/services/agentRunner.d.ts.map +1 -0
  120. package/dist-server/server/services/agentRunner.js +295 -0
  121. package/dist-server/server/services/agentRunner.js.map +1 -0
  122. package/dist-server/server/services/agentStore.d.ts +40 -0
  123. package/dist-server/server/services/agentStore.d.ts.map +1 -0
  124. package/dist-server/server/services/agentStore.js +62 -0
  125. package/dist-server/server/services/agentStore.js.map +1 -0
  126. package/dist-server/server/services/contentStore.d.ts +32 -0
  127. package/dist-server/server/services/contentStore.d.ts.map +1 -0
  128. package/dist-server/server/services/contentStore.js +68 -0
  129. package/dist-server/server/services/contentStore.js.map +1 -0
  130. package/dist-server/server/services/embeddingService.d.ts +53 -0
  131. package/dist-server/server/services/embeddingService.d.ts.map +1 -0
  132. package/dist-server/server/services/embeddingService.js +199 -0
  133. package/dist-server/server/services/embeddingService.js.map +1 -0
  134. package/dist-server/server/services/factExtractor.d.ts +14 -0
  135. package/dist-server/server/services/factExtractor.d.ts.map +1 -0
  136. package/dist-server/server/services/factExtractor.js +126 -0
  137. package/dist-server/server/services/factExtractor.js.map +1 -0
  138. package/dist-server/server/services/githubIndexer.d.ts +59 -0
  139. package/dist-server/server/services/githubIndexer.d.ts.map +1 -0
  140. package/dist-server/server/services/githubIndexer.js +183 -0
  141. package/dist-server/server/services/githubIndexer.js.map +1 -0
  142. package/dist-server/server/services/mcpOAuth.d.ts +32 -0
  143. package/dist-server/server/services/mcpOAuth.d.ts.map +1 -0
  144. package/dist-server/server/services/mcpOAuth.js +264 -0
  145. package/dist-server/server/services/mcpOAuth.js.map +1 -0
  146. package/dist-server/server/services/memoryScorer.d.ts +19 -0
  147. package/dist-server/server/services/memoryScorer.d.ts.map +1 -0
  148. package/dist-server/server/services/memoryScorer.js +147 -0
  149. package/dist-server/server/services/memoryScorer.js.map +1 -0
  150. package/dist-server/server/services/repoIndexer.d.ts +91 -0
  151. package/dist-server/server/services/repoIndexer.d.ts.map +1 -0
  152. package/dist-server/server/services/repoIndexer.js +512 -0
  153. package/dist-server/server/services/repoIndexer.js.map +1 -0
  154. package/dist-server/server/services/teamRunner.d.ts +39 -0
  155. package/dist-server/server/services/teamRunner.d.ts.map +1 -0
  156. package/dist-server/server/services/teamRunner.js +76 -0
  157. package/dist-server/server/services/teamRunner.js.map +1 -0
  158. package/dist-server/server/services/worktreeManager.d.ts +27 -0
  159. package/dist-server/server/services/worktreeManager.d.ts.map +1 -0
  160. package/dist-server/server/services/worktreeManager.js +107 -0
  161. package/dist-server/server/services/worktreeManager.js.map +1 -0
  162. package/dist-server/server/types.d.ts +30 -0
  163. package/dist-server/server/types.d.ts.map +1 -0
  164. package/dist-server/server/types.js +2 -0
  165. package/dist-server/server/types.js.map +1 -0
  166. package/dist-server/server/utils/pathSecurity.d.ts +34 -0
  167. package/dist-server/server/utils/pathSecurity.d.ts.map +1 -0
  168. package/dist-server/server/utils/pathSecurity.js +78 -0
  169. package/dist-server/server/utils/pathSecurity.js.map +1 -0
  170. package/dist-server/src/services/budgetAllocator.d.ts +37 -0
  171. package/dist-server/src/services/budgetAllocator.d.ts.map +1 -0
  172. package/dist-server/src/services/budgetAllocator.js +120 -0
  173. package/dist-server/src/services/budgetAllocator.js.map +1 -0
  174. package/dist-server/src/services/contradictionDetector.d.ts +18 -0
  175. package/dist-server/src/services/contradictionDetector.d.ts.map +1 -0
  176. package/dist-server/src/services/contradictionDetector.js +111 -0
  177. package/dist-server/src/services/contradictionDetector.js.map +1 -0
  178. package/dist-server/src/services/treeIndexer.d.ts +91 -0
  179. package/dist-server/src/services/treeIndexer.d.ts.map +1 -0
  180. package/dist-server/src/services/treeIndexer.js +289 -0
  181. package/dist-server/src/services/treeIndexer.js.map +1 -0
  182. package/dist-server/src/store/knowledgeBase.d.ts +130 -0
  183. package/dist-server/src/store/knowledgeBase.d.ts.map +1 -0
  184. package/dist-server/src/store/knowledgeBase.js +299 -0
  185. package/dist-server/src/store/knowledgeBase.js.map +1 -0
  186. package/dist-server/tsconfig.server.tsbuildinfo +1 -0
  187. package/package.json +92 -0
@@ -0,0 +1,325 @@
1
+ /**
2
+ * Connector Auth Routes — OAuth and API key management for service connectors.
3
+ *
4
+ * Supports:
5
+ * - API key storage (encrypted at rest via config)
6
+ * - OAuth flow initiation + callback
7
+ * - Connection testing
8
+ * - Status checks
9
+ */
10
+ import { Router } from 'express';
11
+ import { readConfig, writeConfig } from '../config.js';
12
+ const router = Router();
13
+ // OAuth configs for supported services
14
+ const OAUTH_CONFIGS = {
15
+ notion: {
16
+ service: 'notion',
17
+ authUrl: 'https://api.notion.com/v1/oauth/authorize',
18
+ tokenUrl: 'https://api.notion.com/v1/oauth/token',
19
+ scopes: [],
20
+ redirectUri: 'http://localhost:4800/api/connectors/oauth/callback',
21
+ },
22
+ github: {
23
+ service: 'github',
24
+ authUrl: 'https://github.com/login/oauth/authorize',
25
+ tokenUrl: 'https://github.com/login/oauth/access_token',
26
+ scopes: ['repo', 'read:org'],
27
+ redirectUri: 'http://localhost:4800/api/connectors/oauth/callback',
28
+ },
29
+ slack: {
30
+ service: 'slack',
31
+ authUrl: 'https://slack.com/oauth/v2/authorize',
32
+ tokenUrl: 'https://slack.com/api/oauth.v2.access',
33
+ scopes: ['channels:read', 'channels:history', 'chat:write'],
34
+ redirectUri: 'http://localhost:4800/api/connectors/oauth/callback',
35
+ },
36
+ 'google-drive': {
37
+ service: 'google-drive',
38
+ authUrl: 'https://accounts.google.com/o/oauth2/v2/auth',
39
+ tokenUrl: 'https://oauth2.googleapis.com/token',
40
+ scopes: ['https://www.googleapis.com/auth/drive.readonly'],
41
+ redirectUri: 'http://localhost:4800/api/connectors/oauth/callback',
42
+ },
43
+ };
44
+ // API key test endpoints
45
+ const API_KEY_TEST = {
46
+ notion: {
47
+ url: 'https://api.notion.com/v1/users/me',
48
+ headers: (key) => ({ 'Authorization': `Bearer ${key}`, 'Notion-Version': '2022-06-28' }),
49
+ },
50
+ github: {
51
+ url: 'https://api.github.com/user',
52
+ headers: (key) => ({ 'Authorization': `Bearer ${key}`, 'Accept': 'application/vnd.github+json' }),
53
+ },
54
+ hubspot: {
55
+ url: 'https://api.hubapi.com/crm/v3/objects/contacts?limit=1',
56
+ headers: (key) => ({ 'Authorization': `Bearer ${key}` }),
57
+ },
58
+ slack: {
59
+ url: 'https://slack.com/api/auth.test',
60
+ headers: (key) => ({ 'Authorization': `Bearer ${key}` }),
61
+ },
62
+ };
63
+ // ── Helper: load/save connector auth ──
64
+ function loadAuth() {
65
+ const config = readConfig();
66
+ return config.connectorAuth || {};
67
+ }
68
+ function saveAuth(auth) {
69
+ const config = readConfig();
70
+ config.connectorAuth = auth;
71
+ writeConfig(config);
72
+ }
73
+ // ── Routes ──
74
+ /**
75
+ * GET /api/connectors/auth
76
+ * List all connector auth statuses.
77
+ */
78
+ router.get('/auth', (_req, res) => {
79
+ const auth = loadAuth();
80
+ // Strip sensitive tokens from response
81
+ const safe = Object.fromEntries(Object.entries(auth).map(([k, v]) => [k, {
82
+ service: v.service,
83
+ method: v.method,
84
+ status: v.status,
85
+ hasApiKey: !!v.apiKey,
86
+ hasOAuth: !!v.oauthTokens?.accessToken,
87
+ lastChecked: v.lastChecked,
88
+ }]));
89
+ res.json({ status: 'ok', data: safe });
90
+ });
91
+ /**
92
+ * POST /api/connectors/auth/api-key
93
+ * Body: { service: string, apiKey: string }
94
+ * Store and test an API key.
95
+ */
96
+ router.post('/auth/api-key', async (req, res) => {
97
+ const { service, apiKey } = req.body;
98
+ if (!service || !apiKey) {
99
+ res.status(400).json({ status: 'error', error: 'Missing service or apiKey' });
100
+ return;
101
+ }
102
+ // Test the key
103
+ const testConfig = API_KEY_TEST[service];
104
+ let testResult = { ok: false };
105
+ if (testConfig) {
106
+ try {
107
+ const resp = await fetch(testConfig.url, { headers: testConfig.headers(apiKey) });
108
+ if (resp.ok) {
109
+ const data = await resp.json();
110
+ testResult = { ok: true, user: data.name || data.login || data.user?.name || data.ok?.toString() };
111
+ }
112
+ else {
113
+ testResult = { ok: false, error: `${resp.status} ${resp.statusText}` };
114
+ }
115
+ }
116
+ catch (err) {
117
+ testResult = { ok: false, error: err instanceof Error ? err.message : 'Test failed' };
118
+ }
119
+ }
120
+ else {
121
+ // No test endpoint — accept the key
122
+ testResult = { ok: true };
123
+ }
124
+ // Save
125
+ const auth = loadAuth();
126
+ auth[service] = {
127
+ service,
128
+ method: 'api-key',
129
+ apiKey,
130
+ status: testResult.ok ? 'connected' : 'configured',
131
+ lastChecked: Date.now(),
132
+ };
133
+ saveAuth(auth);
134
+ // Also inject into MCP server env if a matching server exists
135
+ injectApiKeyToMcp(service, apiKey);
136
+ res.json({
137
+ status: 'ok',
138
+ data: {
139
+ service,
140
+ testResult,
141
+ connectorStatus: testResult.ok ? 'connected' : 'configured',
142
+ },
143
+ });
144
+ });
145
+ /**
146
+ * Inject API key into matching MCP server's env vars.
147
+ */
148
+ function injectApiKeyToMcp(service, apiKey) {
149
+ const envMap = {
150
+ notion: 'NOTION_API_KEY',
151
+ github: 'GITHUB_TOKEN',
152
+ hubspot: 'HUBSPOT_ACCESS_TOKEN',
153
+ slack: 'SLACK_BOT_TOKEN',
154
+ 'google-drive': 'GOOGLE_API_KEY',
155
+ granola: 'GRANOLA_API_KEY',
156
+ };
157
+ const envKey = envMap[service];
158
+ if (!envKey)
159
+ return;
160
+ const config = readConfig();
161
+ for (const server of config.mcpServers) {
162
+ const id = server.id.toLowerCase();
163
+ if (id.includes(service) || id.includes(service.replace('-', ''))) {
164
+ server.env = { ...server.env, [envKey]: apiKey };
165
+ }
166
+ }
167
+ writeConfig(config);
168
+ }
169
+ /**
170
+ * GET /api/connectors/oauth/start/:service
171
+ * Initiate OAuth flow — returns redirect URL.
172
+ */
173
+ router.get('/oauth/start/:service', (req, res) => {
174
+ const { service } = req.params;
175
+ const { clientId, clientSecret } = req.query;
176
+ const oauthConfig = OAUTH_CONFIGS[service];
177
+ if (!oauthConfig) {
178
+ res.status(400).json({ status: 'error', error: `OAuth not supported for "${service}"` });
179
+ return;
180
+ }
181
+ if (!clientId) {
182
+ res.status(400).json({ status: 'error', error: 'clientId required as query param' });
183
+ return;
184
+ }
185
+ // Store client credentials temporarily for callback
186
+ const config = readConfig();
187
+ config._oauthPending = { service, clientId, clientSecret: clientSecret || '' };
188
+ writeConfig(config);
189
+ const params = new URLSearchParams({
190
+ client_id: clientId,
191
+ redirect_uri: oauthConfig.redirectUri,
192
+ response_type: 'code',
193
+ ...(oauthConfig.scopes.length > 0 ? { scope: oauthConfig.scopes.join(' ') } : {}),
194
+ state: service,
195
+ });
196
+ // Notion uses different param name
197
+ if (service === 'notion') {
198
+ params.set('owner', 'user');
199
+ }
200
+ const redirectUrl = `${oauthConfig.authUrl}?${params.toString()}`;
201
+ res.json({ status: 'ok', data: { redirectUrl } });
202
+ });
203
+ /**
204
+ * GET /api/connectors/oauth/callback
205
+ * OAuth callback — exchanges code for tokens.
206
+ */
207
+ router.get('/oauth/callback', async (req, res) => {
208
+ const { code, state: service } = req.query;
209
+ if (!code || !service) {
210
+ res.status(400).send('Missing code or state');
211
+ return;
212
+ }
213
+ const oauthConfig = OAUTH_CONFIGS[service];
214
+ if (!oauthConfig) {
215
+ res.status(400).send(`Unknown service: ${service}`);
216
+ return;
217
+ }
218
+ const config = readConfig();
219
+ const pending = config._oauthPending;
220
+ if (!pending) {
221
+ res.status(400).send('No pending OAuth flow');
222
+ return;
223
+ }
224
+ try {
225
+ // Exchange code for token
226
+ const tokenResp = await fetch(oauthConfig.tokenUrl, {
227
+ method: 'POST',
228
+ headers: {
229
+ 'Content-Type': service === 'notion' ? 'application/json' : 'application/x-www-form-urlencoded',
230
+ 'Accept': 'application/json',
231
+ ...(service === 'notion' ? { 'Authorization': `Basic ${Buffer.from(`${pending.clientId}:${pending.clientSecret}`).toString('base64')}` } : {}),
232
+ },
233
+ body: service === 'notion'
234
+ ? JSON.stringify({ grant_type: 'authorization_code', code, redirect_uri: oauthConfig.redirectUri })
235
+ : new URLSearchParams({
236
+ client_id: pending.clientId,
237
+ client_secret: pending.clientSecret,
238
+ code,
239
+ redirect_uri: oauthConfig.redirectUri,
240
+ grant_type: 'authorization_code',
241
+ }).toString(),
242
+ });
243
+ const tokenData = await tokenResp.json();
244
+ if (!tokenData.access_token) {
245
+ res.status(400).send(`Token exchange failed: ${JSON.stringify(tokenData)}`);
246
+ return;
247
+ }
248
+ // Save tokens
249
+ const auth = loadAuth();
250
+ auth[service] = {
251
+ service,
252
+ method: 'oauth',
253
+ oauthTokens: {
254
+ accessToken: tokenData.access_token,
255
+ refreshToken: tokenData.refresh_token,
256
+ expiresAt: tokenData.expires_in ? Date.now() + tokenData.expires_in * 1000 : undefined,
257
+ },
258
+ status: 'connected',
259
+ lastChecked: Date.now(),
260
+ };
261
+ saveAuth(auth);
262
+ // Inject token into MCP env
263
+ injectApiKeyToMcp(service, tokenData.access_token);
264
+ // Clean up pending state
265
+ delete config._oauthPending;
266
+ writeConfig(config);
267
+ // Return success page that closes itself
268
+ res.send(`<!DOCTYPE html><html><body>
269
+ <h2>Connected to ${service}!</h2>
270
+ <p>You can close this window.</p>
271
+ <script>setTimeout(() => window.close(), 2000);</script>
272
+ </body></html>`);
273
+ }
274
+ catch (err) {
275
+ res.status(500).send(`OAuth error: ${err instanceof Error ? err.message : 'Unknown'}`);
276
+ }
277
+ });
278
+ /**
279
+ * POST /api/connectors/auth/test/:service
280
+ * Test an existing connection.
281
+ */
282
+ router.post('/auth/test/:service', async (req, res) => {
283
+ const { service } = req.params;
284
+ const auth = loadAuth();
285
+ const connAuth = auth[service];
286
+ if (!connAuth) {
287
+ res.json({ status: 'ok', data: { service, connected: false, error: 'Not configured' } });
288
+ return;
289
+ }
290
+ const apiKey = connAuth.apiKey || connAuth.oauthTokens?.accessToken;
291
+ if (!apiKey) {
292
+ res.json({ status: 'ok', data: { service, connected: false, error: 'No credentials' } });
293
+ return;
294
+ }
295
+ const testConfig = API_KEY_TEST[service];
296
+ if (!testConfig) {
297
+ res.json({ status: 'ok', data: { service, connected: true, note: 'No test endpoint' } });
298
+ return;
299
+ }
300
+ try {
301
+ const resp = await fetch(testConfig.url, { headers: testConfig.headers(apiKey) });
302
+ const ok = resp.ok;
303
+ // Update status
304
+ connAuth.status = ok ? 'connected' : 'expired';
305
+ connAuth.lastChecked = Date.now();
306
+ saveAuth(auth);
307
+ res.json({ status: 'ok', data: { service, connected: ok, httpStatus: resp.status } });
308
+ }
309
+ catch (err) {
310
+ res.json({ status: 'ok', data: { service, connected: false, error: err instanceof Error ? err.message : 'Test failed' } });
311
+ }
312
+ });
313
+ /**
314
+ * DELETE /api/connectors/auth/:service
315
+ * Remove stored credentials.
316
+ */
317
+ router.delete('/auth/:service', (req, res) => {
318
+ const { service } = req.params;
319
+ const auth = loadAuth();
320
+ delete auth[service];
321
+ saveAuth(auth);
322
+ res.json({ status: 'ok' });
323
+ });
324
+ export default router;
325
+ //# sourceMappingURL=connectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connectors.js","sourceRoot":"","sources":["../../../server/routes/connectors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Express routes for the embedding service API
3
+ */
4
+ declare const router: import("express-serve-static-core").Router;
5
+ export default router;
6
+ //# sourceMappingURL=embeddings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embeddings.d.ts","sourceRoot":"","sources":["../../../server/routes/embeddings.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,QAAA,MAAM,MAAM,4CAAW,CAAC;AA2IxB,eAAe,MAAM,CAAC"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Express routes for the embedding service API
3
+ */
4
+ import { Router } from 'express';
5
+ import embeddingService from '../services/embeddingService.js';
6
+ const router = Router();
7
+ /**
8
+ * GET /health - Health check endpoint
9
+ * Returns: { ready: boolean, model: string, cacheSize: number }
10
+ */
11
+ router.get('/health', async (_req, res) => {
12
+ try {
13
+ const health = embeddingService.getHealth();
14
+ res.json(health);
15
+ }
16
+ catch (error) {
17
+ const message = error instanceof Error ? error.message : 'Unknown error';
18
+ res.status(500).json({
19
+ ready: false,
20
+ model: 'Xenova/all-MiniLM-L6-v2',
21
+ cacheSize: 0,
22
+ error: message
23
+ });
24
+ }
25
+ });
26
+ /**
27
+ * POST /embed - Generate embeddings for text(s)
28
+ * Body: { texts: string[] }
29
+ * Returns: { embeddings: number[][] }
30
+ */
31
+ router.post('/embed', async (req, res) => {
32
+ try {
33
+ const { texts } = req.body;
34
+ if (!texts || !Array.isArray(texts)) {
35
+ return res.status(400).json({
36
+ error: 'Request body must contain a "texts" array'
37
+ });
38
+ }
39
+ if (texts.length === 0) {
40
+ return res.json({ embeddings: [] });
41
+ }
42
+ if (texts.length > 100) {
43
+ return res.status(400).json({
44
+ error: 'Maximum 100 texts per request'
45
+ });
46
+ }
47
+ // Validate that all texts are non-empty strings
48
+ for (let i = 0; i < texts.length; i++) {
49
+ if (typeof texts[i] !== 'string') {
50
+ return res.status(400).json({
51
+ error: `Text at index ${i} must be a string`
52
+ });
53
+ }
54
+ if (texts[i].trim().length === 0) {
55
+ return res.status(400).json({
56
+ error: `Text at index ${i} cannot be empty`
57
+ });
58
+ }
59
+ }
60
+ // Generate embeddings
61
+ const embeddings = await embeddingService.embedBatch(texts);
62
+ res.json({ embeddings });
63
+ }
64
+ catch (error) {
65
+ console.error('[Embedding API] Error:', error);
66
+ const message = error instanceof Error ? error.message : 'Unknown error';
67
+ res.status(500).json({ error: message });
68
+ }
69
+ });
70
+ /**
71
+ * POST /similarity - Compute cosine similarity between two vectors
72
+ * Body: { a: number[], b: number[] }
73
+ * Returns: { similarity: number }
74
+ */
75
+ router.post('/similarity', async (req, res) => {
76
+ try {
77
+ const { a, b } = req.body;
78
+ if (!Array.isArray(a) || !Array.isArray(b)) {
79
+ return res.status(400).json({
80
+ error: 'Both "a" and "b" must be arrays'
81
+ });
82
+ }
83
+ if (a.length !== b.length) {
84
+ return res.status(400).json({
85
+ error: 'Vectors must have the same length'
86
+ });
87
+ }
88
+ const similarity = embeddingService.similarity(a, b);
89
+ res.json({ similarity });
90
+ }
91
+ catch (error) {
92
+ console.error('[Embedding API] Similarity error:', error);
93
+ const message = error instanceof Error ? error.message : 'Unknown error';
94
+ res.status(500).json({ error: message });
95
+ }
96
+ });
97
+ /**
98
+ * POST /search - Find nearest vectors in a corpus
99
+ * Body: { query: number[], corpus: number[][], k?: number }
100
+ * Returns: { results: Array<{index: number, score: number}> }
101
+ */
102
+ router.post('/search', async (req, res) => {
103
+ try {
104
+ const { query, corpus, k = 10 } = req.body;
105
+ if (!Array.isArray(query)) {
106
+ return res.status(400).json({
107
+ error: 'Query must be an array'
108
+ });
109
+ }
110
+ if (!Array.isArray(corpus)) {
111
+ return res.status(400).json({
112
+ error: 'Corpus must be an array'
113
+ });
114
+ }
115
+ if (typeof k !== 'number' || k < 1 || k > 1000) {
116
+ return res.status(400).json({
117
+ error: 'k must be a number between 1 and 1000'
118
+ });
119
+ }
120
+ const results = embeddingService.nearestK(query, corpus, k);
121
+ res.json({ results });
122
+ }
123
+ catch (error) {
124
+ console.error('[Embedding API] Search error:', error);
125
+ const message = error instanceof Error ? error.message : 'Unknown error';
126
+ res.status(500).json({ error: message });
127
+ }
128
+ });
129
+ export default router;
130
+ //# sourceMappingURL=embeddings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embeddings.js","sourceRoot":"","sources":["../../../server/routes/embeddings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Health Routes — Active probing for MCP servers and skills
3
+ *
4
+ * MCP: Connects if needed, lists tools, measures latency, returns status.
5
+ * Skills: Checks for updates, runs basic security audit.
6
+ */
7
+ declare const router: import("express-serve-static-core").Router;
8
+ export default router;
9
+ //# sourceMappingURL=health.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../../server/routes/health.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,QAAA,MAAM,MAAM,4CAAW,CAAC;AAyTxB,eAAe,MAAM,CAAC"}