mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-05 15:09:42 +02:00
fix(run,terminal): merge-time fixes for the Instance count stepper and capture geometry
#454: the behaviour the PR adds had no test, so a regression test drives runGrok() at tabCount 3 and asserts three quick-start POSTs with sequential w<n>-<case> names (verified to fail against master's session-ui.js). Each caller now reads the count BEFORE its opening banner and announces it there, the way runClaude() already did, so a launch no longer prints two headers and a launch with another session already active still says how many are starting. runClaude() calls the shared _readTabCount() instead of its own copy of the 1..20 clamp, and that helper optional-chains the element read, since hoisting it above each caller's try block would otherwise let a missing #tabCount throw where the launch-error path cannot report it. #435: sizeMovedUnderLoad derived from data.source alone. `mux-visible` is not sufficient: a failed display-message cursor query makes capturePaneBuffer skip the snapshot repaint and return the raw capture, which the route still labels mux-visible, so a size that moved during such a load bought a full forced reload to repair a frame that was never positioned. It now tests Number.isFinite(data.captureRows) like its two siblings. Plus the invariants and CLAUDE.md lines promised on #435: a visible capture reports its geometry and omits it when nothing was positioned, the comparison runs on mux-visible only, and the replay is capped at one attempt and latches per session when it cannot converge. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1122,4 +1122,67 @@ describe('Grok quick start', () => {
|
||||
expect(requests).toEqual(['/api/grok/status']);
|
||||
expect(errors[0]).toContain('https://x.ai/cli/install.sh');
|
||||
});
|
||||
|
||||
// The whole point of the shared _launchQuickStartInstances() helper. Before it,
|
||||
// every non-Claude run*() hardcoded exactly one quick-start call, so the
|
||||
// "Instance count" stepper next to the Run button silently did nothing on all
|
||||
// eight of them: no error, no hint, just the wrong number of sessions. The five
|
||||
// fixture edits that came with the change stub tabCount at '1', so they pass
|
||||
// identically with and without it; this is the one that does not.
|
||||
it('launches tabCount sessions with sequential w<n>-<case> names and selects the first', async () => {
|
||||
const elements: Record<string, any> = {
|
||||
quickStartCase: { value: 'grok-case' },
|
||||
tabCount: { value: '3' },
|
||||
};
|
||||
const requests: Array<{ url: string; body?: any }> = [];
|
||||
const CodemanApp = function CodemanApp(this: any) {};
|
||||
let created = 0;
|
||||
|
||||
const context = vm.createContext({
|
||||
CodemanApp,
|
||||
localStorage: { getItem: () => null, setItem: () => {} },
|
||||
document: { getElementById: (id: string) => elements[id] ?? null },
|
||||
fetch: async (url: string, init?: { body?: string }) => {
|
||||
const body = init?.body ? JSON.parse(init.body) : undefined;
|
||||
requests.push({ url, body });
|
||||
if (url === '/api/grok/status')
|
||||
return {
|
||||
json: async () => ({
|
||||
success: true,
|
||||
data: { available: true, path: '/home/user/.grok/bin', version: '1.0.5' },
|
||||
}),
|
||||
};
|
||||
if (url === '/api/quick-start') {
|
||||
const id = `sess-gk-${created++}`;
|
||||
return {
|
||||
json: async () => ({ success: true, data: { sessionId: id, session: { id, name: body.sessionName } } }),
|
||||
};
|
||||
}
|
||||
throw new Error(`unexpected fetch: ${url}`);
|
||||
},
|
||||
console,
|
||||
});
|
||||
|
||||
const sessionUi = readFileSync(resolve(import.meta.dirname, '../src/web/public/session-ui.js'), 'utf8');
|
||||
vm.runInContext(sessionUi, context, { filename: 'session-ui.js' });
|
||||
|
||||
const app = new (CodemanApp as any)();
|
||||
app.terminal = { clear: () => {}, writeln: () => {}, focus: () => {} };
|
||||
app.loadAppSettingsFromStorage = () => ({});
|
||||
app.getCaseSettings = () => ({});
|
||||
app.buildEnvOverrides = () => ({});
|
||||
app.sessions = new Map();
|
||||
app._onSessionCreated = (session: any) => app.sessions.set(session.id, session);
|
||||
app._renderSessionTabsImmediate = () => {};
|
||||
const selected: string[] = [];
|
||||
app.selectSession = async (id: string) => {
|
||||
selected.push(id);
|
||||
};
|
||||
|
||||
await app.runGrok();
|
||||
|
||||
const names = requests.filter((r) => r.url === '/api/quick-start').map((r) => r.body.sessionName);
|
||||
expect(names).toEqual(['w1-grok-case', 'w2-grok-case', 'w3-grok-case']);
|
||||
expect(selected).toEqual(['sess-gk-0']);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user