mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-30 13:20:54 +01:00
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The issue/task chat subsystem renders board and agent comments as markdown inside chat bubbles. > - Human board comments use a saturated blue bubble so the message can be distinguished from agent output. > - The shared `.paperclip-markdown` rule forced `var(--foreground)` for body text and related markdown elements. > - On the blue bubble, that foreground color is too dark, so paragraphs, lists, links, and emphasis lose contrast. > - This pull request adds an explicit on-accent markdown treatment for blue/current-user message bubbles. > - The benefit is readable markdown without changing neutral markdown surfaces elsewhere in the app. ## Linked Issues or Issue Description Fixes #8688 ## What Changed - Added a `paperclip-markdown-on-accent` class for markdown rendered on accent-colored message bubbles. - Updated current-user issue chat messages to use the accent-safe markdown class. - Added CSS overrides for body text, list markers, headings, emphasis, links, blockquotes, and inline code on accent backgrounds. - Added a regression test proving current-user blue-bubble markdown receives the accent-safe class. ## Before Screenshot: <img width="816" height="618" alt="Screenshot 2026-06-27 at 14 22 59" src="https://github.com/user-attachments/assets/2a982326-9ff3-40ce-9955-ceb081d8a2e0" /> ## After Screenshot: <img width="821" height="624" alt="Screenshot 2026-06-27 at 15 05 17" src="https://github.com/user-attachments/assets/4722a0db-9f6a-4775-a7eb-47328c2f71e0" /> ## Verification - `CI=true corepack pnpm exec vitest run ui/src/components/IssueChatThread.test.tsx` - `CI=true corepack pnpm --filter @paperclipai/ui typecheck` - GitHub Actions PR workflow passed on latest head `f645cca3fc9675071c201471c0df938880c0c351`, including Build, Typecheck + Release Registry, e2e, general test shards, serialized server shards, Canary Dry Run, and aggregate verify. - Greptile Review passed with Confidence Score 5/5 on latest head `f645cca3fc9675071c201471c0df938880c0c351`. ## Risks Low risk. The new color treatment is opt-in and only applied to current-user issue chat markdown on accent bubbles. Neutral comment, document, artifact, and skill markdown surfaces keep the existing `.paperclip-markdown` colors. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI GPT-5 Codex in Codex desktop, with repository tool use and local command execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge
48 lines
2.0 KiB
TypeScript
48 lines
2.0 KiB
TypeScript
import { readFileSync } from "node:fs";
|
|
import { fileURLToPath } from "node:url";
|
|
import { describe, expect, it } from "vitest";
|
|
|
|
const stylesheet = readFileSync(fileURLToPath(new URL("../index.css", import.meta.url)), "utf8");
|
|
|
|
function cssBlock(selector: string): string {
|
|
const start = stylesheet.indexOf(`${selector} {`);
|
|
expect(start, `Missing CSS selector: ${selector}`).toBeGreaterThanOrEqual(0);
|
|
|
|
const bodyStart = stylesheet.indexOf("{", start);
|
|
const bodyEnd = stylesheet.indexOf("\n}", bodyStart);
|
|
expect(bodyStart, `Missing CSS block start: ${selector}`).toBeGreaterThanOrEqual(0);
|
|
expect(bodyEnd, `Missing CSS block end: ${selector}`).toBeGreaterThan(bodyStart);
|
|
|
|
return stylesheet.slice(bodyStart + 1, bodyEnd);
|
|
}
|
|
|
|
describe("accent markdown styles", () => {
|
|
it("inherits the current message bubble foreground for prose text, links, and list counters", () => {
|
|
const block = cssBlock(".paperclip-markdown.paperclip-markdown-on-accent");
|
|
|
|
expect(block).toContain("color: inherit");
|
|
expect(block).toContain("--tw-prose-body: currentColor");
|
|
expect(block).toContain("--tw-prose-links: currentColor");
|
|
expect(block).toContain("--tw-prose-counters: currentColor");
|
|
expect(block).toContain("--tw-prose-bullets: currentColor");
|
|
expect(block).toContain("--tw-prose-invert-links: currentColor");
|
|
});
|
|
|
|
it("keeps ordered-list markers and rendered link variants readable on accent bubbles", () => {
|
|
expect(cssBlock(".paperclip-markdown.paperclip-markdown-on-accent li::marker")).toContain(
|
|
"color: currentColor",
|
|
);
|
|
expect(cssBlock(".paperclip-markdown.paperclip-markdown-on-accent :where(a, a:visited)")).toContain(
|
|
"color: currentColor",
|
|
);
|
|
expect(cssBlock(".paperclip-markdown.paperclip-markdown-on-accent .paperclip-workspace-file-link")).toContain(
|
|
"color: currentColor",
|
|
);
|
|
expect(
|
|
cssBlock(
|
|
".paperclip-markdown.paperclip-markdown-on-accent :where(a.paperclip-mention-chip, a.paperclip-project-mention-chip)",
|
|
),
|
|
).toContain("color: currentColor !important");
|
|
});
|
|
});
|