feat(logging): unify CCS runtime logs and dashboard viewer

- add a shared structured logging service with bounded retention

- expose native /api/logs endpoints and the dashboard /logs route

- wire focused runtime emitters, cleanup support, and feature tests

Refs #926
This commit is contained in:
Tam Nhu Tran committed 2026-04-08 15:57:15 -04:00
1 parent 548edda58b
commit 6c799b2e58
36 files changed
+1648 -48

No files matched your search

@@ -0,0 +1,46 @@
import { afterEach, beforeEach, describe, expect, it } from 'bun:test';
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import {
getCurrentLogPath,
getLogArchiveDir,
getNativeLogsDir,
isPathInsideDirectory,
} from '../../../../src/services/logging';
describe('logging path helpers', () => {
let tempHome = '';
let originalCcsHome: string | undefined;
beforeEach(() => {
originalCcsHome = process.env.CCS_HOME;
tempHome = fs.mkdtempSync(path.join(os.tmpdir(), 'ccs-log-paths-'));
process.env.CCS_HOME = tempHome;
});
afterEach(() => {
if (originalCcsHome !== undefined) {
process.env.CCS_HOME = originalCcsHome;
} else {
delete process.env.CCS_HOME;
}
fs.rmSync(tempHome, { recursive: true, force: true });
tempHome = '';
});
it('resolves native log paths inside the scoped CCS directory', () => {
expect(getNativeLogsDir()).toBe(path.join(tempHome, '.ccs', 'logs'));
expect(getCurrentLogPath()).toBe(path.join(tempHome, '.ccs', 'logs', 'current.jsonl'));
expect(getLogArchiveDir()).toBe(path.join(tempHome, '.ccs', 'logs', 'archive'));
});
it('rejects path escapes outside the CCS log root', () => {
const logsDir = getNativeLogsDir();
expect(isPathInsideDirectory(path.join(logsDir, 'archive', 'entry.gz'), logsDir)).toBe(true);
expect(isPathInsideDirectory(path.join(logsDir, '..', '..', 'etc', 'passwd'), logsDir)).toBe(
false
);
});
});