@search-docs/mcp-server 1.0.13 → 1.0.15

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 (87) hide show
  1. package/dist/__tests__/helpers/test-setup.d.ts +33 -0
  2. package/dist/__tests__/helpers/test-setup.d.ts.map +1 -0
  3. package/dist/__tests__/helpers/test-setup.js +106 -0
  4. package/dist/__tests__/helpers/test-setup.js.map +1 -0
  5. package/dist/__tests__/helpers/types.d.ts +22 -0
  6. package/dist/__tests__/helpers/types.d.ts.map +1 -0
  7. package/dist/__tests__/helpers/types.js +5 -0
  8. package/dist/__tests__/helpers/types.js.map +1 -0
  9. package/dist/__tests__/mcp-server-basic.test.d.ts +16 -0
  10. package/dist/__tests__/mcp-server-basic.test.d.ts.map +1 -0
  11. package/dist/__tests__/mcp-server-basic.test.js +113 -0
  12. package/dist/__tests__/mcp-server-basic.test.js.map +1 -0
  13. package/dist/__tests__/server-lifecycle.test.d.ts +15 -0
  14. package/dist/__tests__/server-lifecycle.test.d.ts.map +1 -0
  15. package/dist/__tests__/server-lifecycle.test.js +171 -0
  16. package/dist/__tests__/server-lifecycle.test.js.map +1 -0
  17. package/dist/__tests__/server-state-transition-v2.test.d.ts +7 -0
  18. package/dist/__tests__/server-state-transition-v2.test.d.ts.map +1 -0
  19. package/dist/__tests__/server-state-transition-v2.test.js +182 -0
  20. package/dist/__tests__/server-state-transition-v2.test.js.map +1 -0
  21. package/dist/__tests__/server-state.test.d.ts +11 -0
  22. package/dist/__tests__/server-state.test.d.ts.map +1 -0
  23. package/dist/__tests__/server-state.test.js +123 -0
  24. package/dist/__tests__/server-state.test.js.map +1 -0
  25. package/dist/__tests__/state.test.d.ts +5 -0
  26. package/dist/__tests__/state.test.d.ts.map +1 -0
  27. package/dist/__tests__/state.test.js +114 -0
  28. package/dist/__tests__/state.test.js.map +1 -0
  29. package/dist/server-manager.d.ts +1 -1
  30. package/dist/server-manager.d.ts.map +1 -1
  31. package/dist/server-manager.js +68 -15
  32. package/dist/server-manager.js.map +1 -1
  33. package/dist/server-state-transition.test.d.ts +9 -0
  34. package/dist/server-state-transition.test.d.ts.map +1 -0
  35. package/dist/server-state-transition.test.js +267 -0
  36. package/dist/server-state-transition.test.js.map +1 -0
  37. package/dist/server.d.ts +4 -0
  38. package/dist/server.d.ts.map +1 -1
  39. package/dist/server.js +91 -243
  40. package/dist/server.js.map +1 -1
  41. package/dist/server.test.js +32 -1
  42. package/dist/server.test.js.map +1 -1
  43. package/dist/state.d.ts +42 -0
  44. package/dist/state.d.ts.map +1 -0
  45. package/dist/state.js +96 -0
  46. package/dist/state.js.map +1 -0
  47. package/dist/tools/__tests__/index-status.test.d.ts +5 -0
  48. package/dist/tools/__tests__/index-status.test.d.ts.map +1 -0
  49. package/dist/tools/__tests__/index-status.test.js +123 -0
  50. package/dist/tools/__tests__/index-status.test.js.map +1 -0
  51. package/dist/tools/get-document.d.ts +10 -0
  52. package/dist/tools/get-document.d.ts.map +1 -0
  53. package/dist/tools/get-document.js +73 -0
  54. package/dist/tools/get-document.js.map +1 -0
  55. package/dist/tools/index-status.d.ts +10 -0
  56. package/dist/tools/index-status.d.ts.map +1 -0
  57. package/dist/tools/index-status.js +51 -0
  58. package/dist/tools/index-status.js.map +1 -0
  59. package/dist/tools/index.d.ts +11 -0
  60. package/dist/tools/index.d.ts.map +1 -0
  61. package/dist/tools/index.js +12 -0
  62. package/dist/tools/index.js.map +1 -0
  63. package/dist/tools/init.d.ts +10 -0
  64. package/dist/tools/init.d.ts.map +1 -0
  65. package/dist/tools/init.js +71 -0
  66. package/dist/tools/init.js.map +1 -0
  67. package/dist/tools/search.d.ts +10 -0
  68. package/dist/tools/search.d.ts.map +1 -0
  69. package/dist/tools/search.js +92 -0
  70. package/dist/tools/search.js.map +1 -0
  71. package/dist/tools/server-control.d.ts +14 -0
  72. package/dist/tools/server-control.d.ts.map +1 -0
  73. package/dist/tools/server-control.js +121 -0
  74. package/dist/tools/server-control.js.map +1 -0
  75. package/dist/tools/system-status.d.ts +10 -0
  76. package/dist/tools/system-status.d.ts.map +1 -0
  77. package/dist/tools/system-status.js +68 -0
  78. package/dist/tools/system-status.js.map +1 -0
  79. package/dist/tools/types.d.ts +17 -0
  80. package/dist/tools/types.d.ts.map +1 -0
  81. package/dist/tools/types.js +5 -0
  82. package/dist/tools/types.js.map +1 -0
  83. package/dist/utils.d.ts +19 -0
  84. package/dist/utils.d.ts.map +1 -0
  85. package/dist/utils.js +36 -0
  86. package/dist/utils.js.map +1 -0
  87. package/package.json +3 -3
