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
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ describe('attachment frontend contract', () => {
// These assertions pin the converged form so the surfaces cannot drift back.
describe('attachment visual token governance (#546)', () => {
it('image thumbnail placeholder uses maka surface-alpha + radius tokens, not shadcn aliases', async () => {
const chatView = await readRepo('packages/ui/src/chat-view.tsx');
const m = chatView.match(/maka-user-attachment-thumb-pending[^"]*/);
const chatTurn = await readRepo('packages/ui/src/chat-turn.tsx');
const m = chatTurn.match(/maka-user-attachment-thumb-pending[^"]*/);
assert.ok(m, 'pending thumbnail className not found — component renamed?');
const cls = m[0];
// No raw shadcn surface aliases — the card next to it uses --foreground-alpha-*.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ describe('chat status cluster layout contract', () => {
// live tail's derived status is `completed`, so a real footer would offer
// a clickable regenerate/branch on a still-streaming answer. Reserving the
// box keeps the live→settled swap height-neutral on the one node.
const src = await readRepo('packages/ui/src/chat-view.tsx');
const src = `${await readRepo('packages/ui/src/chat-view.tsx')}\n${await readRepo('packages/ui/src/chat-turn.tsx')}`;
assert.doesNotMatch(
src,
/maka-turn-streaming/,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { describe, it } from 'node:test';
import { REPO_ROOT } from './css-test-helpers.js';

const MIGRATED_FILES = [
'packages/ui/src/chat-view.tsx',
'packages/ui/src/chat-turn.tsx',
'packages/ui/src/permission-dialog.tsx',
'packages/ui/src/tool-activity.tsx',
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { renderSessionListPanel } from './session-list-render-helpers.js';

const REPO_ROOT = resolve(import.meta.dirname, '../../../../..');
const COMPONENTS_PATH = resolve(REPO_ROOT, 'packages', 'ui', 'src', 'chat-view.tsx');
const CHAT_TURN_PATH = resolve(REPO_ROOT, 'packages', 'ui', 'src', 'chat-turn.tsx');
const SEARCH_MODAL_PATH = resolve(REPO_ROOT, 'packages', 'ui', 'src', 'search-modal.tsx');
const COMMAND_PALETTE_CONTENT_PATH = join(REPO_ROOT, 'apps', 'desktop', 'src', 'renderer', 'command-palette-content-search.ts');

Expand Down Expand Up @@ -162,6 +163,7 @@ describe('SearchModal lifecycle contract (PR-SIDEBAR-IA-0 Phase 3 P0 fixup)', ()
it('search result navigation consumes target.turnId instead of only switching sessions', async () => {
const searchModalSource = await readFile(SEARCH_MODAL_PATH, 'utf8');
const components = await readFile(COMPONENTS_PATH, 'utf8');
const chatTurn = await readFile(CHAT_TURN_PATH, 'utf8');
const main = await readRendererShellCombinedSource();
const contentSearch = await readFile(COMMAND_PALETTE_CONTENT_PATH, 'utf8');

Expand Down Expand Up @@ -216,12 +218,12 @@ describe('SearchModal lifecycle contract (PR-SIDEBAR-IA-0 Phase 3 P0 fixup)', ()
'ChatView must move keyboard focus to the matched turn after search navigation',
);
assert.match(
components,
chatTurn,
/data-search-highlight=\{props\.searchHighlighted\s*\?\s*'true'\s*:\s*undefined\}/,
'ChatView must visually mark the matched search turn',
);
assert.match(
components,
chatTurn,
/tabIndex=\{props\.searchHighlighted \? -1 : undefined\}/,
'Highlighted search turns must be programmatically focusable while the search target is active',
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ it('uses Streamdown streaming mode for live answers without a second fade owner'
const [body, wrapper, chat] = await Promise.all([
uiSource('markdown-body.tsx'),
uiSource('markdown.tsx'),
uiSource('chat-view.tsx'),
uiSource('chat-turn.tsx'),
]);

assert.match(body, /import \{[^}]*Streamdown[^}]*\} from 'streamdown';/);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ import { resolve } from 'node:path';

it('renders live thinking and text from timeline items instead of a trailing live content path', async () => {
const source = await readFile(
resolve(import.meta.dirname, '../../../../../packages/ui/src/chat-view.tsx'),
resolve(import.meta.dirname, '../../../../../packages/ui/src/chat-turn.tsx'),
'utf8',
);

const chatView = await readFile(
resolve(import.meta.dirname, '../../../../../packages/ui/src/chat-view.tsx'),
'utf8',
);
assert.match(
source,
/item\.kind === 'thinking'[\s\S]*?<DeepThinking[\s\S]*?live=\{item\.live === true\}/,
Expand All @@ -22,10 +26,10 @@ it('renders live thinking and text from timeline items instead of a trailing liv
/turn\.timeline\.map[\s\S]*?props\.liveStreaming[\s\S]*?<LiveStreamingEntries/,
);
assert.match(
source,
chatView,
/const settledTurns = useMemo\([\s\S]*?materializeTurns\(visibleMessages\)[\s\S]*?\[visibleMessages\][\s\S]*?const turns = useMemo\([\s\S]*?overlayLiveTurn\(settledTurns, props\.liveTurn\)/,
);
assert.doesNotMatch(source, /materializeTurns\(visibleMessages, props\.liveTurn\)/);
assert.doesNotMatch(chatView, /materializeTurns\(visibleMessages, props\.liveTurn\)/);

const shell = await readFile(
resolve(import.meta.dirname, '../../../../../apps/desktop/src/renderer/app-shell.tsx'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import { RENDERER_SHELL_SOURCE_REPO_PATHS } from './renderer-shell-source-helper
const FILES_TO_SCAN = [
resolve(process.cwd(), '..', '..', 'packages', 'ui', 'src', 'components.tsx'),
resolve(process.cwd(), '..', '..', 'packages', 'ui', 'src', 'chat-view.tsx'),
resolve(process.cwd(), '..', '..', 'packages', 'ui', 'src', 'chat-turn.tsx'),
resolve(process.cwd(), '..', '..', 'packages', 'ui', 'src', 'composer.tsx'),
resolve(process.cwd(), '..', '..', 'packages', 'ui', 'src', 'skills-panel.tsx'),
resolve(process.cwd(), '..', '..', 'packages', 'ui', 'src', 'daily-review-panel.tsx'),
Expand Down Expand Up @@ -397,7 +398,7 @@ describe('turn footer copy feedback contract', () => {
});

it('gates the inline footer copy action instead of silently firing raw clipboard writes', async () => {
const componentsPath = resolve(process.cwd(), '..', '..', 'packages', 'ui', 'src', 'chat-view.tsx');
const componentsPath = resolve(process.cwd(), '..', '..', 'packages', 'ui', 'src', 'chat-turn.tsx');
const src = await readFile(componentsPath, 'utf8');
const footerBlock = src.match(/function TurnFooterActions[\s\S]*?const STATUS_FOOTER_ICON/)?.[0] ?? '';

Expand Down Expand Up @@ -529,14 +530,12 @@ describe('tool error copy feedback contract', () => {

describe('chat markdown copy feedback contract', () => {
it('gates assistant message copy without redacting the raw message markdown', async () => {
const componentsPath = resolve(process.cwd(), '..', '..', 'packages', 'ui', 'src', 'chat-view.tsx');
const componentsPath = resolve(process.cwd(), '..', '..', 'packages', 'ui', 'src', 'chat-turn.tsx');
const src = await readFile(componentsPath, 'utf8');
// PR-UI-LIB-EXTRACT-6 (round 7/10) moved the markdown layer
// out of components.tsx; PR-UI-LIB-EXTRACT-8 (round 9/10)
// then moved `EmptyChatHero` itself into `chat-empty-hero.tsx`.
// The next-named-thing anchor after `MessageCopyButton` is now
// `ChatHeaderAlertBadge`.
const block = src.match(/function MessageCopyButton[\s\S]*?function ChatHeaderAlertBadge/)?.[0] ?? '';
const block = src.match(/function MessageCopyButton[\s\S]*?export const TurnView/)?.[0] ?? '';

assert.match(block, /useClipboardCopyFeedback\(1400, \{ redact: false \}\)/, 'Message copy should preserve raw assistant markdown.');
assert.match(block, /await copyFeedback\.copy\('message', props\.text\)/, 'Message copy should route through the guarded helper.');
Expand Down
Loading
Loading