kiri-mcp-server 0.9.6 → 0.10.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 (207) hide show
  1. package/README.md +144 -13
  2. package/dist/client/cli.js +68 -0
  3. package/dist/client/cli.js.map +1 -0
  4. package/dist/client/index.js +5 -0
  5. package/dist/client/index.js.map +1 -0
  6. package/dist/eval/metrics.js +47 -0
  7. package/dist/eval/metrics.js.map +1 -0
  8. package/dist/indexer/cli.js +362 -0
  9. package/dist/indexer/cli.js.map +1 -0
  10. package/dist/indexer/codeintel.js +182 -0
  11. package/dist/indexer/codeintel.js.map +1 -0
  12. package/dist/indexer/git.js +30 -0
  13. package/dist/indexer/git.js.map +1 -0
  14. package/dist/indexer/language.js +34 -0
  15. package/dist/indexer/language.js.map +1 -0
  16. package/dist/indexer/pipeline/filters/denylist.js +71 -0
  17. package/dist/indexer/pipeline/filters/denylist.js.map +1 -0
  18. package/dist/indexer/schema.js +101 -0
  19. package/dist/indexer/schema.js.map +1 -0
  20. package/dist/package.json +14 -1
  21. package/dist/server/bootstrap.js +19 -0
  22. package/dist/server/bootstrap.js.map +1 -0
  23. package/dist/server/context.js +1 -0
  24. package/dist/server/context.js.map +1 -0
  25. package/dist/server/fallbacks/degradeController.js +69 -0
  26. package/dist/server/fallbacks/degradeController.js.map +1 -0
  27. package/dist/server/handlers.js +1268 -0
  28. package/dist/server/handlers.js.map +1 -0
  29. package/dist/server/main.js +151 -0
  30. package/dist/server/main.js.map +1 -0
  31. package/dist/server/observability/metrics.js +56 -0
  32. package/dist/server/observability/metrics.js.map +1 -0
  33. package/dist/server/observability/tracing.js +58 -0
  34. package/dist/server/observability/tracing.js.map +1 -0
  35. package/dist/server/rpc.js +477 -0
  36. package/dist/server/rpc.js.map +1 -0
  37. package/dist/server/runtime.js +47 -0
  38. package/dist/server/runtime.js.map +1 -0
  39. package/dist/server/scoring.js +116 -0
  40. package/dist/server/scoring.js.map +1 -0
  41. package/dist/server/stdio.js +76 -0
  42. package/dist/server/stdio.js.map +1 -0
  43. package/dist/shared/duckdb.js +119 -0
  44. package/dist/shared/duckdb.js.map +1 -0
  45. package/dist/shared/embedding.js +98 -0
  46. package/dist/shared/embedding.js.map +1 -0
  47. package/dist/shared/index.js +9 -0
  48. package/dist/shared/index.js.map +1 -0
  49. package/dist/shared/security/config.js +64 -0
  50. package/dist/shared/security/config.js.map +1 -0
  51. package/dist/shared/security/masker.js +56 -0
  52. package/dist/shared/security/masker.js.map +1 -0
  53. package/dist/shared/tokenizer.js +4 -0
  54. package/dist/shared/tokenizer.js.map +1 -0
  55. package/dist/shared/utils/simpleYaml.js +89 -0
  56. package/dist/shared/utils/simpleYaml.js.map +1 -0
  57. package/dist/src/client/proxy.js +83 -13
  58. package/dist/src/client/proxy.js.map +1 -1
  59. package/dist/src/client/start-daemon.d.ts.map +1 -1
  60. package/dist/src/client/start-daemon.js +2 -1
  61. package/dist/src/client/start-daemon.js.map +1 -1
  62. package/dist/src/daemon/daemon.js +97 -18
  63. package/dist/src/daemon/daemon.js.map +1 -1
  64. package/dist/src/daemon/socket.d.ts +6 -4
  65. package/dist/src/daemon/socket.d.ts.map +1 -1
  66. package/dist/src/daemon/socket.js +62 -18
  67. package/dist/src/daemon/socket.js.map +1 -1
  68. package/dist/src/indexer/cli.d.ts +1 -0
  69. package/dist/src/indexer/cli.d.ts.map +1 -1
  70. package/dist/src/indexer/cli.js +503 -257
  71. package/dist/src/indexer/cli.js.map +1 -1
  72. package/dist/src/indexer/codeintel.d.ts +1 -1
  73. package/dist/src/indexer/codeintel.d.ts.map +1 -1
  74. package/dist/src/indexer/codeintel.js +296 -3
  75. package/dist/src/indexer/codeintel.js.map +1 -1
  76. package/dist/src/indexer/dart/analyze.d.ts +29 -0
  77. package/dist/src/indexer/dart/analyze.d.ts.map +1 -0
  78. package/dist/src/indexer/dart/analyze.js +452 -0
  79. package/dist/src/indexer/dart/analyze.js.map +1 -0
  80. package/dist/src/indexer/dart/client.d.ts +113 -0
  81. package/dist/src/indexer/dart/client.d.ts.map +1 -0
  82. package/dist/src/indexer/dart/client.js +444 -0
  83. package/dist/src/indexer/dart/client.js.map +1 -0
  84. package/dist/src/indexer/dart/config.d.ts +36 -0
  85. package/dist/src/indexer/dart/config.d.ts.map +1 -0
  86. package/dist/src/indexer/dart/config.js +62 -0
  87. package/dist/src/indexer/dart/config.js.map +1 -0
  88. package/dist/src/indexer/dart/dependencies.d.ts +17 -0
  89. package/dist/src/indexer/dart/dependencies.d.ts.map +1 -0
  90. package/dist/src/indexer/dart/dependencies.js +102 -0
  91. package/dist/src/indexer/dart/dependencies.js.map +1 -0
  92. package/dist/src/indexer/dart/pathKey.d.ts +40 -0
  93. package/dist/src/indexer/dart/pathKey.d.ts.map +1 -0
  94. package/dist/src/indexer/dart/pathKey.js +72 -0
  95. package/dist/src/indexer/dart/pathKey.js.map +1 -0
  96. package/dist/src/indexer/dart/poolGate.d.ts +57 -0
  97. package/dist/src/indexer/dart/poolGate.d.ts.map +1 -0
  98. package/dist/src/indexer/dart/poolGate.js +87 -0
  99. package/dist/src/indexer/dart/poolGate.js.map +1 -0
  100. package/dist/src/indexer/dart/sdk.d.ts +40 -0
  101. package/dist/src/indexer/dart/sdk.d.ts.map +1 -0
  102. package/dist/src/indexer/dart/sdk.js +167 -0
  103. package/dist/src/indexer/dart/sdk.js.map +1 -0
  104. package/dist/src/indexer/dart/transform.d.ts +17 -0
  105. package/dist/src/indexer/dart/transform.d.ts.map +1 -0
  106. package/dist/src/indexer/dart/transform.js +157 -0
  107. package/dist/src/indexer/dart/transform.js.map +1 -0
  108. package/dist/src/indexer/dart/types.d.ts +137 -0
  109. package/dist/src/indexer/dart/types.d.ts.map +1 -0
  110. package/dist/src/indexer/dart/types.js +5 -0
  111. package/dist/src/indexer/dart/types.js.map +1 -0
  112. package/dist/src/indexer/git.d.ts +1 -0
  113. package/dist/src/indexer/git.d.ts.map +1 -1
  114. package/dist/src/indexer/git.js +8 -0
  115. package/dist/src/indexer/git.js.map +1 -1
  116. package/dist/src/indexer/language.d.ts.map +1 -1
  117. package/dist/src/indexer/language.js +1 -0
  118. package/dist/src/indexer/language.js.map +1 -1
  119. package/dist/src/indexer/queue.d.ts +19 -0
  120. package/dist/src/indexer/queue.d.ts.map +1 -0
  121. package/dist/src/indexer/queue.js +50 -0
  122. package/dist/src/indexer/queue.js.map +1 -0
  123. package/dist/src/indexer/schema.d.ts +61 -1
  124. package/dist/src/indexer/schema.d.ts.map +1 -1
  125. package/dist/src/indexer/schema.js +253 -2
  126. package/dist/src/indexer/schema.js.map +1 -1
  127. package/dist/src/indexer/watch.d.ts +21 -0
  128. package/dist/src/indexer/watch.d.ts.map +1 -1
  129. package/dist/src/indexer/watch.js +189 -28
  130. package/dist/src/indexer/watch.js.map +1 -1
  131. package/dist/src/server/abbreviations.d.ts +47 -0
  132. package/dist/src/server/abbreviations.d.ts.map +1 -0
  133. package/dist/src/server/abbreviations.js +71 -0
  134. package/dist/src/server/abbreviations.js.map +1 -0
  135. package/dist/src/server/boost-profiles.d.ts +63 -0
  136. package/dist/src/server/boost-profiles.d.ts.map +1 -0
  137. package/dist/src/server/boost-profiles.js +86 -0
  138. package/dist/src/server/boost-profiles.js.map +1 -0
  139. package/dist/src/server/context.d.ts +7 -0
  140. package/dist/src/server/context.d.ts.map +1 -1
  141. package/dist/src/server/handlers.d.ts +3 -2
  142. package/dist/src/server/handlers.d.ts.map +1 -1
  143. package/dist/src/server/handlers.js +542 -96
  144. package/dist/src/server/handlers.js.map +1 -1
  145. package/dist/src/server/indexBootstrap.d.ts.map +1 -1
  146. package/dist/src/server/indexBootstrap.js +4 -1
  147. package/dist/src/server/indexBootstrap.js.map +1 -1
  148. package/dist/src/server/main.d.ts.map +1 -1
  149. package/dist/src/server/main.js +112 -30
  150. package/dist/src/server/main.js.map +1 -1
  151. package/dist/src/server/rpc.d.ts.map +1 -1
  152. package/dist/src/server/rpc.js +28 -9
  153. package/dist/src/server/rpc.js.map +1 -1
  154. package/dist/src/server/rrf.d.ts +86 -0
  155. package/dist/src/server/rrf.d.ts.map +1 -0
  156. package/dist/src/server/rrf.js +108 -0
  157. package/dist/src/server/rrf.js.map +1 -0
  158. package/dist/src/server/runtime.d.ts.map +1 -1
  159. package/dist/src/server/runtime.js +45 -6
  160. package/dist/src/server/runtime.js.map +1 -1
  161. package/dist/src/server/scoring.d.ts.map +1 -1
  162. package/dist/src/server/scoring.js +19 -0
  163. package/dist/src/server/scoring.js.map +1 -1
  164. package/dist/src/shared/cli/args.d.ts +70 -0
  165. package/dist/src/shared/cli/args.d.ts.map +1 -0
  166. package/dist/src/shared/cli/args.js +84 -0
  167. package/dist/src/shared/cli/args.js.map +1 -0
  168. package/dist/src/shared/duckdb.d.ts.map +1 -1
  169. package/dist/src/shared/duckdb.js +9 -0
  170. package/dist/src/shared/duckdb.js.map +1 -1
  171. package/dist/src/shared/embedding/engine.d.ts +38 -0
  172. package/dist/src/shared/embedding/engine.d.ts.map +1 -0
  173. package/dist/src/shared/embedding/engine.js +6 -0
  174. package/dist/src/shared/embedding/engine.js.map +1 -0
  175. package/dist/src/shared/embedding/lsh-engine.d.ts +11 -0
  176. package/dist/src/shared/embedding/lsh-engine.d.ts.map +1 -0
  177. package/dist/src/shared/embedding/lsh-engine.js +14 -0
  178. package/dist/src/shared/embedding/lsh-engine.js.map +1 -0
  179. package/dist/src/shared/embedding/registry.d.ts +25 -0
  180. package/dist/src/shared/embedding/registry.d.ts.map +1 -0
  181. package/dist/src/shared/embedding/registry.js +50 -0
  182. package/dist/src/shared/embedding/registry.js.map +1 -0
  183. package/dist/src/shared/embedding/semantic-engine.d.ts +14 -0
  184. package/dist/src/shared/embedding/semantic-engine.d.ts.map +1 -0
  185. package/dist/src/shared/embedding/semantic-engine.js +50 -0
  186. package/dist/src/shared/embedding/semantic-engine.js.map +1 -0
  187. package/dist/src/shared/models/model-manager.d.ts +38 -0
  188. package/dist/src/shared/models/model-manager.d.ts.map +1 -0
  189. package/dist/src/shared/models/model-manager.js +116 -0
  190. package/dist/src/shared/models/model-manager.js.map +1 -0
  191. package/dist/src/shared/models/model-manifest.d.ts +22 -0
  192. package/dist/src/shared/models/model-manifest.d.ts.map +1 -0
  193. package/dist/src/shared/models/model-manifest.js +24 -0
  194. package/dist/src/shared/models/model-manifest.js.map +1 -0
  195. package/dist/src/shared/utils/path.d.ts +46 -0
  196. package/dist/src/shared/utils/path.d.ts.map +1 -0
  197. package/dist/src/shared/utils/path.js +94 -0
  198. package/dist/src/shared/utils/path.js.map +1 -0
  199. package/dist/src/shared/utils/socket.d.ts +61 -0
  200. package/dist/src/shared/utils/socket.d.ts.map +1 -0
  201. package/dist/src/shared/utils/socket.js +156 -0
  202. package/dist/src/shared/utils/socket.js.map +1 -0
  203. package/dist/src/shared/utils/validation.d.ts +14 -0
  204. package/dist/src/shared/utils/validation.d.ts.map +1 -0
  205. package/dist/src/shared/utils/validation.js +22 -0
  206. package/dist/src/shared/utils/validation.js.map +1 -0
  207. package/package.json +14 -1
