Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 159 additions & 0 deletions packages/cli/src/__tests__/pi-transcript.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,165 @@ describe('Maka Pi TUI transcript', () => {
);
});

test('status line drops whole low-value segments on overflow, lowest rank first (#3421)', () => {
const richMeta = {
...meta(),
modelContextWindow: 500_000,
usage: {
costUsd: 0.42,
cacheHitInput: 60,
cacheMissInput: 40,
contextRemaining: 480_000,
},
};
// Wide: everything renders.
const wide = stripAnsi(renderMakaPiStatusLine(richMeta, 120));
assert.match(wide, /ctx 20k\/500k 4%/);
assert.match(wide, /\$0\.42/);
assert.match(wide, /cache 60%/);
assert.match(wide, /deepseek · \/tmp\/project/);

// Below full width, cache drops before cost, and no segment is cut
// mid-token while any lower rank still survives.
const fullWidth = visibleWidth(wide);
const noCache = stripAnsi(renderMakaPiStatusLine(richMeta, fullWidth - 1));
assert.doesNotMatch(noCache, /cache/);
assert.match(noCache, /\$0\.42/);
const noCost = stripAnsi(
renderMakaPiStatusLine(richMeta, fullWidth - 'cache 60% · '.length - 1),
);
assert.doesNotMatch(noCost, /cache|\$0\.42/);
assert.match(noCost, /deepseek · \/tmp\/project/);
});

test('status line shortens cwd to its basename before dropping it (#3421)', () => {
const line = stripAnsi(
renderMakaPiStatusLine(
{
...meta(),
cwd: '/very/long/nested/project-directory',
modelContextWindow: 500_000,
usage: {
costUsd: 0,
cacheHitInput: 1,
cacheMissInput: 1,
contextRemaining: 480_000,
},
},
// Room for title, mode, model, ctx and a short tail only.
'Maka · Auto · deepseek-v4-flash · ctx 20k/500k 4% · project-directory'.length,
),
);
assert.doesNotMatch(line, /very\/long/);
assert.match(line, /project-directory/);
});

test('status line drops a drive-root cwd instead of rendering an empty basename (#3421)', () => {
const line = stripAnsi(
renderMakaPiStatusLine(
{
...meta(),
cwd: 'C:\\',
modelContextWindow: 500_000,
usage: {
costUsd: 0.5,
cacheHitInput: 1,
cacheMissInput: 1,
contextRemaining: 480_000,
},
},
40,
),
);
// C:\ has no useful basename; the segment drops cleanly rather than
// leaving an empty segment dangling after the separator.
assert.doesNotMatch(line, /C:\\/);
assert.doesNotMatch(line, /·\s*$/);
});

test('status line never drops mode, model, goal, or ctx at narrow widths (#3421)', () => {
const line = stripAnsi(
renderMakaPiStatusLine(
{
...meta(),
permissionMode: 'bypass',
modelContextWindow: 500_000,
usage: {
costUsd: 9.99,
cacheHitInput: 1,
cacheMissInput: 1,
contextRemaining: 480_000,
},
goal: {
goalId: 'goal-1',
revision: 1,
sessionId: 'session-1',
condition: 'Ship it',
setAt: Date.now() - 60_000,
iterations: 1,
maxIterations: 50,
consecutiveNoProgress: 0,
blockCap: 8,
tokenBudget: null,
tokensSpent: 0,
lastReason: null,
achievedAt: null,
pausedAt: null,
status: 'active' as const,
},
},
75,
),
);
assert.match(line, /Full access/);
assert.match(line, /deepseek-v4-flash/);
assert.match(line, /goal 1\/50/);
assert.match(line, /ctx 20k\/500k 4%/);
assert.doesNotMatch(line, /\$9\.99|cache|deepseek ·|tmp\/project/);
});

test('status line compacts every critical segment before the narrow-width fallback (#3421)', () => {
const metadata = {
...meta(),
permissionMode: 'bypass',
model: 'anthropic/claude-opus-4-1-very-long',
modelContextWindow: 500_000,
usage: {
costUsd: 9.99,
cacheHitInput: 1,
cacheMissInput: 1,
contextRemaining: 20_000,
},
goal: {
goalId: 'goal-1',
revision: 1,
sessionId: 'session-1',
condition: 'Ship it',
setAt: Date.now() - 60_000,
iterations: 1,
maxIterations: 50,
consecutiveNoProgress: 0,
blockCap: 8,
tokenBudget: null,
tokensSpent: 0,
lastReason: null,
achievedAt: null,
pausedAt: null,
status: 'active' as const,
},
};

for (const width of [40, 70, 80]) {
const line = stripAnsi(renderMakaPiStatusLine(metadata, width));
assert.ok(visibleWidth(line) <= width);
assert.match(line, /Maka/);
assert.match(line, /Full/);
assert.match(line, /anthropic/);
assert.match(line, /(?:goal |g)1\/50/);
assert.match(line, /(?:ctx .*96%|c96%)/);
}
});

