Files
oh-my-claudecode/dist/__tests__/hud/watch-mode-init.test.js
Codex Review 287565314b chore(release): bump version to v4.11.6
- Ralph security hardening: PRD gating non-bypassable, approval spoofing closed
- Permission handler: narrowed trust boundary, read-only gh commands allowed
- HUD: MiniMax coding plan provider, extra usage spend data, per-provider cache split
- tmux/openclaw: dead-pane suppression, stale replay suppression, keyword false-positive reduction
- Context dedup: no duplicate rule/skill injection from coexisting plugin+standalone
- Installer: user skills with OMC-style frontmatter preserved during updates
- Test isolation fix: hud-marketplace-resolution afterAll + setup-contracts-regression beforeAll
  restore hooks/hooks.json to prevent parallel worker race in full test suite

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 14:03:35 +00:00

155 lines
6.7 KiB
JavaScript
Generated

import { beforeEach, afterEach, describe, expect, it, vi } from 'vitest';
const fakeStdin = {
cwd: '/tmp/worktree',
transcript_path: '/tmp/worktree/transcript.jsonl',
model: { id: 'claude-test' },
context_window: {
used_percentage: 12,
current_usage: { input_tokens: 10, cache_creation_input_tokens: 0, cache_read_input_tokens: 0 },
context_window_size: 100,
},
};
const fakeConfig = {
preset: 'focused',
elements: {
rateLimits: false,
apiKeySource: false,
safeMode: false,
missionBoard: false,
},
thresholds: {
contextWarning: 70,
contextCritical: 85,
},
staleTaskThresholdMinutes: 30,
contextLimitWarning: {
autoCompact: false,
threshold: 90,
},
missionBoard: {
enabled: false,
},
usageApiPollIntervalMs: 300000,
};
describe('HUD watch mode initialization', () => {
const originalIsTTY = Object.getOwnPropertyDescriptor(process.stdin, 'isTTY');
let initializeHUDState;
let readRalphStateForHud;
let readUltraworkStateForHud;
let readAutopilotStateForHud;
let consoleLogSpy;
let consoleErrorSpy;
async function importHudModule() {
vi.resetModules();
initializeHUDState = vi.fn(async () => { });
readRalphStateForHud = vi.fn(() => null);
readUltraworkStateForHud = vi.fn(() => null);
readAutopilotStateForHud = vi.fn(() => null);
vi.doMock('../../hud/stdin.js', () => ({
readStdin: vi.fn(async () => null),
writeStdinCache: vi.fn(),
readStdinCache: vi.fn(() => fakeStdin),
getContextPercent: vi.fn(() => 12),
getModelName: vi.fn(() => 'claude-test'),
}));
vi.doMock('../../hud/transcript.js', () => ({
parseTranscript: vi.fn(async () => ({
agents: [],
todos: [],
lastActivatedSkill: null,
pendingPermission: null,
thinkingState: null,
toolCallCount: 0,
agentCallCount: 0,
skillCallCount: 0,
sessionStart: null,
})),
}));
vi.doMock('../../hud/state.js', () => ({
initializeHUDState,
readHudConfig: vi.fn(() => fakeConfig),
readHudState: vi.fn(() => null),
getRunningTasks: vi.fn(() => []),
writeHudState: vi.fn(() => true),
}));
vi.doMock('../../hud/omc-state.js', () => ({
readRalphStateForHud,
readUltraworkStateForHud,
readPrdStateForHud: vi.fn(() => null),
readAutopilotStateForHud,
}));
vi.doMock('../../hud/usage-api.js', () => ({ getUsage: vi.fn(async () => null) }));
vi.doMock('../../hud/custom-rate-provider.js', () => ({ executeCustomProvider: vi.fn(async () => null) }));
vi.doMock('../../hud/render.js', () => ({ render: vi.fn(async () => '[HUD] ok') }));
vi.doMock('../../hud/elements/api-key-source.js', () => ({ detectApiKeySource: vi.fn(() => null) }));
vi.doMock('../../hud/mission-board.js', () => ({ refreshMissionBoardState: vi.fn(async () => null) }));
vi.doMock('../../hud/sanitize.js', () => ({ sanitizeOutput: vi.fn((value) => value) }));
vi.doMock('../../lib/version.js', () => ({ getRuntimePackageVersion: vi.fn(() => '4.7.9') }));
vi.doMock('../../features/auto-update.js', () => ({ compareVersions: vi.fn(() => 0) }));
vi.doMock('../../lib/worktree-paths.js', () => ({
resolveToWorktreeRoot: vi.fn((cwd) => cwd ?? '/tmp/worktree'),
resolveTranscriptPath: vi.fn((transcriptPath) => transcriptPath),
getOmcRoot: vi.fn(() => '/tmp/worktree/.omc'),
}));
return import('../../hud/index.js');
}
beforeEach(() => {
Object.defineProperty(process.stdin, 'isTTY', {
configurable: true,
value: true,
});
consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => { });
});
afterEach(() => {
fakeStdin.transcript_path = '/tmp/worktree/transcript.jsonl';
vi.resetModules();
vi.clearAllMocks();
vi.doUnmock('../../hud/stdin.js');
vi.doUnmock('../../hud/transcript.js');
vi.doUnmock('../../hud/state.js');
vi.doUnmock('../../hud/omc-state.js');
vi.doUnmock('../../hud/usage-api.js');
vi.doUnmock('../../hud/custom-rate-provider.js');
vi.doUnmock('../../hud/render.js');
vi.doUnmock('../../hud/elements/api-key-source.js');
vi.doUnmock('../../hud/mission-board.js');
vi.doUnmock('../../hud/sanitize.js');
vi.doUnmock('../../lib/version.js');
vi.doUnmock('../../features/auto-update.js');
vi.doUnmock('../../lib/worktree-paths.js');
consoleLogSpy.mockRestore();
consoleErrorSpy.mockRestore();
if (originalIsTTY) {
Object.defineProperty(process.stdin, 'isTTY', originalIsTTY);
}
});
it('skips HUD initialization during watch polls after the first render', async () => {
const hud = await importHudModule();
initializeHUDState.mockClear();
await hud.main(true, true);
expect(initializeHUDState).not.toHaveBeenCalled();
});
it('still initializes HUD state for the first watch render', async () => {
const hud = await importHudModule();
initializeHUDState.mockClear();
await hud.main(true, false);
expect(initializeHUDState).toHaveBeenCalledTimes(1);
});
it('passes resolved cwd to initializeHUDState instead of defaulting to process.cwd()', async () => {
const hud = await importHudModule();
initializeHUDState.mockClear();
await hud.main(true, false);
// initializeHUDState must receive the resolved cwd from stdin, not undefined/process.cwd()
expect(initializeHUDState).toHaveBeenCalledWith('/tmp/worktree', undefined);
});
it('passes the current session id to OMC state readers', async () => {
const hud = await importHudModule();
fakeStdin.transcript_path = '/tmp/worktree/transcripts/123e4567-e89b-12d3-a456-426614174000.jsonl';
await hud.main(true, false);
expect(readRalphStateForHud).toHaveBeenCalledWith('/tmp/worktree', '123e4567-e89b-12d3-a456-426614174000');
expect(readUltraworkStateForHud).toHaveBeenCalledWith('/tmp/worktree', '123e4567-e89b-12d3-a456-426614174000');
expect(readAutopilotStateForHud).toHaveBeenCalledWith('/tmp/worktree', '123e4567-e89b-12d3-a456-426614174000');
});
});
//# sourceMappingURL=watch-mode-init.test.js.map