mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-09-30 12:39:42 +02:00
- CI: add a 'test' job running the unit suite via config/vitest.ci.config.ts. Excludes browser (Playwright/chromium) and perf tests (timing-flaky), like the existing test/mobile suite. Safe in CI: TmuxManager no-ops shell commands under VITEST (test/setup.ts). - Add scripts/check-frontend-syntax.mjs (node --check on src/web/public/*.js), wired into the lint job — catches a class of frontend SyntaxError that passes lint today (lint globs only TS). - Add test/security-regression.test.ts (wired Host/Origin guard, self-update CSRF, CSP/security headers, text/plain raw body, WS anti-CSWSH) + test/sse-registry-parity.test.ts (backend<->frontend SSE registry parity). - Green pre-existing test debt surfaced by the new gate: stale 'Session not found' asserts -> 'not found' substring; drop tests for removed helpers (isError now internal; createSuccessResponse deleted); file-stream-manager: mock realpathSync + fix stale /tmp assertion; sse-subscription-filter: lifecycle events broadcast to all clients (only terminal stream filtered); session.test.ts: mkdir /tmp/test; skip one interactive-respawn test needing a real PTY (covered by respawn-controller.test.ts). - Full non-mobile suite verified green locally (2680 passed, 12 skipped). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
41 lines
1.4 KiB
JavaScript
41 lines
1.4 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Frontend JS syntax check.
|
|
*
|
|
* CI's `npm run lint` only lints TypeScript under src/, and `tsc` excludes the
|
|
* frontend — so a plain SyntaxError in a shipped `src/web/public` script (loaded
|
|
* as a bare <script>, no bundler) passes CI green yet breaks the whole module at
|
|
* load.
|
|
* (This is exactly how PR #112's duplicate-`const` error in session-ui.js slipped
|
|
* through.) This runs `node --check` (parse-only; browser globals don't matter)
|
|
* on every shipped frontend script so that class of bug fails fast.
|
|
*/
|
|
import { readdirSync } from 'node:fs';
|
|
import { join, dirname } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { execFileSync } from 'node:child_process';
|
|
|
|
const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..');
|
|
const PUBLIC_DIR = join(ROOT, 'src', 'web', 'public');
|
|
|
|
const files = readdirSync(PUBLIC_DIR)
|
|
.filter((f) => f.endsWith('.js'))
|
|
.map((f) => join(PUBLIC_DIR, f));
|
|
|
|
let failed = 0;
|
|
for (const file of files) {
|
|
try {
|
|
execFileSync(process.execPath, ['--check', file], { stdio: 'pipe' });
|
|
} catch (err) {
|
|
failed++;
|
|
const msg = err.stderr ? err.stderr.toString() : String(err);
|
|
console.error(`✗ syntax error in ${file.replace(ROOT + '/', '')}:\n${msg}`);
|
|
}
|
|
}
|
|
|
|
if (failed > 0) {
|
|
console.error(`\n${failed} frontend file(s) failed the syntax check.`);
|
|
process.exit(1);
|
|
}
|
|
console.log(`✓ ${files.length} frontend JS files parse cleanly`);
|