diff --git a/package-lock.json b/package-lock.json index d786816..4b20d9d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "quill", - "version": "1.0.0", + "version": "1.1.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "quill", - "version": "1.0.0", + "version": "1.1.1", "license": "Apache-2.0", "dependencies": { "@manuscripts/track-changes-plugin": "^2.3.10", @@ -33,6 +33,7 @@ "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.2", "@testing-library/user-event": "^14.6.1", + "@types/node": "^22.20.1", "@types/react": "^19.1.8", "@types/react-dom": "^19.1.6", "@vitejs/plugin-react": "^4.6.0", @@ -2629,6 +2630,16 @@ "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", "license": "MIT" }, + "node_modules/@types/node": { + "version": "22.20.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.1.tgz", + "integrity": "sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, "node_modules/@types/react": { "version": "19.2.14", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", @@ -8389,6 +8400,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, "node_modules/update-browserslist-db": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", diff --git a/package.json b/package.json index 2c7f60e..3078f34 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.2", "@testing-library/user-event": "^14.6.1", + "@types/node": "^22.20.1", "@types/react": "^19.1.8", "@types/react-dom": "^19.1.6", "@vitejs/plugin-react": "^4.6.0", diff --git a/src/App.css b/src/App.css index 06dc582..69fbcaa 100644 --- a/src/App.css +++ b/src/App.css @@ -164,7 +164,10 @@ --statusbar-height: 28px; --comment-panel-width: 260px; --page-max-width: 816px; - --page-padding-x: 96px; + /* 816 − 2×64 = 688px measure (~85 chars). Trim padding, not width, so the + page footprint is unchanged and can't force horizontal scroll against the + fixed comment column. Print block flattens this, so PDF stays US-Letter. */ + --page-padding-x: 64px; --page-padding-y: 72px; --editor-scroll-gap: 40px; @@ -1898,7 +1901,6 @@ del.track-delete { } .ProseMirror { min-height: 0 !important; - background-image: none !important; color: #000 !important; } diff --git a/src/components/AddCommentButton.tsx b/src/components/AddCommentButton.tsx index 3f2981e..f6bb49d 100644 --- a/src/components/AddCommentButton.tsx +++ b/src/components/AddCommentButton.tsx @@ -84,7 +84,7 @@ export default function AddCommentButton({ value={text} onChange={(e) => setText(e.target.value)} onKeyDown={handleKeyDown} - placeholder="Add a comment… (Cmd+Enter to post)" + placeholder="Add a comment… (@claude to get an AI response)" rows={3} autoFocus /> diff --git a/src/components/CommentCard.tsx b/src/components/CommentCard.tsx index 635a3be..0ada91c 100644 --- a/src/components/CommentCard.tsx +++ b/src/components/CommentCard.tsx @@ -168,7 +168,7 @@ export default function CommentCard({ value={replyText} onChange={(e) => setReplyText(e.target.value)} onKeyDown={handleKeyDown} - placeholder="Reply… (type @claude to ask Claude)" + placeholder="Reply… (@claude to get an AI response)" rows={2} autoFocus /> diff --git a/src/test/components/composerPlaceholders.test.ts b/src/test/components/composerPlaceholders.test.ts new file mode 100644 index 0000000..92ab01b --- /dev/null +++ b/src/test/components/composerPlaceholders.test.ts @@ -0,0 +1,38 @@ +import { describe, it, expect } from 'vitest'; +import { readFileSync } from 'node:fs'; +import { join } from 'node:path'; + +// Guard test (spec 11): both comment composers must advertise the @claude +// affordance in their placeholder. We read the component sources and match +// EVERY placeholder="…" so a future inserted composer can't silently drop the +// hint. Paired with a negative control proving the check can fail. +// Paths resolve from the repo root (vitest runs with cwd = repo root). + +function source(rel: string): string { + return readFileSync(join(process.cwd(), rel), 'utf8'); +} + +/** All static `placeholder="…"` literals in a source file. */ +function placeholders(src: string): string[] { + return [...src.matchAll(/placeholder="([^"]*)"/g)].map((m) => m[1]); +} + +describe('composer placeholders mention @claude', () => { + it('the new-comment composer placeholder mentions @claude', () => { + const found = placeholders(source('src/components/AddCommentButton.tsx')); + expect(found.length).toBeGreaterThan(0); + for (const p of found) expect(p).toContain('@claude'); + }); + + it('the reply composer placeholder mentions @claude', () => { + const found = placeholders(source('src/components/CommentCard.tsx')); + expect(found.length).toBeGreaterThan(0); + for (const p of found) expect(p).toContain('@claude'); + }); + + it('negative control: a placeholder lacking @claude fails the check', () => { + const found = placeholders('