import { test } from 'node:test' import assert from 'node:assert/strict' import fs from 'node:fs' import os from 'node:os' import path from 'node:path' import { runReportCommand, resolveRunId } from '../src/reportcli.mjs' function collector() { let text = '' return { stream: { write: (s) => { text += s; return true } }, get: () => text, } } function seedRun() { const project = fs.mkdtempSync(path.join(os.tmpdir(), 'kilo-report-')) const dir = path.join(project, '.kilocode-loop', 'runs', 'run-1') fs.mkdirSync(dir, { recursive: true }) fs.writeFileSync(path.join(dir, 'report.md'), '# Run run-1\n\nAll good.\n') fs.writeFileSync(path.join(dir, 'state.json'), JSON.stringify({ runId: 'run-1', status: 'done', apiKey: 'sk-1234567890abcdefghij' })) return project } test('resolveRunId picks the requested run or the most recent', () => { const project = seedRun() const base = path.join(project, '.kilocode-loop', 'runs') assert.equal(resolveRunId(base, { runId: 'run-1', last: false }), 'run-1') assert.equal(resolveRunId(base, { runId: '', last: true }), 'run-1') }) test('report subcommand prints the saved markdown report', () => { const project = seedRun() const out = collector() const code = runReportCommand(['run-1', '--project', project], { stdout: out.stream, stderr: out.stream }) assert.equal(code, 0) assert.match(out.get(), /# Run run-1/) }) test('report --json emits redacted state', () => { const project = seedRun() const out = collector() const code = runReportCommand(['run-1', '--json', '--project', project], { stdout: out.stream, stderr: out.stream }) assert.equal(code, 0) const parsed = JSON.parse(out.get()) assert.equal(parsed.runId, 'run-1') assert.match(parsed.apiKey, /\[REDACTED\]/) }) test('report fails clearly when there are no runs', () => { const project = fs.mkdtempSync(path.join(os.tmpdir(), 'kilo-noruns-')) const out = collector() const code = runReportCommand(['--project', project], { stdout: out.stream, stderr: out.stream }) assert.equal(code, 1) assert.match(out.get(), /No saved runs/) })