@@ -33,12 +33,10 @@ import { log } from "./log.js";
3333 */
3434const SESSION_POLL_MS = 3_000 ;
3535
36- /** Threshold above which we warn the user to close the session. Chosen
37- * to match the upper end of Cursor's reported auto-summarize trigger
38- * (~50–60% of context window for 200k models) so the user has a chance
39- * to close cleanly via our handoff flow BEFORE Cursor's lossy condense
40- * fires. */
41- const SESSION_WARN_TOKENS = 200_000 ;
36+ // (Old SESSION_WARN_TOKENS dropped — we no longer display a token number
37+ // in the session block. See "Live session block" comment in the render
38+ // code for the rationale. Threshold is now message-count + duration in
39+ // the render code itself: >50 messages OR >2h triggers the warning.)
4240
4341export interface SidebarState {
4442 /** Is the workspace initialised (`.axme-code/` exists)? */
@@ -55,10 +53,10 @@ export interface SidebarState {
5553 hooksOk : boolean ;
5654 /** Are we running in Cursor (vs other host)? */
5755 isCursor : boolean ;
58- /** Live snapshot of the active chat session — tokens, messages, age. */
56+ /** Live snapshot of the active chat session — messages, age (tokens are
57+ * collected but no longer displayed; see "Live session block" comment
58+ * in the render code for the rationale). */
5959 session : ActiveSession | null ;
60- /** Warn threshold (passed to webview so it can hide its own UI). */
61- warnTokens : number ;
6260}
6361
6462export type SidebarMessage =
@@ -85,7 +83,7 @@ export class AxmeSidebarProvider implements vscode.WebviewViewProvider {
8583
8684 constructor (
8785 private readonly context : vscode . ExtensionContext ,
88- private readonly initialState : Omit < SidebarState , "counts" | "backlog" | "auditorKeyConfigured" | "session" | "warnTokens" > ,
86+ private readonly initialState : Omit < SidebarState , "counts" | "backlog" | "auditorKeyConfigured" | "session" > ,
8987 ) { }
9088
9189 attach ( workspaceRoot : string | undefined , binary : string ) : void {
@@ -152,7 +150,6 @@ export class AxmeSidebarProvider implements vscode.WebviewViewProvider {
152150 counts,
153151 backlog,
154152 hooksOk : hooksAreInstalled ( ) ,
155- warnTokens : SESSION_WARN_TOKENS ,
156153 ...this . pendingState ,
157154 } ) ;
158155 this . pendingState = { } ;
@@ -441,7 +438,7 @@ select, input[type=text], input[type=password] {
441438
442439const SIDEBAR_JS = `
443440const vscode = acquireVsCodeApi();
444- let S = { setupDone: false, counts: { memories:0, decisions:0, safety:0, backlog:0, questions:0 }, backlog: [], auditorMode: "cooperative", auditorKeyConfigured: false, hooksOk: false, isCursor: true, session: null, warnTokens: 200000 };
441+ let S = { setupDone: false, counts: { memories:0, decisions:0, safety:0, backlog:0, questions:0 }, backlog: [], auditorMode: "cooperative", auditorKeyConfigured: false, hooksOk: false, isCursor: true, session: null };
445442
446443function formatDuration(ms) {
447444 if (ms <= 0) return "just now";
@@ -453,11 +450,8 @@ function formatDuration(ms) {
453450 const rm = m % 60;
454451 return h + "h " + (rm ? rm + "m" : "");
455452}
456- function formatTokens(n) {
457- if (n < 1000) return n + "";
458- if (n < 100000) return (n / 1000).toFixed(1).replace(/\\.0$/, "") + "k";
459- return Math.round(n / 1000) + "k";
460- }
453+ // formatTokens was used by the old Tokens row in the session block.
454+ // Variant B dropped that row — function removed to keep dead code out.
461455
462456function send(msg) { vscode.postMessage(msg); }
463457function cmd(id) { send({ type: "command", commandId: id }); }
@@ -554,22 +548,32 @@ function render() {
554548 });
555549
556550 // Live session block — driven by readActiveSession on the host side.
551+ // We deliberately do NOT show a token count: our only data source is the
552+ // local Cursor JSONL transcript which contains compact message envelopes,
553+ // not the expanded tool results that dominate Cursor's actual context
554+ // budget. Showing "3.8k" while Cursor's own Context panel shows 43.5k
555+ // confused users more than it helped. Instead we show two signals we CAN
556+ // measure honestly: messages (count) and duration (age).
557+ //
558+ // Warning threshold uses both. >50 messages OR >2h is a reasonable
559+ // proxy for "you're heading toward Cursor's ~50–60% auto-summarize
560+ // trigger" without lying about a token number we can't see.
557561 const sess = S.session;
558562 let sessionHtml = '<p class="muted">No active chat detected. Tools will record activity when an MCP call lands.</p>';
559563 if (sess && sess.hasData) {
560564 const startedMs = Date.parse(sess.startedAt);
561565 const ageMs = Number.isFinite(startedMs) ? Date.now() - startedMs : 0;
562- const overWarn = sess.tokens >= S.warnTokens;
566+ const ageHours = ageMs / 3_600_000;
567+ const overWarn = sess.messages >= 50 || ageHours >= 2;
563568 sessionHtml = \`
564569 <div class="row"><span class="k">Started</span><span class="v">\${formatDuration(ageMs)} ago</span></div>
565- <div class="row"><span class="k">Tokens</span><span class="v">\${formatTokens(sess.tokens)}</span></div>
566570 <div class="row"><span class="k">Messages</span><span class="v">\${sess.messages}</span></div>
567571 \${overWarn ? \`
568572 <div class="warning-banner">
569- Approaching Cursor's auto-summarize threshold. Cursor will compress
570- your conversation around here and quality often degrades after that.
571- Ask the agent in the chat to <b>close the session</b> — it will
572- extract memories / decisions / safety inline and give you a
573+ Session is getting long (\${sess.messages} messages, \${formatDuration(ageMs)}).
574+ Cursor auto-summarizes around the ~50% context mark and quality often
575+ regresses after that. Ask the agent to <b>close the session</b> —
576+ it will extract memories / decisions / safety inline and give you a
573577 startup prompt for a fresh chat with zero context loss.
574578 </div>\` : ""}
575579 \`;
0 commit comments