fix: resolve all 14 test failures to 0

- Remove duplicate notifyAutomationStateChanged that shadowed real impl (sessionState 3→0)
- Fix messages.ts stub: re-export instead of type-only (ExecuteTool/VaultHttpFetch mock leaks)
- Fix CWD-dependent paths in queryModelOpenAI and VaultHttpFetch tests (use import.meta.url)
- Add missing logger.ts stub for remote-control-server
- CI: add --isolate flag, baseline 14→0
- Tests: 3643 pass,14 fail → 3857 pass,0 fail (--isolate)
This commit is contained in:
James Feng 2026-06-05 01:17:04 +08:00
parent 2c27fd8075
commit 18f5f99e7d
6 changed files with 26 additions and 36 deletions

View File

@ -31,14 +31,14 @@ jobs:
- name: Test
run: |
set +e
bun test > /tmp/ci-test.log 2>&1
bun test --isolate > /tmp/ci-test.log 2>&1
TEST_EXIT=$?
FAILS=$(grep -oE '[0-9]+ fail' /tmp/ci-test.log | tail -1 | grep -oE '[0-9]+')
if [ -z "$FAILS" ]; then FAILS=0; fi
echo "Failures: $FAILS (baseline: 14) | bun test exit: $TEST_EXIT"
echo "Failures: $FAILS (baseline: 0) | bun test exit: $TEST_EXIT"
# Show last 30 lines of test output
tail -30 /tmp/ci-test.log
if [ "$FAILS" -le 14 ]; then
if [ "$FAILS" -le 0 ]; then
echo "✅ Test baseline OK"
else
echo "❌ Test regressions detected"

View File

@ -607,7 +607,10 @@ describe('AC18: VaultHttpFetch is in ALL_AGENT_DISALLOWED_TOOLS', () => {
test('subagent gate layer 1 registration is wired', async () => {
const fs = await import('node:fs')
const path = await import('node:path')
const file = path.resolve('src/constants/tools.ts')
const url = await import('node:url')
// Resolve relative to this test file, not CWD (--isolate changes CWD)
const testDir = path.dirname(url.fileURLToPath(import.meta.url))
const file = path.resolve(testDir, '../../../../../../src/constants/tools.ts')
const src = fs.readFileSync(file, 'utf8')
// (a) constant is imported
expect(src).toContain('VAULT_HTTP_FETCH_TOOL_NAME')

View File

@ -0,0 +1,5 @@
// Stub logger for remote-control-server (tests don't need real logging)
export function log(...args: unknown[]): void {}
export function error(...args: unknown[]): void {}
export function warn(...args: unknown[]): void {}
export function debug(...args: unknown[]): void {}

View File

@ -1,8 +1,13 @@
import { describe, expect, test } from 'bun:test'
import { resolve, dirname } from 'node:path'
import { fileURLToPath } from 'node:url'
async function runIsolatedTestFile(path: string) {
const proc = Bun.spawn([process.execPath, 'test', path], {
cwd: process.cwd(),
const testDir = dirname(fileURLToPath(import.meta.url))
const projectRoot = resolve(testDir, '../../../../..')
async function runIsolatedTestFile(relativePath: string) {
const proc = Bun.spawn([process.execPath, 'test', relativePath], {
cwd: projectRoot,
env: process.env,
stdout: 'pipe',
stderr: 'pipe',

View File

@ -1,4 +1,6 @@
// Auto-generated type stub — replace with real implementation
export type createAssistantAPIErrorMessage = any;
export type NO_RESPONSE_REQUESTED = any;
export type createSystemAPIErrorMessage = any;
// Stub — re-exports from the canonical implementation
export {
createAssistantAPIErrorMessage,
NO_RESPONSE_REQUESTED,
createSystemAPIErrorMessage,
} from '../../../../utils/messages.js'

View File

@ -255,31 +255,6 @@ export function notifyPermissionModeChanged(mode: PermissionMode): void {
permissionModeListener?.(mode)
}
// ── Automation state (PROACTIVE / KAIROS) ──────────────────────
// Pushed by SleepTool when the autonomous agent enters/leaves sleep.
// Consumers (CCR sidebar, PromptInput footer) render a status indicator
// so the user knows the agent is intentionally idle, not crashed.
export type AutomationState = {
enabled: boolean
phase: string | null // 'sleeping' | null
next_tick_at: number | null
sleep_until: number | null
} | null
type AutomationStateChangedListener = (state: AutomationState) => void
let automationStateListener: AutomationStateChangedListener | null = null
export function setAutomationStateChangedListener(
cb: AutomationStateChangedListener | null,
): void {
automationStateListener = cb
}
export function notifyAutomationStateChanged(state: AutomationState): void {
automationStateListener?.(state)
}
export function resetSessionStateForTests(): void {
stateListener = null
metadataListener = null