@geminilight/mindos 0.6.71 → 0.6.73

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 (227) hide show
  1. package/_standalone/.mindos-build-version +1 -1
  2. package/_standalone/.next/BUILD_ID +1 -1
  3. package/_standalone/.next/app-path-routes-manifest.json +27 -27
  4. package/_standalone/.next/build-manifest.json +3 -3
  5. package/_standalone/.next/cache/.previewinfo +1 -1
  6. package/_standalone/.next/cache/.rscinfo +1 -1
  7. package/_standalone/.next/cache/config.json +3 -3
  8. package/_standalone/.next/prerender-manifest.json +3 -3
  9. package/_standalone/.next/react-loadable-manifest.json +4 -4
  10. package/_standalone/.next/server/app/.well-known/agent-card.json/route_client-reference-manifest.js +1 -1
  11. package/_standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  12. package/_standalone/.next/server/app/_global-error.html +2 -2
  13. package/_standalone/.next/server/app/_global-error.rsc +1 -1
  14. package/_standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  15. package/_standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  16. package/_standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  17. package/_standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  18. package/_standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  19. package/_standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  20. package/_standalone/.next/server/app/_not-found/page.js +1 -1
  21. package/_standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  22. package/_standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  23. package/_standalone/.next/server/app/agents/[agentKey]/page.js +1 -1
  24. package/_standalone/.next/server/app/agents/[agentKey]/page.js.nft.json +1 -1
  25. package/_standalone/.next/server/app/agents/[agentKey]/page_client-reference-manifest.js +1 -1
  26. package/_standalone/.next/server/app/agents/page.js +1 -1
  27. package/_standalone/.next/server/app/agents/page.js.nft.json +1 -1
  28. package/_standalone/.next/server/app/agents/page_client-reference-manifest.js +1 -1
  29. package/_standalone/.next/server/app/api/a2a/agents/route_client-reference-manifest.js +1 -1
  30. package/_standalone/.next/server/app/api/a2a/delegations/route_client-reference-manifest.js +1 -1
  31. package/_standalone/.next/server/app/api/a2a/discover/route_client-reference-manifest.js +1 -1
  32. package/_standalone/.next/server/app/api/a2a/route_client-reference-manifest.js +1 -1
  33. package/_standalone/.next/server/app/api/acp/config/route_client-reference-manifest.js +1 -1
  34. package/_standalone/.next/server/app/api/acp/detect/route_client-reference-manifest.js +1 -1
  35. package/_standalone/.next/server/app/api/acp/install/route_client-reference-manifest.js +1 -1
  36. package/_standalone/.next/server/app/api/acp/registry/route_client-reference-manifest.js +1 -1
  37. package/_standalone/.next/server/app/api/acp/session/route_client-reference-manifest.js +1 -1
  38. package/_standalone/.next/server/app/api/agent-activity/route_client-reference-manifest.js +1 -1
  39. package/_standalone/.next/server/app/api/agents/copy-skill/route_client-reference-manifest.js +1 -1
  40. package/_standalone/.next/server/app/api/agents/custom/detect/route_client-reference-manifest.js +1 -1
  41. package/_standalone/.next/server/app/api/agents/custom/route_client-reference-manifest.js +1 -1
  42. package/_standalone/.next/server/app/api/ask/route_client-reference-manifest.js +1 -1
  43. package/_standalone/.next/server/app/api/ask-sessions/route_client-reference-manifest.js +1 -1
  44. package/_standalone/.next/server/app/api/auth/route_client-reference-manifest.js +1 -1
  45. package/_standalone/.next/server/app/api/backlinks/route_client-reference-manifest.js +1 -1
  46. package/_standalone/.next/server/app/api/bootstrap/route_client-reference-manifest.js +1 -1
  47. package/_standalone/.next/server/app/api/changes/route_client-reference-manifest.js +1 -1
  48. package/_standalone/.next/server/app/api/channels/verify/route_client-reference-manifest.js +1 -1
  49. package/_standalone/.next/server/app/api/connect/route_client-reference-manifest.js +1 -1
  50. package/_standalone/.next/server/app/api/embedding/route_client-reference-manifest.js +1 -1
  51. package/_standalone/.next/server/app/api/export/route_client-reference-manifest.js +1 -1
  52. package/_standalone/.next/server/app/api/extract-pdf/route_client-reference-manifest.js +1 -1
  53. package/_standalone/.next/server/app/api/file/import/route_client-reference-manifest.js +1 -1
  54. package/_standalone/.next/server/app/api/file/raw/route_client-reference-manifest.js +1 -1
  55. package/_standalone/.next/server/app/api/file/route_client-reference-manifest.js +1 -1
  56. package/_standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  57. package/_standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  58. package/_standalone/.next/server/app/api/graph/route_client-reference-manifest.js +1 -1
  59. package/_standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
  60. package/_standalone/.next/server/app/api/im/activity/route_client-reference-manifest.js +1 -1
  61. package/_standalone/.next/server/app/api/im/config/route_client-reference-manifest.js +1 -1
  62. package/_standalone/.next/server/app/api/im/status/route_client-reference-manifest.js +1 -1
  63. package/_standalone/.next/server/app/api/im/test/route_client-reference-manifest.js +1 -1
  64. package/_standalone/.next/server/app/api/im/webhook/feishu/route_client-reference-manifest.js +1 -1
  65. package/_standalone/.next/server/app/api/im/webhook-status/route_client-reference-manifest.js +1 -1
  66. package/_standalone/.next/server/app/api/inbox/clip/route_client-reference-manifest.js +1 -1
  67. package/_standalone/.next/server/app/api/inbox/route_client-reference-manifest.js +1 -1
  68. package/_standalone/.next/server/app/api/init/route_client-reference-manifest.js +1 -1
  69. package/_standalone/.next/server/app/api/lint/route_client-reference-manifest.js +1 -1
  70. package/_standalone/.next/server/app/api/mcp/agents/route_client-reference-manifest.js +1 -1
  71. package/_standalone/.next/server/app/api/mcp/direct-tools/route_client-reference-manifest.js +1 -1
  72. package/_standalone/.next/server/app/api/mcp/install/route_client-reference-manifest.js +1 -1
  73. package/_standalone/.next/server/app/api/mcp/install-skill/route_client-reference-manifest.js +1 -1
  74. package/_standalone/.next/server/app/api/mcp/restart/route_client-reference-manifest.js +1 -1
  75. package/_standalone/.next/server/app/api/mcp/status/route_client-reference-manifest.js +1 -1
  76. package/_standalone/.next/server/app/api/mcp/tools/route_client-reference-manifest.js +1 -1
  77. package/_standalone/.next/server/app/api/mcp/uninstall/route_client-reference-manifest.js +1 -1
  78. package/_standalone/.next/server/app/api/monitoring/route_client-reference-manifest.js +1 -1
  79. package/_standalone/.next/server/app/api/recent-files/route_client-reference-manifest.js +1 -1
  80. package/_standalone/.next/server/app/api/restart/route_client-reference-manifest.js +1 -1
  81. package/_standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
  82. package/_standalone/.next/server/app/api/settings/list-models/route_client-reference-manifest.js +1 -1
  83. package/_standalone/.next/server/app/api/settings/reset-token/route_client-reference-manifest.js +1 -1
  84. package/_standalone/.next/server/app/api/settings/route_client-reference-manifest.js +1 -1
  85. package/_standalone/.next/server/app/api/settings/test-key/route_client-reference-manifest.js +1 -1
  86. package/_standalone/.next/server/app/api/setup/check-path/route_client-reference-manifest.js +1 -1
  87. package/_standalone/.next/server/app/api/setup/check-port/route_client-reference-manifest.js +1 -1
  88. package/_standalone/.next/server/app/api/setup/generate-token/route_client-reference-manifest.js +1 -1
  89. package/_standalone/.next/server/app/api/setup/ls/route_client-reference-manifest.js +1 -1
  90. package/_standalone/.next/server/app/api/setup/route_client-reference-manifest.js +1 -1
  91. package/_standalone/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  92. package/_standalone/.next/server/app/api/space-overview/route_client-reference-manifest.js +1 -1
  93. package/_standalone/.next/server/app/api/sync/route_client-reference-manifest.js +1 -1
  94. package/_standalone/.next/server/app/api/tree-version/route_client-reference-manifest.js +1 -1
  95. package/_standalone/.next/server/app/api/uninstall/route_client-reference-manifest.js +1 -1
  96. package/_standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  97. package/_standalone/.next/server/app/api/update-check/route_client-reference-manifest.js +1 -1
  98. package/_standalone/.next/server/app/api/update-status/route_client-reference-manifest.js +1 -1
  99. package/_standalone/.next/server/app/api/workflows/route_client-reference-manifest.js +1 -1
  100. package/_standalone/.next/server/app/changelog/page.js +1 -1
  101. package/_standalone/.next/server/app/changelog/page.js.nft.json +1 -1
  102. package/_standalone/.next/server/app/changelog/page_client-reference-manifest.js +1 -1
  103. package/_standalone/.next/server/app/changes/page.js +1 -1
  104. package/_standalone/.next/server/app/changes/page.js.nft.json +1 -1
  105. package/_standalone/.next/server/app/changes/page_client-reference-manifest.js +1 -1
  106. package/_standalone/.next/server/app/echo/[segment]/page.js +1 -1
  107. package/_standalone/.next/server/app/echo/[segment]/page.js.nft.json +1 -1
  108. package/_standalone/.next/server/app/echo/[segment]/page_client-reference-manifest.js +1 -1
  109. package/_standalone/.next/server/app/echo/page.js +1 -1
  110. package/_standalone/.next/server/app/echo/page.js.nft.json +1 -1
  111. package/_standalone/.next/server/app/echo/page_client-reference-manifest.js +1 -1
  112. package/_standalone/.next/server/app/explore/page.js +1 -1
  113. package/_standalone/.next/server/app/explore/page.js.nft.json +1 -1
  114. package/_standalone/.next/server/app/explore/page_client-reference-manifest.js +1 -1
  115. package/_standalone/.next/server/app/help/page.js +1 -1
  116. package/_standalone/.next/server/app/help/page.js.nft.json +1 -1
  117. package/_standalone/.next/server/app/help/page_client-reference-manifest.js +1 -1
  118. package/_standalone/.next/server/app/inbox/history/page.js +1 -1
  119. package/_standalone/.next/server/app/inbox/history/page.js.nft.json +1 -1
  120. package/_standalone/.next/server/app/inbox/history/page_client-reference-manifest.js +1 -1
  121. package/_standalone/.next/server/app/login/page.js +1 -1
  122. package/_standalone/.next/server/app/login/page.js.nft.json +1 -1
  123. package/_standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  124. package/_standalone/.next/server/app/page.js +1 -1
  125. package/_standalone/.next/server/app/page.js.nft.json +1 -1
  126. package/_standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  127. package/_standalone/.next/server/app/setup/page.js +1 -1
  128. package/_standalone/.next/server/app/setup/page.js.nft.json +1 -1
  129. package/_standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  130. package/_standalone/.next/server/app/trash/page.js +2 -2
  131. package/_standalone/.next/server/app/trash/page_client-reference-manifest.js +1 -1
  132. package/_standalone/.next/server/app/view/[...path]/page.js +2 -2
  133. package/_standalone/.next/server/app/view/[...path]/page.js.nft.json +1 -1
  134. package/_standalone/.next/server/app/view/[...path]/page_client-reference-manifest.js +1 -1
  135. package/_standalone/.next/server/app-paths-manifest.json +27 -27
  136. package/_standalone/.next/server/chunks/{3311.js → 2449.js} +2 -2
  137. package/_standalone/.next/server/chunks/5299.js +1 -1
  138. package/_standalone/.next/server/chunks/6022.js +34 -34
  139. package/_standalone/.next/server/middleware-build-manifest.js +1 -1
  140. package/_standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  141. package/_standalone/.next/server/pages/500.html +2 -2
  142. package/_standalone/.next/server/server-reference-manifest.js +1 -1
  143. package/_standalone/.next/server/server-reference-manifest.json +1 -1
  144. package/_standalone/.next/static/chunks/{7143.879daa87569c5b02.js → 4094.09364c01df411380.js} +1 -1
  145. package/_standalone/.next/static/chunks/{5795.d9099a1afecd6047.js → 5331.c89084fd7f67887d.js} +2 -2
  146. package/_standalone/.next/static/chunks/app/{layout-a344709b8447be75.js → layout-fcbde5bee626d21a.js} +63 -63
  147. package/_standalone/.next/static/chunks/app/trash/page-e623ff0ab35de002.js +1 -0
  148. package/_standalone/.next/static/chunks/app/view/[...path]/page-49c4eff6ffdb5168.js +12 -0
  149. package/_standalone/.next/static/chunks/{webpack-2f2787d3469d3df1.js → webpack-dc486b68118d1328.js} +1 -1
  150. package/_standalone/.next/trace +72 -72
  151. package/_standalone/package-lock.json +2 -2
  152. package/_standalone/package.json +1 -1
  153. package/app/package.json +1 -1
  154. package/package.json +1 -1
  155. package/_standalone/.next/static/chunks/app/trash/page-0907fdd06a4467de.js +0 -1
  156. package/_standalone/.next/static/chunks/app/view/[...path]/page-f53ce199b4a4bbb5.js +0 -12
  157. package/browser-extension/README.md +0 -160
  158. package/browser-extension/build.mjs +0 -63
  159. package/browser-extension/extension/background/service-worker.js +0 -1
  160. package/browser-extension/extension/content/extractor.js +0 -2
  161. package/browser-extension/extension/icons/icon-128.png +0 -0
  162. package/browser-extension/extension/icons/icon-128.svg +0 -4
  163. package/browser-extension/extension/icons/icon-16.png +0 -0
  164. package/browser-extension/extension/icons/icon-16.svg +0 -4
  165. package/browser-extension/extension/icons/icon-32.png +0 -0
  166. package/browser-extension/extension/icons/icon-32.svg +0 -4
  167. package/browser-extension/extension/icons/icon-48.png +0 -0
  168. package/browser-extension/extension/icons/icon-48.svg +0 -4
  169. package/browser-extension/extension/manifest.json +0 -47
  170. package/browser-extension/extension/popup/popup.css +0 -510
  171. package/browser-extension/extension/popup/popup.html +0 -128
  172. package/browser-extension/extension/popup/popup.js +0 -73
  173. package/browser-extension/package-lock.json +0 -617
  174. package/browser-extension/package.json +0 -21
  175. package/browser-extension/scripts/gen-icons.sh +0 -38
  176. package/browser-extension/src/background/service-worker.ts +0 -27
  177. package/browser-extension/src/content/extractor.ts +0 -44
  178. package/browser-extension/src/icons/icon-128.png +0 -0
  179. package/browser-extension/src/icons/icon-128.svg +0 -4
  180. package/browser-extension/src/icons/icon-16.png +0 -0
  181. package/browser-extension/src/icons/icon-16.svg +0 -4
  182. package/browser-extension/src/icons/icon-32.png +0 -0
  183. package/browser-extension/src/icons/icon-32.svg +0 -4
  184. package/browser-extension/src/icons/icon-48.png +0 -0
  185. package/browser-extension/src/icons/icon-48.svg +0 -4
  186. package/browser-extension/src/lib/api.ts +0 -146
  187. package/browser-extension/src/lib/markdown.ts +0 -68
  188. package/browser-extension/src/lib/storage.ts +0 -37
  189. package/browser-extension/src/lib/types.ts +0 -42
  190. package/browser-extension/src/manifest.json +0 -47
  191. package/browser-extension/src/popup/popup.css +0 -510
  192. package/browser-extension/src/popup/popup.html +0 -128
  193. package/browser-extension/src/popup/popup.ts +0 -416
  194. package/browser-extension/tsconfig.json +0 -16
  195. package/tests/e2e/README.md +0 -25
  196. package/tests/e2e/navigation.spec.ts +0 -14
  197. package/tests/e2e/playwright.config.ts +0 -14
  198. package/tests/integration/README.md +0 -25
  199. package/tests/integration/mcp-contract.test.ts +0 -57
  200. package/tests/integration/mcp-transport.test.ts +0 -361
  201. package/tests/integration/package-lock.json +0 -1463
  202. package/tests/integration/package.json +0 -8
  203. package/tests/integration/vitest.config.ts +0 -11
  204. package/tests/security-hardening.test.ts +0 -456
  205. package/tests/unit/build-integrity.test.ts +0 -137
  206. package/tests/unit/cli-build.test.ts +0 -180
  207. package/tests/unit/cli-config.test.ts +0 -257
  208. package/tests/unit/cli-mcp-install-toml.test.ts +0 -586
  209. package/tests/unit/cli-mcp-install.test.ts +0 -123
  210. package/tests/unit/cli-mcp-stdio-default.test.ts +0 -180
  211. package/tests/unit/cli-modules-load.test.ts +0 -64
  212. package/tests/unit/cli-port.test.ts +0 -87
  213. package/tests/unit/cli-skill-auto-copy.test.ts +0 -260
  214. package/tests/unit/cli-smoke.test.ts +0 -88
  215. package/tests/unit/cli-uninstall.test.ts +0 -218
  216. package/tests/unit/cli-update-root.test.ts +0 -89
  217. package/tests/unit/cli-user-flow-sim.test.ts +0 -506
  218. package/tests/unit/cli-wait-hint.test.ts +0 -86
  219. package/tests/unit/custom-agents.test.ts +0 -478
  220. package/tests/unit/dep-safety.test.ts +0 -126
  221. package/tests/unit/detect-system-lang.test.ts +0 -122
  222. package/tests/unit/mcp-build.test.ts +0 -162
  223. package/tests/unit/setup-needs-restart.test.ts +0 -139
  224. package/tests/unit/stop-restart.test.ts +0 -393
  225. package/tests/unit/vitest.config.ts +0 -8
  226. /package/_standalone/.next/static/{w5bqzZbd2_vdoPRB0JQ_I → Dn8EHqUedSzanCfrM8WWS}/_buildManifest.js +0 -0
  227. /package/_standalone/.next/static/{w5bqzZbd2_vdoPRB0JQ_I → Dn8EHqUedSzanCfrM8WWS}/_ssgManifest.js +0 -0
