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
3 changes: 3 additions & 0 deletions frontend/src/v2/__tests__/V2ActivityPage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1706,6 +1706,9 @@ describe('V2ActivityPage', () => {
// The shape agent posts arrive in: whitespace already folded by the recap.
expect(plainLine('Done: - a - b - c ## Shipped **ok**')).toBe('Done: a - b - c Shipped ok');
expect(plainLine('```\nlog line\n```')).toBe('log line');
// Folded, as agent posts arrive: the fence ends where its closing marks are, not at the end.
expect(plainLine('Before ```js code ``` after')).toBe('Before after');
expect(plainLine('```sh npm test```')).toBe('npm test');
expect(plainLine('中_文_字 and __init__.py stay')).toBe('中_文_字 and __init__.py stay');
const link = `${'y'.repeat(160)} see [the doc](https://example.com/aaaaaaaaaaaa`.slice(0, 180);
expect(plainLine(link)).toMatch(/ see the doc…$/);
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/v2/__tests__/V2ConnectPage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ describe('V2ConnectPage in zh-CN', () => {
expect(container.querySelector('.v2-connect__rule .v2-connect__code-head > span'))
.toHaveTextContent(`Cursor 规则 · 在项目中保存为 ${CURSOR_PROJECT_RULE_PATH}`);
expect(container.querySelector('.v2-connect__cursor')).toHaveTextContent('在 Cursor 的 MCP 设置里填入你的智能体密钥。');
// The intro line that replaced the head's hint renders translated, not just present in source.
expect(container.querySelector('p.v2-connect__intro')).toHaveTextContent('MCP 用的是接入时创建的智能体密钥。');
expect(chrome.join('\n')).not.toMatch(/\b(Copy|Copied|Connect|Manage|Add|Set up|Open|Instance keys|save as)\b/);
fireEvent.click(screen.getAllByRole('button', { name: '复制' })[0]);
expect(await screen.findByRole('button', { name: '已复制' })).toBeInTheDocument();
Expand Down
14 changes: 14 additions & 0 deletions frontend/src/v2/__tests__/v2-layout-invariants.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6133,6 +6133,19 @@ describe('secondary pages on the reference grammar (ui-audit-1104 findings 2–8
expect(css.lastIndexOf('@media (max-width: 760px)')).toBeLessThan(css.indexOf('.v2-feature--aprofile .v2-aprofile__avatar-button::after'));
});

test('the public bar\'s keys (Sign up) reach 44px to touch on a phone', () => {
const css = read('../agents/v2-agent-profile.css');
expect(ruleBody(css, '.v2-aprofile .v2-aprofile__btn')).toContain('height: 28px');
// Both bar keys carry a 1px border, and an absolute ::before measures from the padding box,
// so the overlay starts from 26, not 28 (measured in Chromium: -8px gave 42).
expect(ruleBody(css, '.v2-aprofile .v2-aprofile__btn--primary')).toContain('border: 1px solid');
const phone = css.slice(css.lastIndexOf('@media (max-width: 760px)'));
const hits = [...phone.matchAll(/\.v2-aprofile \.v2-aprofile__bar \.v2-aprofile__btn::before \{([^}]*)\}/g)].map((m) => m[1]);
// The last inset wins: its vertical reach must make 44 from the 26px padding box.
const inset = hits.map((body) => body.match(/inset:\s*(-?\d+)px/)).filter(Boolean).pop();
expect(28 - 2 - 2 * Number(inset?.[1])).toBeGreaterThanOrEqual(44);
});

test('finding 6: the board header icon keys never shrink on a phone', () => {
const phone = mediaBlockContaining(boardCss, '.v2-feature--board .v2-board__key--icon { flex: none; }');
expect(ruleBody(boardCss, '.v2-feature--board .v2-board__key--icon', { within: phone })).toContain('flex: none');
Expand Down Expand Up @@ -6197,6 +6210,7 @@ describe('Activity built to the d215 signal frames (#s-activity-signal)', () =>
const text = rule('.v2-activity__moved-text');
expect(text).toContain('-webkit-line-clamp: 2');
expect(text).toContain('display: -webkit-box');
expect(text).toContain('-webkit-box-orient: vertical');
expect(text).toContain('overflow: hidden');
});

Expand Down
3 changes: 3 additions & 0 deletions frontend/src/v2/agents/v2-agent-profile.css
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@
.v2-aprofile .v2-aprofile__bar .v2-aprofile__btn { position: relative; }
.v2-aprofile .v2-aprofile__navlink::before,
.v2-aprofile .v2-aprofile__bar .v2-aprofile__btn::before { content: ''; position: absolute; inset: -5px -6px; }
/* The bar key draws at the v2p small key's 28 with a 1px border, and an absolute overlay
measures from inside the border (26), so it reaches 9px each way: 26 + 18 = 44. */
.v2-aprofile .v2-aprofile__bar .v2-aprofile__btn::before { inset: -9px -6px; }
.v2-aprofile .v2-aprofile__navlink::before { inset: -14px -7px; }
.v2-aprofile .v2-agent-settings__tabs > * { box-sizing: border-box; min-height: 44px; display: inline-flex; align-items: center; }
.v2-aprofile .v2-aprofile__pod-remove { height: 44px; line-height: 44px; }
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/v2/components/V2ActivityPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@ const RECAP_CLIP = 180;
export const plainLine = (value: string): string => {
const clipped = value.length >= RECAP_CLIP;
const fold = (text: string) => text.replace(/\s+/g, ' ').trim();
const fence = /```[^\n]*\n?([\s\S]*?)(?:```|$)/g;
// The info string is a bare word (js, ts, sh), so a folded post's fence keeps the text after it.
const fence = /```[\w+-]*[ \t]*\n?([\s\S]*?)(?:```|$)/g;
const prose = value.replace(fence, ' ');
let text = (fold(prose) ? prose : value.replace(fence, ' $1 '))
.replace(/!?\[([^\]]*)\]\([^)]*\)/g, '$1');
Expand Down
Loading