@@ -0,0 +1,182 @@
1
+ /**
2
+ * MCP Server 状態遷移とライフサイクル E2E Tests (リファクタリング版)
3
+ *
4
+ * テストヘルパーを使用して、各状態のテストを明確に分離
5
+ */
6
+ import { describe, test, expect, afterEach } from 'vitest';
7
+ import { setupTestEnvironment } from './helpers/test-setup.js';
8
+ describe('MCP Server 状態遷移テスト (リファクタリング版)', () => {
9
+ let env = null;
10
+ afterEach(async () => {
11
+ if (env) {
12
+ await env.cleanup();
13
+ env = null;
14
+ }
15
+ });
16
+ describe('NOT_CONFIGURED状態', () => {
17
+ test('未設定状態で利用可能なツールはinit, get_system_statusのみ', async () => {
18
+ env = await setupTestEnvironment({
19
+ prefix: 'not-configured',
20
+ createConfig: false,
21
+ });
22
+ const response = (await env.tester.sendRequest('tools/list', {}));
23
+ const toolNames = response.tools.map((t) => t.name);
24
+ // NOT_CONFIGURED状態では init と get_system_status のみ利用可能
25
+ expect(toolNames).toContain('init');
26
+ expect(toolNames).toContain('get_system_status');
27
+ // 他のツールは利用不可
28
+ expect(toolNames).not.toContain('search');
29
+ expect(toolNames).not.toContain('get_document');
30
+ expect(toolNames).not.toContain('index_status');
31
+ });
32
+ test('get_system_statusで未設定状態を確認', async () => {
33
+ env = await setupTestEnvironment({
34
+ prefix: 'not-configured',
35
+ createConfig: false,
36
+ });
37
+ const result = await env.tester.callTool('get_system_status', {});
38
+ expect(result.success).toBe(true);
39
+ const content = result.result?.content?.[0]?.text;
40
+ expect(content).toBeDefined();
41
+ expect(content).toContain('状態: 未設定');
42
+ });
43
+ test('initツールで設定ファイルを作成', async () => {
44
+ env = await setupTestEnvironment({
45
+ prefix: 'not-configured',
46
+ createConfig: false,
47
+ });
48
+ const result = await env.tester.callTool('init', {
49
+ port: 54321,
50
+ });
51
+ expect(result.success).toBe(true);
52
+ const content = result.result?.content?.[0]?.text;
53
+ expect(content).toContain('✅ 設定ファイルの初期化が完了しました');
54
+ expect(content).toContain('📝 設定ファイルの重要な項目');
55
+ });
56
+ });
57
+ describe('CONFIGURED_SERVER_DOWN状態', () => {
58
+ test('設定済み・サーバ停止状態で利用可能なツール', async () => {
59
+ env = await setupTestEnvironment({
60
+ prefix: 'configured-down',
61
+ createConfig: true,
62
+ port: 54322,
63
+ createIndexDir: false, // インデックスなし = auto-startしない
64
+ });
65
+ const response = (await env.tester.sendRequest('tools/list', {}));
66
+ const toolNames = response.tools.map((t) => t.name);
67
+ // CONFIGURED_SERVER_DOWN状態では server_start, server_stop も利用可能
68
+ expect(toolNames).toContain('init');
69
+ expect(toolNames).toContain('server_start');
70
+ expect(toolNames).toContain('server_stop');
71
+ expect(toolNames).toContain('get_system_status');
72
+ // 検索系ツールは利用不可
73
+ expect(toolNames).not.toContain('search');
74
+ expect(toolNames).not.toContain('get_document');
75
+ expect(toolNames).not.toContain('index_status');
76
+ });
77
+ test('get_system_statusで設定済み・サーバ停止状態を確認', async () => {
78
+ env = await setupTestEnvironment({
79
+ prefix: 'configured-down',
80
+ createConfig: true,
81
+ port: 54323,
82
+ createIndexDir: false,
83
+ });
84
+ const result = await env.tester.callTool('get_system_status', {});
85
+ expect(result.success).toBe(true);
86
+ const content = result.result?.content?.[0]?.text;
87
+ expect(content).toContain('状態: 設定済み・サーバ停止中');
88
+ });
89
+ });
90
+ describe('RUNNING状態(auto-start)', () => {
91
+ test('インデックス存在時にauto-startで全ツールが利用可能', async () => {
92
+ env = await setupTestEnvironment({
93
+ prefix: 'running-auto',
94
+ createConfig: true,
95
+ port: 54324,
96
+ createIndexDir: true, // インデックスあり = auto-start
97
+ });
98
+ const response = (await env.tester.sendRequest('tools/list', {}));
99
+ const toolNames = response.tools.map((t) => t.name);
100
+ // RUNNING状態では全ツールが利用可能
101
+ expect(toolNames).toContain('init');
102
+ expect(toolNames).toContain('server_start');
103
+ expect(toolNames).toContain('server_stop');
104
+ expect(toolNames).toContain('get_system_status');
105
+ expect(toolNames).toContain('search');
106
+ expect(toolNames).toContain('get_document');
107
+ expect(toolNames).toContain('index_status');
108
+ }, 40000); // 40秒のタイムアウト(auto-start health check 30s + buffer)
109
+ test('get_system_statusで稼働中状態を確認', async () => {
110
+ env = await setupTestEnvironment({
111
+ prefix: 'running-auto',
112
+ createConfig: true,
113
+ port: 54325,
114
+ createIndexDir: true,
115
+ });
116
+ const result = await env.tester.callTool('get_system_status', {});
117
+ expect(result.success).toBe(true);
118
+ const content = result.result?.content?.[0]?.text;
119
+ expect(content).toContain('状態: 稼働中');
120
+ expect(content).toContain('サーバURL:');
121
+ }, 40000); // 40秒のタイムアウト(auto-start health check 30s + buffer)
122
+ });
123
+ describe('サーバ起動・停止のライフサイクル', () => {
124
+ test('server_startでサーバを起動し、server_stopで停止できる', async () => {
125
+ env = await setupTestEnvironment({
126
+ prefix: 'lifecycle',
127
+ createConfig: true,
128
+ port: 54326,
129
+ createIndexDir: false,
130
+ });
131
+ // 1. サーバを起動
132
+ const startResult = await env.tester.callTool('server_start', {});
133
+ expect(startResult.success).toBe(true);
134
+ const startContent = startResult.result?.content?.[0]?.text;
135
+ expect(startContent).toContain('✅ サーバを起動しました');
136
+ // サーバ起動を待機
137
+ await new Promise((resolve) => setTimeout(resolve, 3000));
138
+ // 2. 起動後の状態確認
139
+ const statusAfterStart = await env.tester.callTool('get_system_status', {});
140
+ const statusContent = statusAfterStart.result?.content?.[0]?.text;
141
+ expect(statusContent).toContain('状態: 稼働中');
142
+ // 3. サーバを停止
143
+ const stopResult = await env.tester.callTool('server_stop', {});
144
+ expect(stopResult.success).toBe(true);
145
+ const stopContent = stopResult.result?.content?.[0]?.text;
146
+ expect(stopContent).toContain('✅ サーバを停止しました');
147
+ // サーバ停止を待機
148
+ await new Promise((resolve) => setTimeout(resolve, 2000));
149
+ // 4. 停止後の状態確認
150
+ const statusAfterStop = await env.tester.callTool('get_system_status', {});
151
+ const statusAfterStopContent = statusAfterStop.result?.content?.[0]
152
+ ?.text;
153
+ expect(statusAfterStopContent).toContain('状態: 設定済み・サーバ停止中');
154
+ }, 30000); // 30秒のタイムアウト
155
+ test('停止後に再度server_startで起動できる', async () => {
156
+ env = await setupTestEnvironment({
157
+ prefix: 'lifecycle-restart',
158
+ createConfig: true,
159
+ port: 54327,
160
+ createIndexDir: false,
161
+ });
162
+ // 1. 初回起動
163
+ await env.tester.callTool('server_start', {});
164
+ await new Promise((resolve) => setTimeout(resolve, 3000));
165
+ // 2. 停止
166
+ await env.tester.callTool('server_stop', {});
167
+ await new Promise((resolve) => setTimeout(resolve, 2000));
168
+ // 3. 再起動
169
+ const restartResult = await env.tester.callTool('server_start', {});
170
+ expect(restartResult.success).toBe(true);
171
+ const restartContent = restartResult.result?.content?.[0]?.text;
172
+ expect(restartContent).toContain('✅ サーバを起動しました');
173
+ // 再起動を待機
174
+ await new Promise((resolve) => setTimeout(resolve, 3000));
175
+ // 4. 再起動後の状態確認
176
+ const statusAfterRestart = await env.tester.callTool('get_system_status', {});
177
+ const statusContent = statusAfterRestart.result?.content?.[0]?.text;
178
+ expect(statusContent).toContain('状態: 稼働中');
179
+ }, 40000); // 40秒のタイムアウト
180
+ });
181
+ });
182
+ //# sourceMappingURL=server-state-transition-v2.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-state-transition-v2.test.js","sourceRoot":"","sources":["../../src/__tests__/server-state-transition-v2.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * MCP Server 状態確認テスト
3
+ *
4
+ * 目的: 各状態(NOT_CONFIGURED, CONFIGURED_SERVER_DOWN, RUNNING)において、
5
+ * 利用可能なツールとget_system_statusの内容が正しいかを確認する。
6
+ *
7
+ * 特徴: search-docsサーバを起動/停止しない静的なテスト
8
+ * 各テストは独立した一時ディレクトリとポート番号を使用
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=server-state.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-state.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/server-state.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * MCP Server 状態確認テスト
3
+ *
4
+ * 目的: 各状態(NOT_CONFIGURED, CONFIGURED_SERVER_DOWN, RUNNING)において、
5
+ * 利用可能なツールとget_system_statusの内容が正しいかを確認する。
6
+ *
7
+ * 特徴: search-docsサーバを起動/停止しない静的なテスト
8
+ * 各テストは独立した一時ディレクトリとポート番号を使用
9
+ */
10
+ import { describe, test, expect, afterEach } from 'vitest';
11
+ import { setupTestEnvironment } from './helpers/test-setup.js';
12
+ describe('MCP Server 状態確認テスト', () => {
13
+ let env = null;
14
+ afterEach(async () => {
15
+ if (env) {
16
+ await env.cleanup();
17
+ env = null;
18
+ }
19
+ });
20
+ describe('NOT_CONFIGURED状態', () => {
21
+ test('利用可能なツールはinit, get_system_statusのみ', async () => {
22
+ env = await setupTestEnvironment({
23
+ prefix: 'state-not-configured',
24
+ createConfig: false,
25
+ port: 54320,
26
+ });
27
+ const response = (await env.tester.sendRequest('tools/list', {}));
28
+ const toolNames = response.tools.map((t) => t.name);
29
+ // NOT_CONFIGURED状態では init と get_system_status のみ利用可能
30
+ expect(toolNames).toContain('init');
31
+ expect(toolNames).toContain('get_system_status');
32
+ // 他のツールは利用不可
33
+ expect(toolNames).not.toContain('server_start');
34
+ expect(toolNames).not.toContain('server_stop');
35
+ expect(toolNames).not.toContain('search');
36
+ expect(toolNames).not.toContain('get_document');
37
+ expect(toolNames).not.toContain('index_status');
38
+ });
39
+ test('get_system_statusで未設定状態を確認', async () => {
40
+ env = await setupTestEnvironment({
41
+ prefix: 'state-not-configured-status',
42
+ createConfig: false,
43
+ port: 54320,
44
+ });
45
+ const result = await env.tester.callTool('get_system_status', {});
46
+ expect(result.success).toBe(true);
47
+ const content = result.result?.content?.[0]?.text;
48
+ expect(content).toBeDefined();
49
+ expect(content).toContain('状態: 未設定');
50
+ });
51
+ });
52
+ describe('CONFIGURED_SERVER_DOWN状態', () => {
53
+ test('利用可能なツールはserver_start, server_stopなどが追加', async () => {
54
+ env = await setupTestEnvironment({
55
+ prefix: 'state-configured-down',
56
+ createConfig: true,
57
+ port: 54321,
58
+ createIndexDir: false, // インデックスなし = auto-startしない
59
+ });
60
+ const response = (await env.tester.sendRequest('tools/list', {}));
61
+ const toolNames = response.tools.map((t) => t.name);
62
+ // CONFIGURED_SERVER_DOWN状態では server_start, server_stop も利用可能
63
+ expect(toolNames).toContain('init');
64
+ expect(toolNames).toContain('server_start');
65
+ expect(toolNames).toContain('server_stop');
66
+ expect(toolNames).toContain('get_system_status');
67
+ // 検索系ツールは利用不可
68
+ expect(toolNames).not.toContain('search');
69
+ expect(toolNames).not.toContain('get_document');
70
+ expect(toolNames).not.toContain('index_status');
71
+ });
72
+ test('get_system_statusで設定済み・サーバ停止中状態を確認', async () => {
73
+ env = await setupTestEnvironment({
74
+ prefix: 'state-configured-down-status',
75
+ createConfig: true,
76
+ port: 54321,
77
+ createIndexDir: false,
78
+ });
79
+ const result = await env.tester.callTool('get_system_status', {});
80
+ expect(result.success).toBe(true);
81
+ const content = result.result?.content?.[0]?.text;
82
+ expect(content).toContain('状態: 設定済み・サーバ停止中');
83
+ });
84
+ });
85
+ describe('RUNNING状態(auto-start後)', () => {
86
+ test('全ツールが利用可能', async () => {
87
+ env = await setupTestEnvironment({
88
+ prefix: 'state-running',
89
+ createConfig: true,
90
+ port: 54322,
91
+ createIndexDir: true, // インデックスあり = auto-start
92
+ });
93
+ // auto-start完了を待機
94
+ await new Promise((resolve) => setTimeout(resolve, 3000));
95
+ const response = (await env.tester.sendRequest('tools/list', {}));
96
+ const toolNames = response.tools.map((t) => t.name);
97
+ // RUNNING状態では全ツールが利用可能
98
+ expect(toolNames).toContain('init');
99
+ expect(toolNames).toContain('server_start');
100
+ expect(toolNames).toContain('server_stop');
101
+ expect(toolNames).toContain('get_system_status');
102
+ expect(toolNames).toContain('search');
103
+ expect(toolNames).toContain('get_document');
104
+ expect(toolNames).toContain('index_status');
105
+ }, 40000); // 40秒のタイムアウト(auto-start health check 30s + buffer)
106
+ test('get_system_statusで稼働中状態を確認', async () => {
107
+ env = await setupTestEnvironment({
108
+ prefix: 'state-running-status',
109
+ createConfig: true,
110
+ port: 54322,
111
+ createIndexDir: true,
112
+ });
113
+ // auto-start完了を待機
114
+ await new Promise((resolve) => setTimeout(resolve, 3000));
115
+ const result = await env.tester.callTool('get_system_status', {});
116
+ expect(result.success).toBe(true);
117
+ const content = result.result?.content?.[0]?.text;
118
+ expect(content).toContain('状態: 稼働中');
119
+ expect(content).toContain('サーバURL:');
120
+ }, 40000); // 40秒のタイムアウト(auto-start health check 30s + buffer)
121
+ });
122
+ });
123
+ //# sourceMappingURL=server-state.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-state.test.js","sourceRoot":"","sources":["../../src/__tests__/server-state.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * 状態管理のテスト
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=state.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/state.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * 状態管理のテスト
3
+ */
4
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
5
+ import { detectSystemState, getStateErrorMessage } from '../state.js';
6
+ import { ConfigLoader } from '@search-docs/types';
7
+ import { SearchDocsClient } from '@search-docs/client';
8
+ // モック
9
+ vi.mock('@search-docs/types');
10
+ vi.mock('@search-docs/client');
11
+ describe('state', () => {
12
+ describe('detectSystemState', () => {
13
+ beforeEach(() => {
14
+ vi.clearAllMocks();
15
+ });
16
+ it('設定ファイルがない場合、NOT_CONFIGUREDを返す', async () => {
17
+ // ConfigLoader.resolve が設定なしを返す
18
+ vi.mocked(ConfigLoader.resolve).mockResolvedValue({
19
+ config: null,
20
+ configPath: null,
21
+ projectRoot: '/test/project',
22
+ });
23
+ const result = await detectSystemState('/test/project');
24
+ expect(result.state).toBe('NOT_CONFIGURED');
25
+ expect(result.projectRoot).toBe('/test/project');
26
+ expect(result.config).toBeUndefined();
27
+ expect(result.configPath).toBeUndefined();
28
+ });
29
+ it('設定ファイル読み込みエラーの場合、NOT_CONFIGUREDを返す', async () => {
30
+ // ConfigLoader.resolve がエラーを投げる
31
+ vi.mocked(ConfigLoader.resolve).mockRejectedValue(new Error('Configuration file not found'));
32
+ const result = await detectSystemState('/test/project');
33
+ expect(result.state).toBe('NOT_CONFIGURED');
34
+ expect(result.projectRoot).toBe('/test/project');
35
+ });
36
+ it('設定ファイルがあるがサーバが停止中の場合、CONFIGURED_SERVER_DOWNを返す', async () => {
37
+ const mockConfig = {
38
+ version: '1.0',
39
+ server: {
40
+ host: 'localhost',
41
+ port: 24280,
42
+ protocol: 'json-rpc',
43
+ },
44
+ };
45
+ // ConfigLoader.resolve が設定を返す
46
+ vi.mocked(ConfigLoader.resolve).mockResolvedValue({
47
+ config: mockConfig,
48
+ configPath: '/test/project/.search-docs.json',
49
+ projectRoot: '/test/project',
50
+ });
51
+ // SearchDocsClient.healthCheck がエラーを投げる(サーバ停止中)
52
+ const mockHealthCheck = vi.fn().mockRejectedValue(new Error('Connection refused'));
53
+ vi.mocked(SearchDocsClient).mockImplementation(class {
54
+ healthCheck = mockHealthCheck;
55
+ });
56
+ const result = await detectSystemState('/test/project');
57
+ expect(result.state).toBe('CONFIGURED_SERVER_DOWN');
58
+ expect(result.config).toBe(mockConfig);
59
+ expect(result.configPath).toBe('/test/project/.search-docs.json');
60
+ expect(result.projectRoot).toBe('/test/project');
61
+ expect(result.serverUrl).toBe('http://localhost:24280');
62
+ expect(result.client).toBeUndefined();
63
+ });
64
+ it('設定ファイルがありサーバが稼働中の場合、RUNNINGを返す', async () => {
65
+ const mockConfig = {
66
+ version: '1.0',
67
+ server: {
68
+ host: 'localhost',
69
+ port: 24280,
70
+ protocol: 'json-rpc',
71
+ },
72
+ };
73
+ // ConfigLoader.resolve が設定を返す
74
+ vi.mocked(ConfigLoader.resolve).mockResolvedValue({
75
+ config: mockConfig,
76
+ configPath: '/test/project/.search-docs.json',
77
+ projectRoot: '/test/project',
78
+ });
79
+ // SearchDocsClient.healthCheck が成功(サーバ稼働中)
80
+ const mockHealthCheck = vi.fn().mockResolvedValue(undefined);
81
+ vi.mocked(SearchDocsClient).mockImplementation(class {
82
+ healthCheck = mockHealthCheck;
83
+ });
84
+ const result = await detectSystemState('/test/project');
85
+ expect(result.state).toBe('RUNNING');
86
+ expect(result.config).toBe(mockConfig);
87
+ expect(result.configPath).toBe('/test/project/.search-docs.json');
88
+ expect(result.projectRoot).toBe('/test/project');
89
+ expect(result.serverUrl).toBe('http://localhost:24280');
90
+ expect(result.client).toBeDefined();
91
+ });
92
+ });
93
+ describe('getStateErrorMessage', () => {
94
+ it('NOT_CONFIGURED状態のエラーメッセージを返す', () => {
95
+ const message = getStateErrorMessage('NOT_CONFIGURED', '検索');
96
+ expect(message).toContain('検索を実行できません');
97
+ expect(message).toContain('セットアップされていません');
98
+ expect(message).toContain('init');
99
+ expect(message).toContain('server_start');
100
+ });
101
+ it('CONFIGURED_SERVER_DOWN状態のエラーメッセージを返す', () => {
102
+ const message = getStateErrorMessage('CONFIGURED_SERVER_DOWN', '検索');
103
+ expect(message).toContain('検索を実行できません');
104
+ expect(message).toContain('起動していません');
105
+ expect(message).toContain('server_start');
106
+ });
107
+ it('RUNNING状態のエラーメッセージを返す', () => {
108
+ const message = getStateErrorMessage('RUNNING', '検索');
109
+ expect(message).toContain('検索を実行できません');
110
+ expect(message).toContain('予期しないエラー');
111
+ });
112
+ });
113
+ });
114
+ //# sourceMappingURL=state.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.test.js","sourceRoot":"","sources":["../../src/__tests__/state.test.ts"],"names":[],"mappings":"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"}
@@ -11,7 +11,7 @@ export declare class ServerManager {
11
11
  */
12
12
  private resolveCliPath;
13
13
  /**
14
- * サーバを起動
14
+ * サーバを起動(デーモンモード)
15
15
  */
16
16
  startServer(projectDir: string, port: number, configPath?: string): Promise<void>;
17
17
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"server-manager.d.ts","sourceRoot":"","sources":["../src/server-manager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,aAAa,CAA8B;IAEnD;;OAEG;YACW,cAAc;IA0B5B;;OAEG;IACG,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA6DvF;;OAEG;IACH,UAAU,IAAI,IAAI;IAQlB;;OAEG;IACH,OAAO,IAAI,IAAI;CAGhB"}
1
+ {"version":3,"file":"server-manager.d.ts","sourceRoot":"","sources":["../src/server-manager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAeH;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,aAAa,CAA8B;IAEnD;;OAEG;YACW,cAAc;IAqB5B;;OAEG;IACG,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAyHvF;;OAEG;IACH,UAAU,IAAI,IAAI;IAQlB;;OAEG;IACH,OAAO,IAAI,IAAI;CAGhB"}
@@ -4,6 +4,7 @@
4
4
  import { spawn } from 'child_process';
5
5
  import * as path from 'path';
6
6
  import * as fs from 'fs/promises';
7
+ import { SearchDocsClient } from '@search-docs/client';
7
8
  /**
8
9
  * サーバマネージャー
9
10
  */
@@ -15,13 +16,10 @@ export class ServerManager {
15
16
  async resolveCliPath() {
16
17
  try {
17
18
  // import.meta.resolve()でパスを解決
19
+ // これはパッケージのエントリポイント(package.jsonのmainフィールド)を返す
18
20
  const cliPackage = import.meta.resolve('@search-docs/cli');
19
21
  // file:// プロトコルを削除してファイルパスに変換
20
- const cliPackagePath = cliPackage.replace(/^file:\/\//, '');
21
- // パッケージディレクトリを取得
22
- const cliDir = path.dirname(cliPackagePath);
23
- // dist/index.jsを探す
24
- const cliEntryPoint = path.join(cliDir, 'dist', 'index.js');
22
+ const cliEntryPoint = cliPackage.replace(/^file:\/\//, '');
25
23
  // ファイルが存在するか確認
26
24
  await fs.access(cliEntryPoint);
27
25
  return cliEntryPoint;
@@ -32,25 +30,37 @@ export class ServerManager {
32
30
  }
33
31
  }
34
32
  /**
35
- * サーバを起動
33
+ * サーバを起動(デーモンモード)
36
34
  */
37
35
  async startServer(projectDir, port, configPath) {
36
+ console.error('[mcp-server] ========================================');
38
37
  console.error('[mcp-server] Starting search-docs server...');
38
+ console.error('[mcp-server] Input parameters:');
39
+ console.error(`[mcp-server] - projectDir: ${projectDir}`);
40
+ console.error(`[mcp-server] - port: ${port}`);
41
+ console.error(`[mcp-server] - configPath: ${configPath || '(not provided)'}`);
39
42
  try {
40
43
  // CLIのエントリポイントを解決
41
44
  const cliPath = await this.resolveCliPath();
42
45
  console.error(`[mcp-server] CLI path resolved: ${cliPath}`);
43
- // サーバ起動コマンドを構築
44
- const args = ['server', 'start', '--foreground', '--port', port.toString()];
46
+ // サーバ起動コマンドを構築(デーモンモード)
47
+ const args = ['server', 'start', '--port', port.toString()];
45
48
  if (configPath) {
46
49
  args.push('--config', configPath);
47
50
  }
48
- // サーバを起動
51
+ console.error('[mcp-server] Spawn parameters:');
52
+ console.error(`[mcp-server] - command: node`);
53
+ console.error(`[mcp-server] - args: ${JSON.stringify([cliPath, ...args])}`);
54
+ console.error(`[mcp-server] - cwd: ${projectDir}`);
55
+ console.error(`[mcp-server] - stdio: ['ignore', 'pipe', 'pipe']`);
56
+ console.error(`[mcp-server] - detached: false`);
57
+ // サーバを起動(デーモンモード)
49
58
  const serverProcess = spawn('node', [cliPath, ...args], {
50
59
  cwd: projectDir, // プロジェクトディレクトリで実行
51
60
  stdio: ['ignore', 'pipe', 'pipe'], // stdin無視, stdout/stderrキャプチャ
52
- detached: false, // MCP終了時にサーバも終了
61
+ detached: false,
53
62
  });
63
+ console.error(`[mcp-server] Process spawned with PID: ${serverProcess.pid || '(unknown)'}`);
54
64
  // エラーハンドリング
55
65
  serverProcess.on('error', (error) => {
56
66
  console.error(`[mcp-server] Server process error: ${error.message}`);
@@ -65,16 +75,59 @@ export class ServerManager {
65
75
  });
66
76
  // プロセス終了時
67
77
  serverProcess.on('exit', (code, signal) => {
68
- console.error(`[mcp-server] Server process exited: code=${code}, signal=${signal}`);
69
- this.serverProcess = null;
78
+ console.error(`[mcp-server] Server launcher exited: code=${code}, signal=${signal}`);
70
79
  });
80
+ // デーモンモードなので、起動プロセスは即座に終了する
81
+ // 実際のサーバプロセスは別プロセスとして起動される
71
82
  this.serverProcess = {
72
83
  process: serverProcess,
73
84
  port,
74
85
  };
75
- // サーバの起動を待つ(簡易的に2秒待機)
76
- await new Promise(resolve => setTimeout(resolve, 2000));
77
- console.error('[mcp-server] Server started successfully');
86
+ // デーモンモードでは起動プロセスが即座に終了するため、
87
+ // 実際のサーバプロセスが起動完了するまで待機する
88
+ console.error('[mcp-server] Waiting for server to start...');
89
+ // サーバのヘルスチェックを行う(最大30秒待機)
90
+ const serverUrl = `http://localhost:${port}`;
91
+ const client = new SearchDocsClient({ baseUrl: serverUrl });
92
+ const maxWaitTime = 30000; // 30秒
93
+ const checkInterval = 1000; // 1秒
94
+ let waited = 0;
95
+ let serverReady = false;
96
+ console.error(`[mcp-server] Health check target: ${serverUrl}`);
97
+ console.error(`[mcp-server] Max wait time: ${maxWaitTime}ms, check interval: ${checkInterval}ms`);
98
+ while (waited < maxWaitTime) {
99
+ try {
100
+ console.error(`[mcp-server] Health check attempt (waited: ${waited}ms)...`);
101
+ await client.healthCheck();
102
+ serverReady = true;
103
+ console.error('[mcp-server] ✓ Server is ready (health check passed)');
104
+ break;
105
+ }
106
+ catch (error) {
107
+ // サーバがまだ起動していない、待機を続ける
108
+ console.error(`[mcp-server] Health check failed: ${error.message}`);
109
+ await new Promise(resolve => setTimeout(resolve, checkInterval));
110
+ waited += checkInterval;
111
+ }
112
+ }
113
+ if (!serverReady) {
114
+ console.error('[mcp-server] ✗ Health check timeout after 30 seconds');
115
+ throw new Error('Server failed to start within 30 seconds');
116
+ }
117
+ // PIDファイルの作成を確認
118
+ const pidFilePath = path.join(projectDir, '.search-docs', 'server.pid');
119
+ console.error(`[mcp-server] Checking PID file at: ${pidFilePath}`);
120
+ try {
121
+ await fs.access(pidFilePath);
122
+ const pidContent = await fs.readFile(pidFilePath, 'utf-8');
123
+ console.error('[mcp-server] ✓ PID file confirmed');
124
+ console.error(`[mcp-server] PID file content: ${pidContent.substring(0, 200)}...`);
125
+ }
126
+ catch (error) {
127
+ console.error(`[mcp-server] ✗ Warning: PID file not found: ${error.message}`);
128
+ }
129
+ console.error('[mcp-server] Server started successfully (daemon mode)');
130
+ console.error('[mcp-server] ========================================');
78
131
  }
79
132
  catch (error) {
80
133
  throw new Error(`Failed to start server: ${error.message}`);