(jsonOutput: boolean, includeStale: boolean)
| 277 | } |
| 278 | |
| 279 | async function handleList(jsonOutput: boolean, includeStale: boolean): Promise<void> { |
| 280 | const registryEntries = listDaemonRegistryEntries(); |
| 281 | |
| 282 | if (registryEntries.length === 0) { |
| 283 | if (jsonOutput) { |
| 284 | writeLine(JSON.stringify([])); |
| 285 | } else { |
| 286 | writeLine('No daemons found'); |
| 287 | } |
| 288 | return; |
| 289 | } |
| 290 | |
| 291 | // Check each daemon's status |
| 292 | const entries: DaemonListEntry[] = []; |
| 293 | |
| 294 | for (const entry of registryEntries) { |
| 295 | const client = new DaemonClient({ |
| 296 | socketPath: entry.socketPath, |
| 297 | timeout: 1000, // Short timeout for status check |
| 298 | }); |
| 299 | |
| 300 | let status: 'running' | 'stale' = 'stale'; |
| 301 | try { |
| 302 | await client.status(); |
| 303 | status = 'running'; |
| 304 | } catch { |
| 305 | status = 'stale'; |
| 306 | } |
| 307 | |
| 308 | if (status === 'stale' && !includeStale) { |
| 309 | continue; |
| 310 | } |
| 311 | |
| 312 | entries.push({ |
| 313 | workspaceKey: entry.workspaceKey, |
| 314 | workspaceRoot: entry.workspaceRoot, |
| 315 | socketPath: entry.socketPath, |
| 316 | pid: entry.pid, |
| 317 | startedAt: entry.startedAt, |
| 318 | version: entry.version, |
| 319 | status, |
| 320 | }); |
| 321 | } |
| 322 | |
| 323 | if (jsonOutput) { |
| 324 | writeLine(JSON.stringify(entries, null, 2)); |
| 325 | } else { |
| 326 | if (entries.length === 0) { |
| 327 | writeLine('No daemons found'); |
| 328 | return; |
| 329 | } |
| 330 | |
| 331 | writeLine('Daemons:\n'); |
| 332 | for (const entry of entries) { |
| 333 | const statusLabel = entry.status === 'running' ? '[running]' : '[stale]'; |
| 334 | writeLine(` ${statusLabel} ${entry.workspaceKey}`); |
| 335 | writeLine(` Workspace: ${entry.workspaceRoot}`); |
| 336 | writeLine(` PID: ${entry.pid}`); |
no test coverage detected