(home: string = KIMI_CODE_HOME)
| 10 | const HOME_GLOBAL_LOG_REL = ['logs', 'kimi-code.log'] as const; |
| 11 | |
| 12 | export function logsRoute(home: string = KIMI_CODE_HOME): Hono { |
| 13 | const r = new Hono(); |
| 14 | r.get('/:id/logs', async (c) => { |
| 15 | const id = c.req.param('id'); |
| 16 | const which = c.req.query('which') === 'global' ? 'global' : 'session'; |
| 17 | const detail = await readSessionDetail(home, id); |
| 18 | if (!detail) { |
| 19 | return c.json({ error: 'session not found', code: 'NOT_FOUND' }, 404); |
| 20 | } |
| 21 | const sessionLog = join(detail.sessionDir, ...SESSION_LOG_REL); |
| 22 | // The global diagnostic log is a single shared file. In an exported bundle |
| 23 | // it is captured under the session dir (logs/global/kimi-code.log); for a |
| 24 | // live local session it lives at <KIMI_CODE_HOME>/logs/kimi-code.log |
| 25 | // (agent-core's resolveGlobalLogPath), NOT under the session dir. |
| 26 | const globalLog = detail.imported |
| 27 | ? join(detail.sessionDir, ...GLOBAL_LOG_REL) |
| 28 | : join(home, ...HOME_GLOBAL_LOG_REL); |
| 29 | // Either log may have rotated (kimi-code.log.1, .2, …); discover the active |
| 30 | // file plus its archives so a bundle with only rotated logs still surfaces. |
| 31 | const sessionFiles = await discoverLogFiles(sessionLog); |
| 32 | const globalFiles = await discoverLogFiles(globalLog); |
| 33 | const available = { |
| 34 | session: sessionFiles.length > 0, |
| 35 | global: globalFiles.length > 0, |
| 36 | }; |
| 37 | const targetFiles = which === 'global' ? globalFiles : sessionFiles; |
| 38 | const result = await readLogs(targetFiles); |
| 39 | return c.json({ |
| 40 | sessionId: id, |
| 41 | which, |
| 42 | available, |
| 43 | lines: result?.lines ?? [], |
| 44 | truncated: result?.truncated ?? false, |
| 45 | }); |
| 46 | }); |
| 47 | return r; |
| 48 | } |
no test coverage detected