@@ -1,361 +0,0 @@
1
- /**
2
- * MCP Transport Connectivity Test
3
- *
4
- * Pre-release smoke test: verifies both HTTP and stdio MCP transports
5
- * can initialize and execute a tool call (mindos_list_files).
6
- *
7
- * Prerequisites:
8
- * - App server running at MINDOS_URL (default http://localhost:3456)
9
- * - MCP bundle built: `cd mcp && npm run build`
10
- *
11
- * Run:
12
- * cd tests/integration && npx vitest run mcp-transport.test.ts
13
- */
14
-
15
- import { describe, it, expect, afterAll } from 'vitest';
16
- import { spawn, ChildProcess } from 'child_process';
17
- import { join } from 'path';
18
- import { createConnection, Socket } from 'net';
19
- import { readFileSync, existsSync } from 'fs';
20
- import { homedir } from 'os';
21
-
22
- const APP_URL = process.env.MINDOS_URL ?? 'http://localhost:3456';
23
-
24
- // Read AUTH_TOKEN from env or config file (same as bin/lib/config.js)
25
- function resolveAuthToken(): string {
26
- if (process.env.AUTH_TOKEN) return process.env.AUTH_TOKEN;
27
- try {
28
- const configPath = join(homedir(), '.mindos', 'config.json');
29
- if (existsSync(configPath)) {
30
- const config = JSON.parse(readFileSync(configPath, 'utf-8'));
31
- return config.authToken || '';
32
- }
33
- } catch {}
34
- return '';
35
- }
36
-
37
- const AUTH_TOKEN = resolveAuthToken();
38
- const MCP_BUNDLE = join(__dirname, '../../mcp/dist/index.cjs');
39
-
40
- // Track spawned processes for cleanup
41
- const children: ChildProcess[] = [];
42
- afterAll(() => {
43
- for (const child of children) {
44
- try { child.kill('SIGTERM'); } catch {}
45
- }
46
- });
47
-
48
- /** Find a free port by briefly listening on :0 */
49
- function getFreePort(): Promise<number> {
50
- return new Promise((resolve, reject) => {
51
- const srv = require('net').createServer();
52
- srv.listen(0, '127.0.0.1', () => {
53
- const port = srv.address().port;
54
- srv.close(() => resolve(port));
55
- });
56
- srv.on('error', reject);
57
- });
58
- }
59
-
60
- /** JSON-RPC 2.0 request factory */
61
- function jsonrpc(method: string, params: Record<string, unknown>, id: number) {
62
- return { jsonrpc: '2.0', method, params, id };
63
- }
64
-
65
- /** Wait until a TCP port accepts connections (max waitMs) */
66
- async function waitForPort(port: number, waitMs = 8000): Promise<void> {
67
- const start = Date.now();
68
- while (Date.now() - start < waitMs) {
69
- const ok = await new Promise<boolean>((resolve) => {
70
- const sock: Socket = createConnection({ host: '127.0.0.1', port }, () => {
71
- sock.destroy();
72
- resolve(true);
73
- });
74
- sock.on('error', () => resolve(false));
75
- sock.setTimeout(500, () => { sock.destroy(); resolve(false); });
76
- });
77
- if (ok) return;
78
- await new Promise((r) => setTimeout(r, 300));
79
- }
80
- throw new Error(`Port ${port} not ready after ${waitMs}ms`);
81
- }
82
-
83
- // ─── HTTP Transport ─────────────────────────────────────────────────────────
84
-
85
- describe('MCP HTTP transport', () => {
86
- let mcpPort: number;
87
- let proc: ChildProcess;
88
-
89
- it('initializes and lists tools via Streamable HTTP', async () => {
90
- mcpPort = await getFreePort();
91
-
92
- proc = spawn(process.execPath, [MCP_BUNDLE], {
93
- env: {
94
- ...process.env,
95
- MCP_TRANSPORT: 'http',
96
- MCP_PORT: String(mcpPort),
97
- MCP_HOST: '127.0.0.1',
98
- MINDOS_URL: APP_URL,
99
- AUTH_TOKEN,
100
- },
101
- stdio: ['pipe', 'pipe', 'pipe'],
102
- });
103
- children.push(proc);
104
-
105
- // Collect stderr for debugging
106
- let stderr = '';
107
- proc.stderr?.on('data', (d: Buffer) => { stderr += d.toString(); });
108
-
109
- await waitForPort(mcpPort);
110
-
111
- const endpoint = `http://127.0.0.1:${mcpPort}/mcp`;
112
-
113
- // Build auth headers — MCP HTTP server checks Bearer token when AUTH_TOKEN is set
114
- const authHeader: Record<string, string> = AUTH_TOKEN
115
- ? { Authorization: `Bearer ${AUTH_TOKEN}` }
116
- : {};
117
-
118
- // 1. Initialize
119
- const initRes = await fetch(endpoint, {
120
- method: 'POST',
121
- headers: { 'Content-Type': 'application/json', Accept: 'application/json, text/event-stream', ...authHeader },
122
- body: JSON.stringify(jsonrpc('initialize', {
123
- protocolVersion: '2025-03-26',
124
- capabilities: {},
125
- clientInfo: { name: 'test-client', version: '1.0.0' },
126
- }, 1)),
127
- });
128
-
129
- // Streamable HTTP may return SSE or JSON
130
- const contentType = initRes.headers.get('content-type') ?? '';
131
- let initResult: Record<string, unknown>;
132
-
133
- if (contentType.includes('text/event-stream')) {
134
- // Parse SSE: find the "data:" line with JSON-RPC response
135
- const text = await initRes.text();
136
- const dataLine = text.split('\n').find((l) => l.startsWith('data: '));
137
- expect(dataLine).toBeDefined();
138
- initResult = JSON.parse(dataLine!.replace('data: ', ''));
139
- } else {
140
- initResult = await initRes.json() as Record<string, unknown>;
141
- }
142
-
143
- expect(initResult).toHaveProperty('result');
144
- const result = initResult.result as Record<string, unknown>;
145
- expect(result).toHaveProperty('serverInfo');
146
- expect((result.serverInfo as Record<string, string>).name).toBe('mindos-mcp-server');
147
-
148
- // Extract session ID from response header (Mcp-Session-Id)
149
- const sessionId = initRes.headers.get('mcp-session-id');
150
-
151
- // 2. Send initialized notification
152
- const notifHeaders: Record<string, string> = {
153
- 'Content-Type': 'application/json',
154
- ...authHeader,
155
- };
156
- if (sessionId) notifHeaders['Mcp-Session-Id'] = sessionId;
157
-
158
- await fetch(endpoint, {
159
- method: 'POST',
160
- headers: notifHeaders,
161
- body: JSON.stringify({ jsonrpc: '2.0', method: 'notifications/initialized' }),
162
- });
163
-
164
- // 3. List tools
165
- const toolsHeaders: Record<string, string> = {
166
- 'Content-Type': 'application/json',
167
- Accept: 'application/json, text/event-stream',
168
- ...authHeader,
169
- };
170
- if (sessionId) toolsHeaders['Mcp-Session-Id'] = sessionId;
171
-
172
- const toolsRes = await fetch(endpoint, {
173
- method: 'POST',
174
- headers: toolsHeaders,
175
- body: JSON.stringify(jsonrpc('tools/list', {}, 2)),
176
- });
177
-
178
- const toolsCt = toolsRes.headers.get('content-type') ?? '';
179
- let toolsResult: Record<string, unknown>;
180
-
181
- if (toolsCt.includes('text/event-stream')) {
182
- const text = await toolsRes.text();
183
- const dataLine = text.split('\n').find((l) => l.startsWith('data: '));
184
- toolsResult = JSON.parse(dataLine!.replace('data: ', ''));
185
- } else {
186
- toolsResult = await toolsRes.json() as Record<string, unknown>;
187
- }
188
-
189
- expect(toolsResult).toHaveProperty('result');
190
- const toolsList = (toolsResult.result as Record<string, unknown>).tools as Array<{ name: string }>;
191
- expect(toolsList.length).toBeGreaterThan(10);
192
-
193
- // Verify known tools exist
194
- const toolNames = toolsList.map((t) => t.name);
195
- expect(toolNames).toContain('mindos_list_files');
196
- expect(toolNames).toContain('mindos_read_file');
197
- expect(toolNames).toContain('mindos_search_notes');
198
- expect(toolNames).toContain('mindos_bootstrap');
199
-
200
- // Cleanup
201
- proc.kill('SIGTERM');
202
- }, 20_000);
203
- });
204
-
205
- // ─── stdio Transport ────────────────────────────────────────────────────────
206
-
207
- describe('MCP stdio transport', () => {
208
- it('initializes and lists tools via stdio', async () => {
209
- const proc = spawn(process.execPath, [MCP_BUNDLE], {
210
- env: {
211
- ...process.env,
212
- MCP_TRANSPORT: 'stdio',
213
- MINDOS_URL: APP_URL,
214
- AUTH_TOKEN,
215
- },
216
- stdio: ['pipe', 'pipe', 'pipe'],
217
- });
218
- children.push(proc);
219
-
220
- let stderr = '';
221
- proc.stderr?.on('data', (d: Buffer) => { stderr += d.toString(); });
222
-
223
- function sendAndReceive(msg: Record<string, unknown>): Promise<Record<string, unknown>> {
224
- return new Promise((resolve, reject) => {
225
- const timeout = setTimeout(() => reject(new Error('stdio response timeout')), 10_000);
226
- let buf = '';
227
-
228
- const onData = (chunk: Buffer) => {
229
- buf += chunk.toString();
230
- // JSON-RPC over stdio uses newline-delimited JSON
231
- const lines = buf.split('\n');
232
- for (const line of lines) {
233
- if (!line.trim()) continue;
234
- try {
235
- const parsed = JSON.parse(line);
236
- // Match by id (skip notifications which have no id)
237
- if (parsed.id === msg.id) {
238
- clearTimeout(timeout);
239
- proc.stdout?.off('data', onData);
240
- resolve(parsed);
241
- return;
242
- }
243
- } catch {
244
- // incomplete JSON, keep buffering
245
- }
246
- }
247
- };
248
-
249
- proc.stdout?.on('data', onData);
250
- proc.stdin?.write(JSON.stringify(msg) + '\n');
251
- });
252
- }
253
-
254
- // 1. Initialize
255
- const initRes = await sendAndReceive(jsonrpc('initialize', {
256
- protocolVersion: '2025-03-26',
257
- capabilities: {},
258
- clientInfo: { name: 'test-client', version: '1.0.0' },
259
- }, 1));
260
-
261
- expect(initRes).toHaveProperty('result');
262
- const result = initRes.result as Record<string, unknown>;
263
- expect(result).toHaveProperty('serverInfo');
264
- expect((result.serverInfo as Record<string, string>).name).toBe('mindos-mcp-server');
265
-
266
- // 2. Send initialized notification (no response expected)
267
- proc.stdin?.write(JSON.stringify({ jsonrpc: '2.0', method: 'notifications/initialized' }) + '\n');
268
-
269
- // Small delay for notification processing
270
- await new Promise((r) => setTimeout(r, 200));
271
-
272
- // 3. List tools
273
- const toolsRes = await sendAndReceive(jsonrpc('tools/list', {}, 2));
274
-
275
- expect(toolsRes).toHaveProperty('result');
276
- const toolsList = (toolsRes.result as Record<string, unknown>).tools as Array<{ name: string }>;
277
- expect(toolsList.length).toBeGreaterThan(10);
278
-
279
- const toolNames = toolsList.map((t) => t.name);
280
- expect(toolNames).toContain('mindos_list_files');
281
- expect(toolNames).toContain('mindos_read_file');
282
- expect(toolNames).toContain('mindos_search_notes');
283
- expect(toolNames).toContain('mindos_bootstrap');
284
-
285
- // Cleanup
286
- proc.kill('SIGTERM');
287
- }, 20_000);
288
- });
289
-
290
- // ─── Tool Call (requires running App server) ────────────────────────────────
291
-
292
- describe('MCP tool call via stdio', () => {
293
- it('calls mindos_list_files and gets response', async () => {
294
- const proc = spawn(process.execPath, [MCP_BUNDLE], {
295
- env: {
296
- ...process.env,
297
- MCP_TRANSPORT: 'stdio',
298
- MINDOS_URL: APP_URL,
299
- AUTH_TOKEN,
300
- },
301
- stdio: ['pipe', 'pipe', 'pipe'],
302
- });
303
- children.push(proc);
304
-
305
- let buf = '';
306
- function sendAndReceive(msg: Record<string, unknown>): Promise<Record<string, unknown>> {
307
- return new Promise((resolve, reject) => {
308
- const timeout = setTimeout(() => reject(new Error('stdio response timeout')), 10_000);
309
-
310
- const onData = (chunk: Buffer) => {
311
- buf += chunk.toString();
312
- const lines = buf.split('\n');
313
- // Keep the last incomplete line in buffer
314
- buf = lines.pop() || '';
315
- for (const line of lines) {
316
- if (!line.trim()) continue;
317
- try {
318
- const parsed = JSON.parse(line);
319
- if (parsed.id === msg.id) {
320
- clearTimeout(timeout);
321
- proc.stdout?.off('data', onData);
322
- resolve(parsed);
323
- return;
324
- }
325
- } catch { /* incomplete */ }
326
- }
327
- };
328
-
329
- proc.stdout?.on('data', onData);
330
- proc.stdin?.write(JSON.stringify(msg) + '\n');
331
- });
332
- }
333
-
334
- // Initialize
335
- await sendAndReceive(jsonrpc('initialize', {
336
- protocolVersion: '2025-03-26',
337
- capabilities: {},
338
- clientInfo: { name: 'test-client', version: '1.0.0' },
339
- }, 1));
340
-
341
- proc.stdin?.write(JSON.stringify({ jsonrpc: '2.0', method: 'notifications/initialized' }) + '\n');
342
- await new Promise((r) => setTimeout(r, 200));
343
-
344
- // Call mindos_list_files — this actually hits the App API
345
- const callRes = await sendAndReceive(jsonrpc('tools/call', {
346
- name: 'mindos_list_files',
347
- arguments: { response_format: 'json' },
348
- }, 3));
349
-
350
- expect(callRes).toHaveProperty('result');
351
- const callResult = callRes.result as Record<string, unknown>;
352
- expect(callResult).toHaveProperty('content');
353
- const content = callResult.content as Array<{ type: string; text: string }>;
354
- expect(content.length).toBeGreaterThan(0);
355
- expect(content[0].type).toBe('text');
356
- // Should contain file listing (non-empty KB)
357
- expect(content[0].text.length).toBeGreaterThan(0);
358
-
359
- proc.kill('SIGTERM');
360
- }, 20_000);
361
- });