Skip to content

Commit b9c8366

Browse files
LHMQ878cursoragent
andcommitted
fix: reset compress-pending manual mode after compression
After /dcp-compress, finalizeSession must not treat compress-pending as active manual mode, which permanently blocked automatic compression. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 85b6f5c commit b9c8366

2 files changed

Lines changed: 97 additions & 1 deletion

File tree

lib/compress/pipeline.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ export async function finalizeSession(
8585
entries: NotificationEntry[],
8686
batchTopic: string | undefined,
8787
): Promise<void> {
88-
ctx.state.manualMode = ctx.state.manualMode ? "active" : false
88+
ctx.state.manualMode = ctx.state.manualMode === "active" ? "active" : false
8989
applyPendingCompressionDurations(ctx.state)
9090
await saveSessionState(ctx.state, ctx.logger)
9191

tests/finalize-session.test.ts

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import assert from "node:assert/strict"
2+
import test from "node:test"
3+
import { finalizeSession } from "../lib/compress/pipeline"
4+
import type { PluginConfig } from "../lib/config"
5+
import { Logger } from "../lib/logger"
6+
import {
7+
createSessionState,
8+
loadManualModeSetting,
9+
type WithParts,
10+
} from "../lib/state"
11+
12+
function buildConfig(): PluginConfig {
13+
return {
14+
enabled: true,
15+
debug: false,
16+
pruneNotification: "off",
17+
pruneNotificationType: "chat",
18+
commands: { enabled: true, protectedTools: [] },
19+
manualMode: { enabled: false, automaticStrategies: true },
20+
turnProtection: { enabled: false, turns: 4 },
21+
experimental: { allowSubAgents: false, customPrompts: false },
22+
protectedFilePatterns: [],
23+
compress: {
24+
mode: "message",
25+
permission: "allow",
26+
showCompression: false,
27+
maxContextLimit: 150000,
28+
minContextLimit: 50000,
29+
nudgeFrequency: 5,
30+
iterationNudgeThreshold: 15,
31+
nudgeForce: "soft",
32+
protectedTools: ["task"],
33+
protectTags: false,
34+
protectUserMessages: false,
35+
},
36+
strategies: {
37+
deduplication: { enabled: true, protectedTools: [] },
38+
purgeErrors: { enabled: true, turns: 4, protectedTools: [] },
39+
},
40+
} as PluginConfig
41+
}
42+
43+
function buildToolContext(state: ReturnType<typeof createSessionState>) {
44+
return {
45+
client: { session: { get: async () => ({}) } },
46+
state,
47+
logger: new Logger(false),
48+
config: buildConfig(),
49+
prompts: {
50+
reload() {},
51+
getRuntimePrompts() {
52+
return {} as any
53+
},
54+
},
55+
}
56+
}
57+
58+
test("finalizeSession resets compress-pending to auto mode", async () => {
59+
const sessionId = `finalize-compress-pending-${Date.now()}`
60+
const state = createSessionState()
61+
state.sessionId = sessionId
62+
state.manualMode = "compress-pending"
63+
64+
await finalizeSession(
65+
buildToolContext(state) as any,
66+
{ sessionID: sessionId, metadata: () => {}, ask: async () => {} },
67+
[] as WithParts[],
68+
[],
69+
undefined,
70+
)
71+
72+
assert.equal(state.manualMode, false)
73+
74+
const persisted = await loadManualModeSetting(sessionId, new Logger(false))
75+
assert.equal(persisted, false)
76+
})
77+
78+
test("finalizeSession preserves explicit active manual mode", async () => {
79+
const sessionId = `finalize-active-manual-${Date.now()}`
80+
const state = createSessionState()
81+
state.sessionId = sessionId
82+
state.manualMode = "active"
83+
84+
await finalizeSession(
85+
buildToolContext(state) as any,
86+
{ sessionID: sessionId, metadata: () => {}, ask: async () => {} },
87+
[] as WithParts[],
88+
[],
89+
undefined,
90+
)
91+
92+
assert.equal(state.manualMode, "active")
93+
94+
const persisted = await loadManualModeSetting(sessionId, new Logger(false))
95+
assert.equal(persisted, true)
96+
})

0 commit comments

Comments
 (0)