From 2dd926a5b194f4fefdea02fd9e5fb72e40130fad Mon Sep 17 00:00:00 2001 From: jatmn Date: Wed, 15 Jul 2026 18:35:58 -0700 Subject: [PATCH 1/3] test: restore compact test module stubs --- src/services/compact/compact.test.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/services/compact/compact.test.ts b/src/services/compact/compact.test.ts index 06e5d97be5..74de3e9519 100644 --- a/src/services/compact/compact.test.ts +++ b/src/services/compact/compact.test.ts @@ -72,6 +72,15 @@ const _realConfigModule = await import( const _realProjectInstructionsModule = await import( `../../utils/projectInstructions.js?real=${Date.now()}-${Math.random()}` ) +const _realTokenEstimationModule = await import( + `../tokenEstimation.js?real=${Date.now()}-${Math.random()}` +) +const _realClaudeApiModule = await import( + `../api/claude.js?real=${Date.now()}-${Math.random()}` +) +const _realGrowthBookModule = await import( + `../analytics/growthbook.js?real=${Date.now()}-${Math.random()}` +) // --------------------------------------------------------------------------- // Helpers @@ -669,6 +678,11 @@ afterAll(async () => { mock.module('../../utils/auth.js', () => ({ ..._realAuthModule })) mock.module('../../utils/path.js', () => ({ ..._realPathModule })) mock.module('../../utils/config.js', () => ({ ..._realConfigModule })) + // These compact-only stubs affect the standalone microcompact and + // auto-compact tests that run later in the serialized smoke suite. + mock.module('../tokenEstimation.js', () => ({ ..._realTokenEstimationModule })) + mock.module('../api/claude.js', () => ({ ..._realClaudeApiModule })) + mock.module('../analytics/growthbook.js', () => ({ ..._realGrowthBookModule })) // projectInstructions: the stub above replaces the whole module with only // getProjectInstructionFilePaths, so every other export becomes undefined. // Downstream CLAUDE.md discovery in runAgent.routing.test.ts then crashes in From 39ff243f0478493fd6229dd58ea4b2a635a939f7 Mon Sep 17 00:00:00 2001 From: jatmn Date: Wed, 15 Jul 2026 19:14:49 -0700 Subject: [PATCH 2/3] test: restore remaining compact mock modules --- src/services/compact/compact.test.ts | 79 ++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/src/services/compact/compact.test.ts b/src/services/compact/compact.test.ts index 74de3e9519..086f5532d8 100644 --- a/src/services/compact/compact.test.ts +++ b/src/services/compact/compact.test.ts @@ -81,6 +81,60 @@ const _realClaudeApiModule = await import( const _realGrowthBookModule = await import( `../analytics/growthbook.js?real=${Date.now()}-${Math.random()}` ) +const _realContextModule = await import( + `../../utils/context.js?real=${Date.now()}-${Math.random()}` +) +const _realErrorsModule = await import( + `../../utils/errors.js?real=${Date.now()}-${Math.random()}` +) +const _realTokensModule = await import( + `../../utils/tokens.js?real=${Date.now()}-${Math.random()}` +) + +const COMPACT_STUB_MODULES = [ + '../analytics/growthbook.js', + '../analytics/index.js', + '../api/claude.js', + '../api/errors.js', + '../api/promptCacheBreakDetection.js', + '../api/withRetry.js', + '../tokenEstimation.js', + '../../bootstrap/state.js', + '../../tools/FileReadTool/FileReadTool.js', + '../../tools/FileReadTool/prompt.js', + '../../tools/ToolSearchTool/ToolSearchTool.js', + '../../utils/attachments.js', + '../../utils/auth.js', + '../../utils/config.js', + '../../utils/context.js', + '../../utils/contextAnalysis.js', + '../../utils/debug.js', + '../../utils/errors.js', + '../../utils/fileStateCache.js', + '../../utils/forkedAgent.js', + '../../utils/hooks.js', + '../../utils/log.js', + '../../utils/memory/types.js', + '../../utils/messages.js', + '../../utils/messages/systemFactories.js', + '../../utils/model/model.js', + '../../utils/model/modelSupportOverrides.js', + '../../utils/path.js', + '../../utils/plans.js', + '../../utils/projectInstructions.js', + '../../utils/sessionActivity.js', + '../../utils/sessionStart.js', + '../../utils/sessionStorage.js', + '../../utils/settings/settings.js', + '../../utils/sleep.js', + '../../utils/slowOperations.js', + '../../utils/systemPromptType.js', + '../../utils/task/diskOutput.js', + '../../utils/tokens.js', + '../../utils/toolSearch.js', + './grouping.js', + './prompt.js', +] as const // --------------------------------------------------------------------------- // Helpers @@ -644,6 +698,12 @@ afterEach(() => { afterAll(async () => { mock.restore() clearProviderEnv() + for (const specifier of COMPACT_STUB_MODULES) { + const realModule = await import( + `${specifier}?real=${Date.now()}-${Math.random()}` + ) + mock.module(specifier, () => ({ ...realModule })) + } // The compact test registers many mock.module() stubs that persist // process-wide. Restore the real implementations so downstream test files // (goal controller, runAgent routing, BashTool) get correct behaviour. @@ -683,6 +743,25 @@ afterAll(async () => { mock.module('../tokenEstimation.js', () => ({ ..._realTokenEstimationModule })) mock.module('../api/claude.js', () => ({ ..._realClaudeApiModule })) mock.module('../analytics/growthbook.js', () => ({ ..._realGrowthBookModule })) + mock.module('../../utils/context.js', () => ({ ..._realContextModule })) + mock.module('../../utils/errors.js', () => ({ ..._realErrorsModule })) + mock.module('../../utils/tokens.js', () => ({ ..._realTokensModule })) + // Keep the cleanup load-bearing: these modules are consumed by standalone + // auto-compact tests when this file happens to run first in the smoke suite. + const [restoredContext, restoredErrors, restoredTokens] = await Promise.all([ + import('../../utils/context.js'), + import('../../utils/errors.js'), + import('../../utils/tokens.js'), + ]) + expect(restoredContext.getContextWindowForModel).toBe( + _realContextModule.getContextWindowForModel, + ) + expect(restoredErrors.hasExactErrorMessage).toBe( + _realErrorsModule.hasExactErrorMessage, + ) + expect(restoredTokens.tokenCountWithEstimation).toBe( + _realTokensModule.tokenCountWithEstimation, + ) // projectInstructions: the stub above replaces the whole module with only // getProjectInstructionFilePaths, so every other export becomes undefined. // Downstream CLAUDE.md discovery in runAgent.routing.test.ts then crashes in From 30370185fb5889a677bb94489ca3eaa20b77d97c Mon Sep 17 00:00:00 2001 From: jatmn Date: Wed, 15 Jul 2026 19:51:07 -0700 Subject: [PATCH 3/3] test: isolate auto compact from compact mocks --- src/services/compact/autoCompact.test.ts | 15 +++++++++++++++ src/services/compact/compact.test.ts | 21 ++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/services/compact/autoCompact.test.ts b/src/services/compact/autoCompact.test.ts index 35a636cd83..c59a398bd1 100644 --- a/src/services/compact/autoCompact.test.ts +++ b/src/services/compact/autoCompact.test.ts @@ -14,6 +14,16 @@ import { import type { Message } from '../../types/message.js' import * as realConfig from '../../utils/config.js' +const realContext = await import( + `../../utils/context.js?real=${Date.now()}-${Math.random()}` +) +const realErrors = await import( + `../../utils/errors.js?real=${Date.now()}-${Math.random()}` +) +const realTokens = await import( + `../../utils/tokens.js?real=${Date.now()}-${Math.random()}` +) + const USER_ABORT_MESSAGE = 'API Error: Request was aborted.' type ImportAutoCompactOptions = { @@ -22,6 +32,11 @@ type ImportAutoCompactOptions = { } async function importAutoCompact(options: ImportAutoCompactOptions = {}) { + // compact.test.ts uses process-global module stubs. Re-register the real + // dependencies this standalone suite needs before importing autoCompact. + mock.module('../../utils/context.js', () => ({ ...realContext })) + mock.module('../../utils/errors.js', () => ({ ...realErrors })) + mock.module('../../utils/tokens.js', () => ({ ...realTokens })) mock.module('../../utils/config.js', () => ({ ...realConfig, getGlobalConfig: () => ({ autoCompactEnabled: true }), diff --git a/src/services/compact/compact.test.ts b/src/services/compact/compact.test.ts index 086f5532d8..4e37bcf217 100644 --- a/src/services/compact/compact.test.ts +++ b/src/services/compact/compact.test.ts @@ -748,10 +748,20 @@ afterAll(async () => { mock.module('../../utils/tokens.js', () => ({ ..._realTokensModule })) // Keep the cleanup load-bearing: these modules are consumed by standalone // auto-compact tests when this file happens to run first in the smoke suite. - const [restoredContext, restoredErrors, restoredTokens] = await Promise.all([ + const [ + restoredContext, + restoredErrors, + restoredTokens, + restoredTokenEstimation, + restoredClaudeApi, + restoredGrowthBook, + ] = await Promise.all([ import('../../utils/context.js'), import('../../utils/errors.js'), import('../../utils/tokens.js'), + import('../tokenEstimation.js'), + import('../api/claude.js'), + import('../analytics/growthbook.js'), ]) expect(restoredContext.getContextWindowForModel).toBe( _realContextModule.getContextWindowForModel, @@ -762,6 +772,15 @@ afterAll(async () => { expect(restoredTokens.tokenCountWithEstimation).toBe( _realTokensModule.tokenCountWithEstimation, ) + expect(restoredTokenEstimation.roughTokenCountEstimation).toBe( + _realTokenEstimationModule.roughTokenCountEstimation, + ) + expect(restoredClaudeApi.getMaxOutputTokensForModel).toBe( + _realClaudeApiModule.getMaxOutputTokensForModel, + ) + expect(restoredGrowthBook.getFeatureValue_CACHED_MAY_BE_STALE).toBe( + _realGrowthBookModule.getFeatureValue_CACHED_MAY_BE_STALE, + ) // projectInstructions: the stub above replaces the whole module with only // getProjectInstructionFilePaths, so every other export becomes undefined. // Downstream CLAUDE.md discovery in runAgent.routing.test.ts then crashes in