test('keeps assistant text after a tool call visible after the tool block', () => {
const state = createMakaPiTranscriptState();
appendUserPrompt(state, 'inspect the package');
Expand Down
4 changes: 3 additions & 1 deletion packages/cli/src/__tests__/pi-tui-runner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3506,7 +3506,9 @@ describe('Maka Pi TUI runner', () => {
});

test('restores switched session state from stored messages', async () => {
const terminal = new FakeTerminal();
// 120 cols: the status line fits every segment, so the usage segments this
// test asserts (ctx, cache) are not priority-dropped (#3421).
const terminal = new FakeTerminal(120);
const driver = new SlashCommandDriver(
[fakeSessionSummary('session-2', '/repo')],
new Map([
Expand Down
166 changes: 142 additions & 24 deletions packages/cli/src/pi-transcript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import {
} from '@maka/core/tool-result-status';
import { type ShellRunUpdate } from '@maka/core/events';
import { homedir } from 'node:os';
import { basename } from 'node:path';
import type { MakaSessionDriver, MakaSideConversationParentStatus } from './session-driver.js';
import { BoundedChunkBuffer } from './bounded-chunk-buffer.js';
import { ansi } from './tui-ansi.js';
Expand Down Expand Up @@ -1336,38 +1337,69 @@ export function renderMakaPiStatusLine(metadata: MakaPiTranscriptMetadata, width
return fitLine(ansi.dim(sideConversationStatusLineText(metadata.sideConversation)), safeWidth);
}
const sep = ansi.dim(' · ');
const parts: string[] = [
ansi.bold(metadata.title),
ansi.dim(permissionModeLabel(metadata.permissionMode)),
ansi.dim(metadata.model),
// #3421: segments carry a dropRank so overflow drops whole low-value
// segments instead of cutting the chain mid-token from the right.
// Lower ranks drop first; segments without a rank never drop:
// title, permission mode and goal are safety-relevant, ctx is the
// context budget, model is the session's identity.
const parts: MakaPiStatusLineSegment[] = [
{
text: ansi.bold(metadata.title),
compactRank: 1,
shortenedText: ansi.bold(fitLine(metadata.title, 7)),
},
{
text: ansi.dim(permissionModeLabel(metadata.permissionMode)),
compactRank: 4,
shortenedText: ansi.dim(compactPermissionModeLabel(metadata.permissionMode)),
},
{
text: ansi.dim(metadata.model),
compactRank: 0,
shortenedText: ansi.dim(fitLine(metadata.model, 11)),
},
];
if (metadata.sideConversation?.view === 'parent') {
parts.push(ansi.dim(sideConversationStatusLineText(metadata.sideConversation)));
parts.push({
text: ansi.dim(sideConversationStatusLineText(metadata.sideConversation)),
dropRank: 4,
});
}
// #1064: omit thinking:default — it is noise before the user explicitly
// changes the level. Only a non-default, explicitly set level shows.
if (metadata.thinkingLevel) {
parts.push(ansi.dim(`thinking:${metadata.thinkingLevel}`));
parts.push({ text: ansi.dim(`thinking:${metadata.thinkingLevel}`), dropRank: 3 });
}
if (metadata.orchestrationMode === 'swarm') {
parts.push(ansi.accent('swarm'));
parts.push({ text: ansi.accent('swarm'), dropRank: 4 });
} else if (metadata.orchestrationMode === 'graph') {
parts.push(ansi.accent('graph'));
parts.push({ text: ansi.accent('graph'), dropRank: 4 });
}
// An autonomous goal burns tokens between prompts; it must never be
// invisible. Terminal goals show nothing (the desktop chip hides them too).
if (metadata.goal && isLiveGoalStatus(metadata.goal.status)) {
const text = goalStatusLineText(metadata.goal, Date.now());
const compactStatus =
metadata.goal.status === 'active' ? '' : metadata.goal.status === 'paused' ? 'p' : 'w';
const compactText = `g${compactStatus}${metadata.goal.iterations}/${metadata.goal.maxIterations}`;
// paused gets warning salience: the loop stopped burning but stays armed
// and resumable, which the user must not miss. waiting is a normal
// transient between turns, so it stays dim like the other chrome.
parts.push(
metadata.goal.status === 'active'
? ansi.accent(text)
: metadata.goal.status === 'paused'
? ansi.yellow(text)
: ansi.dim(text),
);
parts.push({
text:
metadata.goal.status === 'active'
? ansi.accent(text)
: metadata.goal.status === 'paused'
? ansi.yellow(text)
: ansi.dim(text),
compactRank: 3,
shortenedText:
metadata.goal.status === 'active'
? ansi.accent(fitLine(compactText, 8))
: metadata.goal.status === 'paused'
? ansi.yellow(fitLine(compactText, 8))
: ansi.dim(fitLine(compactText, 8)),
});
}
const usage = metadata.usage;
// ctx segment: only show "used" when contextRemaining is available, since
Expand All @@ -1380,32 +1412,118 @@ export function renderMakaPiStatusLine(metadata: MakaPiTranscriptMetadata, width
const pct = Math.round((used / metadata.modelContextWindow) * 100);
// #1064: color warning — yellow >80%, red >95%, dim otherwise.
const ctxColor = pct > 95 ? ansi.red : pct > 80 ? ansi.yellow : ansi.dim;
parts.push(
ctxColor(
parts.push({
text: ctxColor(
`ctx ${formatTokenCount(used)}/${formatTokenCount(metadata.modelContextWindow)} ${pct}%`,
),
);
compactRank: 2,
shortenedText: ctxColor(`c${pct}%`),
});
} else if (metadata.modelContextWindow !== undefined) {
// #3371: the window is known but no usage has arrived yet (fresh session,
// or the provider doesn't report per-step input tokens). Degrade
// explicitly, pi-style, instead of hiding the segment silently — the user
// can then tell "not measured yet" apart from "window unknown".
parts.push(ansi.dim(`ctx ?/${formatTokenCount(metadata.modelContextWindow)}`));
parts.push({
text: ansi.dim(`ctx ?/${formatTokenCount(metadata.modelContextWindow)}`),
compactRank: 2,
shortenedText: ansi.dim('c?'),
});
}
if (usage) {
if (usage.costUsd > 0) {
parts.push(ansi.dim(`$${formatCost(usage.costUsd)}`));
parts.push({ text: ansi.dim(`$${formatCost(usage.costUsd)}`), dropRank: 1 });
}
const totalCache = usage.cacheHitInput + usage.cacheMissInput;
if (totalCache > 0) {
const hitRate = Math.round((usage.cacheHitInput / totalCache) * 100);
parts.push(ansi.dim(`cache ${hitRate}%`));
parts.push({ text: ansi.dim(`cache ${hitRate}%`), dropRank: 0 });
}
}
parts.push(ansi.dim(metadata.connectionSlug));
parts.push({ text: ansi.dim(metadata.connectionSlug), dropRank: 2 });
// #1064: shorten cwd to ~-relative path instead of the full path.
parts.push(ansi.dim(shortenCwd(metadata.cwd)));
return fitLine(parts.join(sep), safeWidth);
const cwd = shortenCwd(metadata.cwd);
// cwd degrades progressively (full → basename → dropped), after every
// ranked segment above but before the final truncation fallback. A drive
// root (C:\) or filesystem root has no useful basename — empty, or the
// path itself — so it drops directly instead of rendering an empty
// segment after the separator.
const cwdBase = basename(cwd);
parts.push({
text: ansi.dim(cwd),
dropRank: 5,
shortenedText: cwdBase === '' || cwdBase === cwd ? undefined : ansi.dim(cwdBase),
});
return fitStatusLine(parts, sep, safeWidth);
}

interface MakaPiStatusLineSegment {
text: string;
/** Overflow drops whole segments lowest-rank-first; undefined never drops. */
dropRank?: number;
/** Critical segments shorten in this order after every droppable segment is gone. */
compactRank?: number;
/** Progressive fallback tried before this segment is dropped entirely. */
shortenedText?: string;
}

function fitStatusLine(segments: MakaPiStatusLineSegment[], sep: string, width: number): string {
const compactSep = ansi.dim(' ');
let activeSep = sep;
const lineWidth = (segs: MakaPiStatusLineSegment[]): number =>
visibleWidth(segs.map((segment) => segment.text).join(activeSep));
let kept = segments;
// Drop whole low-value segments, lowest rank first, re-checking after each
// rank so the fewest possible segments are sacrificed.
while (lineWidth(kept) > width) {
const dropRanks = kept.flatMap((segment) =>
segment.dropRank !== undefined ? [segment.dropRank] : [],
);
if (dropRanks.length > 0) {
const lowest = Math.min(...dropRanks);
// A droppable segment with a shortened form degrades before disappearing.
const shorten = kept.find(
(segment) => segment.dropRank === lowest && segment.shortenedText !== undefined,
);
if (shorten) {
kept = kept.map((segment) =>
segment === shorten
? { ...segment, text: segment.shortenedText ?? segment.text, shortenedText: undefined }
: segment,
);
} else {
kept = kept.filter((segment) => segment.dropRank !== lowest);
}
continue;
}

const compactRanks = kept.flatMap((segment) =>
segment.compactRank !== undefined && segment.shortenedText !== undefined
? [segment.compactRank]
: [],
);
if (compactRanks.length === 0) break;
const nextRank = Math.min(...compactRanks);
const shorten = kept.find(
(segment) => segment.compactRank === nextRank && segment.shortenedText !== undefined,
);
if (!shorten) break;
kept = kept.map((segment) =>
segment === shorten
? { ...segment, text: segment.shortenedText ?? segment.text, shortenedText: undefined }
: segment,
);
// Once critical values compact, reclaim separator chrome too. At widths
// below the compact critical seam, fitLine remains the honest fallback.
activeSep = compactSep;
}
return fitLine(kept.map((segment) => segment.text).join(activeSep), width);
}

function compactPermissionModeLabel(mode: string): string {
if (mode === 'bypass') return 'Full';
if (mode === 'explore') return 'Read';
return 'Auto';
}

function sideConversationStatusLineText(
Expand Down