@@ -0,0 +1,444 @@
1
+ /**
2
+ * DartAnalysisClient: Dart Analysis Server との JSON-RPC 通信クライアント
3
+ */
4
+ import { spawn, execSync } from "node:child_process";
5
+ import { createInterface } from "node:readline";
6
+ import PQueue from "p-queue";
7
+ import { parseFileQueueTtlMs } from "./config.js";
8
+ import { normalizeFileKey } from "./pathKey.js";
9
+ import { detectDartSdk } from "./sdk.js";
10
+ // Fix #4: File queue TTL (default: 30000ms = 30 seconds)
11
+ // Fix #15 (Codex Critical Review): Enforce minimum 1000ms to prevent memory leak when set to 0
12
+ // Fix #19 (Codex Critical Review Round 3): Validate TTL to prevent NaN
13
+ // Extracted to config.ts for testability
14
+ const FILE_QUEUE_TTL_MS = parseFileQueueTtlMs();
15
+ /**
16
+ * DAPProtocolError: Analysis Server プロトコルエラー
17
+ */
18
+ export class DAPProtocolError extends Error {
19
+ code;
20
+ data;
21
+ constructor(message, code, data) {
22
+ super(message);
23
+ this.code = code;
24
+ this.data = data;
25
+ this.name = "DAPProtocolError";
26
+ }
27
+ }
28
+ /**
29
+ * DartAnalysisClient: Dart Analysis Server プロセス管理と JSON-RPC 通信
30
+ */
31
+ export class DartAnalysisClient {
32
+ options;
33
+ process = null;
34
+ readline = null;
35
+ requestId = 0;
36
+ pendingRequests = new Map();
37
+ serverVersion = null;
38
+ initialized = false;
39
+ initializePromise = null;
40
+ // Fix #2: ファイル単位のリクエストキューでオーバーレイ競合を防ぐ
41
+ // Fix #4: TTL cleanup to prevent memory leak
42
+ fileQueues = new Map();
43
+ constructor(options) {
44
+ this.options = options;
45
+ }
46
+ /**
47
+ * Analysis Server プロセスを起動し初期化する
48
+ *
49
+ * 並行呼び出しを安全に処理: 既に初期化中の場合は同じPromiseを返す
50
+ *
51
+ * @throws MissingToolError - Dart SDK が見つからない場合
52
+ * @throws DAPProtocolError - サーバー起動失敗時
53
+ */
54
+ async initialize() {
55
+ if (this.initialized) {
56
+ return;
57
+ }
58
+ // 既に初期化中なら、そのPromiseを返す(並行初期化の競合を防ぐ)
59
+ if (this.initializePromise) {
60
+ return this.initializePromise;
61
+ }
62
+ this.initializePromise = (async () => {
63
+ try {
64
+ // Dart SDK 検出
65
+ const sdkInfo = detectDartSdk();
66
+ console.log(`[DartAnalysisClient] Detected Dart SDK ${sdkInfo.version} at ${sdkInfo.sdkPath}`);
67
+ // Analysis Server プロセス起動
68
+ // Windows対応: dartExecutable の絶対パスを使用
69
+ const args = [
70
+ "--disable-dart-dev",
71
+ sdkInfo.analysisServerPath,
72
+ "--protocol=instrumentation",
73
+ ];
74
+ if (this.options.logPath) {
75
+ args.push(`--instrumentation-log-file=${this.options.logPath}`);
76
+ }
77
+ this.process = spawn(sdkInfo.dartExecutable, args, {
78
+ stdio: ["pipe", "pipe", "pipe"],
79
+ });
80
+ if (!this.process.stdout || !this.process.stdin) {
81
+ throw new DAPProtocolError("Failed to spawn Analysis Server: stdio not available");
82
+ }
83
+ // readline で行単位で JSON を読み取る
84
+ this.readline = createInterface({
85
+ input: this.process.stdout,
86
+ crlfDelay: Infinity,
87
+ });
88
+ this.readline.on("line", (line) => {
89
+ this.handleMessage(line);
90
+ });
91
+ this.process.stderr?.on("data", (data) => {
92
+ console.error(`[DartAnalysisClient] stderr: ${data}`);
93
+ });
94
+ this.process.on("error", (error) => {
95
+ console.error(`[DartAnalysisClient] process error:`, error);
96
+ this.rejectAllPending(new DAPProtocolError(`Analysis Server process error: ${error.message}`));
97
+ // Fix #1: Reset state to allow reinitialization after crash
98
+ this.cleanupState();
99
+ });
100
+ this.process.on("exit", (code, signal) => {
101
+ console.log(`[DartAnalysisClient] process exited: code=${code}, signal=${signal}`);
102
+ this.rejectAllPending(new DAPProtocolError(`Analysis Server exited unexpectedly: code=${code}`));
103
+ // Fix #1: Reset state to allow reinitialization after crash
104
+ this.cleanupState();
105
+ });
106
+ // server.setSubscriptions で接続通知を受け取る
107
+ await this.sendRequest("server.setSubscriptions", {
108
+ subscriptions: ["STATUS"],
109
+ });
110
+ // analysis.setAnalysisRoots でワークスペースルートを設定
111
+ await this.sendRequest("analysis.setAnalysisRoots", {
112
+ included: this.options.workspaceRoots,
113
+ excluded: [],
114
+ });
115
+ this.initialized = true;
116
+ console.log(`[DartAnalysisClient] Initialized with roots:`, this.options.workspaceRoots);
117
+ }
118
+ finally {
119
+ // 初期化完了(成功/失敗問わず)後はPromiseをリセット
120
+ this.initializePromise = null;
121
+ }
122
+ })();
123
+ await this.initializePromise;
124
+ }
125
+ /**
126
+ * ファイルを解析してシンボル情報を取得(MVP版)
127
+ *
128
+ * Fix #2: 同一ファイルの並列解析でオーバーレイ競合を防ぐため、
129
+ * ファイル単位でリクエストをシリアライズ
130
+ *
131
+ * @param filePath - 解析対象ファイルの絶対パス
132
+ * @param content - ファイル内容
133
+ * @returns DartAnalysisPayload
134
+ */
135
+ async analyzeFile(filePath, content) {
136
+ // Fix #5: Normalize file path for Windows case-insensitivity
137
+ const fileKey = normalizeFileKey(filePath);
138
+ // Fix #4: ファイルパス単位でキューを取得または作成(TTL cleanup付き)
139
+ let entry = this.fileQueues.get(fileKey);
140
+ if (!entry) {
141
+ entry = {
142
+ queue: new PQueue({ concurrency: 1 }),
143
+ lastUsed: Date.now(),
144
+ };
145
+ this.fileQueues.set(fileKey, entry);
146
+ }
147
+ // Fix #4: 既存のクリーンアップタイマーをキャンセル(再利用時)
148
+ if (entry.cleanupTimer) {
149
+ clearTimeout(entry.cleanupTimer);
150
+ delete entry.cleanupTimer;
151
+ }
152
+ // Fix #4: 使用時刻を更新
153
+ entry.lastUsed = Date.now();
154
+ // キューに追加して順次実行を保証
155
+ return entry.queue
156
+ .add(async () => {
157
+ if (!this.initialized) {
158
+ await this.initialize();
159
+ }
160
+ // analysis.updateContent でファイル内容を送信
161
+ const updateParams = {
162
+ files: {
163
+ [filePath]: {
164
+ type: "add",
165
+ content,
166
+ },
167
+ },
168
+ };
169
+ await this.sendRequest("analysis.updateContent", updateParams);
170
+ try {
171
+ // analysis.getOutline でシンボル階層を取得
172
+ const outlineResult = await this.sendRequest("analysis.getOutline", {
173
+ file: filePath,
174
+ });
175
+ return {
176
+ outline: outlineResult.outline,
177
+ };
178
+ }
179
+ finally {
180
+ // メモリリーク防止: オーバーレイを必ず削除
181
+ // キューによって直列化されているため、他のリクエストのオーバーレイを削除する心配がない
182
+ await this.sendRequest("analysis.updateContent", {
183
+ files: {
184
+ [filePath]: {
185
+ type: "remove",
186
+ },
187
+ },
188
+ }).catch((error) => {
189
+ console.warn(`[analyzeFile] Failed to remove overlay for ${filePath}:`, error);
190
+ });
191
+ }
192
+ })
193
+ .finally(() => {
194
+ // Fix #4: TTL cleanup timer を設定(キュー実行完了後)
195
+ const currentEntry = this.fileQueues.get(fileKey);
196
+ if (currentEntry && FILE_QUEUE_TTL_MS > 0) {
197
+ currentEntry.cleanupTimer = setTimeout(() => {
198
+ // アイドル状態(size=0, pending=0)の場合のみ削除
199
+ if (currentEntry.queue.size === 0 && currentEntry.queue.pending === 0) {
200
+ this.fileQueues.delete(fileKey);
201
+ }
202
+ }, FILE_QUEUE_TTL_MS);
203
+ // Fix #4: unref() to prevent blocking Node.js exit
204
+ currentEntry.cleanupTimer.unref();
205
+ }
206
+ });
207
+ }
208
+ /**
209
+ * ライブラリの依存関係を取得(Phase 3)
210
+ *
211
+ * @param _filePath - 解析対象ファイルの絶対パス (現在未使用: workspace全体の依存関係を返すため)
212
+ * @returns GetLibraryDependenciesResult
213
+ */
214
+ async getLibraryDependencies(_filePath) {
215
+ if (!this.initialized) {
216
+ await this.initialize();
217
+ }
218
+ const result = await this.sendRequest("analysis.getLibraryDependencies", {});
219
+ return result;
220
+ }
221
+ /**
222
+ * Analysis Server プロセスを終了
223
+ *
224
+ * Fix #3: dispose に options パラメータを追加して柔軟な終了処理を実現
225
+ *
226
+ * @param options - 終了オプション
227
+ * @param options.timeoutMs - Graceful shutdown timeout (デフォルト: 5000ms)
228
+ * @param options.skipShutdown - server.shutdown RPC をスキップして即時強制終了
229
+ */
230
+ async dispose(options) {
231
+ if (!this.process) {
232
+ return;
233
+ }
234
+ const timeoutMs = options?.timeoutMs ?? 5000;
235
+ const skipShutdown = options?.skipShutdown ?? false;
236
+ // Fix #27 (Codex Critical Review Round 5): Store timer handle for cleanup
237
+ let killTimer = null;
238
+ const cleanup = () => {
239
+ if (killTimer) {
240
+ clearTimeout(killTimer);
241
+ killTimer = null;
242
+ }
243
+ this.readline?.close();
244
+ this.process = null;
245
+ this.readline = null;
246
+ this.initialized = false;
247
+ };
248
+ try {
249
+ if (!skipShutdown && this.initialized) {
250
+ // Fix #3: server.shutdown を短いタイムアウトで実行
251
+ await this.sendRequest("server.shutdown", {}, timeoutMs).catch((error) => {
252
+ console.warn(`[DartAnalysisClient] shutdown request failed:`, error);
253
+ });
254
+ // プロセス終了を待つ
255
+ await new Promise((resolve) => {
256
+ if (!this.process) {
257
+ resolve();
258
+ return;
259
+ }
260
+ this.process.once("exit", () => resolve());
261
+ // Fix #14 (Codex Critical Review): Use forceKill() on timeout (includes Windows taskkill)
262
+ // Fix #27 (Codex Critical Review Round 5): Store timer handle and use unref() to prevent event loop hanging
263
+ killTimer = setTimeout(() => {
264
+ this.forceKill();
265
+ resolve();
266
+ }, timeoutMs);
267
+ // CRITICAL: unref() prevents event loop from staying alive waiting for this timer
268
+ killTimer.unref();
269
+ });
270
+ }
271
+ else {
272
+ // Fix #3: skipShutdown または未初期化の場合は即時強制終了
273
+ this.forceKill();
274
+ }
275
+ }
276
+ catch (error) {
277
+ console.error(`[DartAnalysisClient] dispose error:`, error);
278
+ this.forceKill(); // エラー時は強制終了
279
+ }
280
+ finally {
281
+ cleanup();
282
+ }
283
+ }
284
+ /**
285
+ * Fix #1 & #3: プロセスを同期的に強制終了
286
+ *
287
+ * exit フォールバックや緊急時に使用
288
+ * Windows対応: SIGKILLは存在しないため、プラットフォーム別に処理
289
+ */
290
+ forceKill() {
291
+ if (this.process) {
292
+ try {
293
+ this.process.kill("SIGTERM");
294
+ // SIGKILL fallback after 100ms
295
+ setTimeout(() => {
296
+ if (this.process && !this.process.killed) {
297
+ try {
298
+ if (process.platform === "win32") {
299
+ // Windows: Use taskkill for forceful termination
300
+ // Fix #7 (Critical Review): More aggressive than default kill()
301
+ // Fix #11 (Codex Critical Review): Use ESM import instead of require()
302
+ execSync(`taskkill /PID ${this.process.pid} /F /T`, { stdio: "ignore" });
303
+ }
304
+ else {
305
+ // Unix: Use SIGKILL for force termination
306
+ this.process.kill("SIGKILL");
307
+ }
308
+ }
309
+ catch {
310
+ // Force kill may fail if process is already gone
311
+ }
312
+ }
313
+ }, 100);
314
+ }
315
+ catch {
316
+ // kill 失敗は無視(既に終了している可能性)
317
+ }
318
+ }
319
+ }
320
+ /**
321
+ * JSON-RPC リクエスト送信
322
+ *
323
+ * Fix #3: タイムアウト時間を可変にして dispose や初期化での短縮タイムアウトを実現
324
+ *
325
+ * @param method - RPC メソッド名
326
+ * @param params - RPC パラメータ
327
+ * @param timeoutMs - タイムアウト時間(デフォルト: 30000ms)
328
+ */
329
+ async sendRequest(method, params, timeoutMs = 30000) {
330
+ if (!this.process?.stdin) {
331
+ throw new DAPProtocolError("Analysis Server process not running");
332
+ }
333
+ const id = `${++this.requestId}`;
334
+ const request = { id, method, params };
335
+ return new Promise((resolve, reject) => {
336
+ // Fix #3: タイムアウト設定(可変)
337
+ const timeout = setTimeout(() => {
338
+ this.pendingRequests.delete(id);
339
+ reject(new DAPProtocolError(`Request timeout: ${method}`, -32000, { method, params }));
340
+ }, timeoutMs);
341
+ this.pendingRequests.set(id, {
342
+ resolve: resolve,
343
+ reject,
344
+ timeout,
345
+ });
346
+ // JSON-RPC メッセージ送信(改行区切り)
347
+ const message = JSON.stringify(request) + "\n";
348
+ this.process.stdin.write(message);
349
+ });
350
+ }
351
+ /**
352
+ * サーバーからのメッセージを処理
353
+ */
354
+ handleMessage(line) {
355
+ if (!line.trim()) {
356
+ return;
357
+ }
358
+ try {
359
+ const message = JSON.parse(line);
360
+ // レスポンス処理
361
+ if ("id" in message && message.id) {
362
+ this.handleResponse(message);
363
+ }
364
+ // 通知処理
365
+ else if ("event" in message) {
366
+ this.handleNotification(message);
367
+ }
368
+ }
369
+ catch (error) {
370
+ console.error(`[DartAnalysisClient] Failed to parse message:`, line, error);
371
+ }
372
+ }
373
+ /**
374
+ * レスポンス処理
375
+ */
376
+ handleResponse(response) {
377
+ const pending = this.pendingRequests.get(response.id);
378
+ if (!pending) {
379
+ console.warn(`[DartAnalysisClient] Received response for unknown request: ${response.id}`);
380
+ return;
381
+ }
382
+ this.pendingRequests.delete(response.id);
383
+ clearTimeout(pending.timeout);
384
+ if (response.error) {
385
+ pending.reject(new DAPProtocolError(response.error.message, response.error.code, response.error.data));
386
+ }
387
+ else {
388
+ pending.resolve(response.result);
389
+ }
390
+ }
391
+ /**
392
+ * 通知処理
393
+ */
394
+ handleNotification(notification) {
395
+ switch (notification.event) {
396
+ case "server.connected": {
397
+ const params = notification.params;
398
+ this.serverVersion = params.version;
399
+ console.log(`[DartAnalysisClient] Server connected: version=${params.version}, pid=${params.pid}`);
400
+ break;
401
+ }
402
+ case "server.error": {
403
+ const params = notification.params;
404
+ console.error(`[DartAnalysisClient] Server error (fatal=${params.isFatal}):`, params.message);
405
+ if (params.isFatal) {
406
+ this.rejectAllPending(new DAPProtocolError(`Fatal server error: ${params.message}`));
407
+ // Fix #21 (Codex Critical Review Round 3): Auto-recovery after fatal server.error
408
+ this.cleanupState(); // Reset initialized flag to allow reinitialization
409
+ }
410
+ break;
411
+ }
412
+ case "analysis.errors":
413
+ // MVP では無視(後のフェーズで処理)
414
+ break;
415
+ default:
416
+ // その他の通知は無視
417
+ break;
418
+ }
419
+ }
420
+ /**
421
+ * 全ての pending リクエストを reject
422
+ */
423
+ rejectAllPending(error) {
424
+ for (const [_id, pending] of this.pendingRequests) {
425
+ clearTimeout(pending.timeout);
426
+ pending.reject(error);
427
+ }
428
+ this.pendingRequests.clear();
429
+ }
430
+ /**
431
+ * プロセス状態をクリーンアップ(Fix #1: crash recovery用)
432
+ *
433
+ * dispose() とは異なり、server.shutdown を送らずに状態のみリセット。
434
+ * プロセスクラッシュ後の再初期化を可能にする。
435
+ */
436
+ cleanupState() {
437
+ this.readline?.close();
438
+ this.readline = null;
439
+ this.process = null;
440
+ this.initialized = false;
441
+ this.initializePromise = null;
442
+ }
443
+ }
444
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../../src/indexer/dart/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Dart Analysis Server 設定のパース・バリデーション
3
+ *
4
+ * Fix #17-21 (Codex Critical Review Round 3):
5
+ * 環境変数の異常値(NaN、空文字、負数)からデフォルト値へのフォールバックを一元管理
6
+ */
7
+ /**
8
+ * MAX_CLIENTS環境変数をパースして検証
9
+ *
10
+ * @returns 検証済みの MAX_CLIENTS 値(デフォルト: 8)
11
+ */
12
+ export declare function parseMaxClients(): number;
13
+ /**
14
+ * CLIENT_WAIT_MS環境変数をパースして検証
15
+ *
16
+ * @returns 検証済みの CLIENT_WAIT_MS 値(デフォルト: 10000)
17
+ */
18
+ export declare function parseClientWaitMs(): number;
19
+ /**
20
+ * IDLE_TTL_MS環境変数をパースして検証
21
+ *
22
+ * 0 = TTL無効化(無期限保持、LRUで管理)
23
+ * 負数 = デフォルト値にフォールバック
24
+ *
25
+ * @returns 検証済みの IDLE_TTL_MS 値(デフォルト: 60000)
26
+ */
27
+ export declare function parseIdleTtlMs(): number;
28
+ /**
29
+ * FILE_QUEUE_TTL_MS環境変数をパースして検証
30
+ *
31
+ * 最小値: 1000ms(メモリリーク防止)
32
+ *
33
+ * @returns 検証済みの FILE_QUEUE_TTL_MS 値(デフォルト: 30000、最小: 1000)
34
+ */
35
+ export declare function parseFileQueueTtlMs(): number;
36
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../src/indexer/dart/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;GAIG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAGxC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAG1C;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAsBvC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAG5C"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Dart Analysis Server 設定のパース・バリデーション
3
+ *
4
+ * Fix #17-21 (Codex Critical Review Round 3):
5
+ * 環境変数の異常値(NaN、空文字、負数)からデフォルト値へのフォールバックを一元管理
6
+ */
7
+ /**
8
+ * MAX_CLIENTS環境変数をパースして検証
9
+ *
10
+ * @returns 検証済みの MAX_CLIENTS 値(デフォルト: 8)
11
+ */
12
+ export function parseMaxClients() {
13
+ const parsed = Number.parseInt(process.env.DART_ANALYSIS_MAX_CLIENTS ?? "8", 10);
14
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : 8;
15
+ }
16
+ /**
17
+ * CLIENT_WAIT_MS環境変数をパースして検証
18
+ *
19
+ * @returns 検証済みの CLIENT_WAIT_MS 値(デフォルト: 10000)
20
+ */
21
+ export function parseClientWaitMs() {
22
+ const parsed = Number.parseInt(process.env.DART_ANALYSIS_CLIENT_WAIT_MS ?? "10000", 10);
23
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : 10000;
24
+ }
25
+ /**
26
+ * IDLE_TTL_MS環境変数をパースして検証
27
+ *
28
+ * 0 = TTL無効化(無期限保持、LRUで管理)
29
+ * 負数 = デフォルト値にフォールバック
30
+ *
31
+ * @returns 検証済みの IDLE_TTL_MS 値(デフォルト: 60000)
32
+ */
33
+ export function parseIdleTtlMs() {
34
+ const envValue = process.env.DART_ANALYSIS_IDLE_MS ?? "60000";
35
+ // Empty string check first (Number("") returns 0, which is ambiguous)
36
+ if (envValue.trim() === "") {
37
+ return 60000;
38
+ }
39
+ const parsed = Number(envValue);
40
+ // NaN check (handles non-numeric values)
41
+ if (!Number.isFinite(parsed)) {
42
+ return 60000;
43
+ }
44
+ // Explicit 0 is valid (TTL disabled)
45
+ if (parsed === 0) {
46
+ return 0;
47
+ }
48
+ // Negative values fallback to default
49
+ return parsed > 0 ? parsed : 60000;
50
+ }
51
+ /**
52
+ * FILE_QUEUE_TTL_MS環境変数をパースして検証
53
+ *
54
+ * 最小値: 1000ms(メモリリーク防止)
55
+ *
56
+ * @returns 検証済みの FILE_QUEUE_TTL_MS 値(デフォルト: 30000、最小: 1000)
57
+ */
58
+ export function parseFileQueueTtlMs() {
59
+ const parsed = Number.parseInt(process.env.DART_FILE_QUEUE_TTL_MS ?? "30000", 10);
60
+ return Number.isFinite(parsed) ? Math.max(1000, parsed) : 30000;
61
+ }
62
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../src/indexer/dart/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;GAIG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;IACjF,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,4BAA4B,IAAI,OAAO,EAAE,EAAE,CAAC,CAAC;IACxF,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;AAChE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,OAAO,CAAC;IAE9D,sEAAsE;IACtE,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEhC,yCAAyC;IACzC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,qCAAqC;IACrC,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;QACjB,OAAO,CAAC,CAAC;IACX,CAAC;IAED,sCAAsC;IACtC,OAAO,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;AACrC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB;IACjC,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,OAAO,EAAE,EAAE,CAAC,CAAC;IAClF,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAClE,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Dart依存関係解析(Phase 3)
3
+ *
4
+ * Analysis ServerのGetLibraryDependenciesResultからDependencyRecordを生成
5
+ */
6
+ import type { DependencyRecord } from "../codeintel.js";
7
+ import type { GetLibraryDependenciesResult } from "./types.js";
8
+ /**
9
+ * GetLibraryDependenciesResultからDependencyRecordを生成
10
+ *
11
+ * @param filePath - 解析対象ファイルのパス
12
+ * @param dependenciesResult - Analysis Serverの依存関係情報
13
+ * @param workspaceRoot - ワークスペースルート(相対パス解決用)
14
+ * @returns DependencyRecord配列
15
+ */
16
+ export declare function extractDependencies(filePath: string, dependenciesResult: GetLibraryDependenciesResult, workspaceRoot: string): DependencyRecord[];
17
+ //# sourceMappingURL=dependencies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependencies.d.ts","sourceRoot":"","sources":["../../../../src/indexer/dart/dependencies.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAExD,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAE/D;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,kBAAkB,EAAE,4BAA4B,EAChD,aAAa,EAAE,MAAM,GACpB,gBAAgB,EAAE,CAiBpB"}