From 08a4f65345964993c8b9e6aaaaf34eae70d8ef6a Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 18 Sep 2025 11:21:54 -0700 Subject: [PATCH 01/10] Improve the corpus-viewer, and add a Claude slash-command for powering this loop. --- .claude/commands/corpus-loop.md | 42 +++++++++++++++++++++++++++++++++ tests/corpus-view.ts | 29 ++++++++++------------- 2 files changed, 55 insertions(+), 16 deletions(-) create mode 100644 .claude/commands/corpus-loop.md diff --git a/.claude/commands/corpus-loop.md b/.claude/commands/corpus-loop.md new file mode 100644 index 0000000..6662d62 --- /dev/null +++ b/.claude/commands/corpus-loop.md @@ -0,0 +1,42 @@ +--- +argument-hint: [corpus_slug] +description: uses Playwright MCP and the `corpus:view` dev environment to help with parsing page elements +--- + +- using Playwright MCP, navigate to `http://localhost:3001/corpus/$1/gitcasso` +- the page will have a div with id `gitcasso-comment-spots`, wait 500ms for it to settle +- inside the `gitcasso-comment-spots` div you will see something like this: + +```json +{ + "url": "https://github.com/diffplug/selfie/issues/523", + "allTextAreas": [ + { + "textarea": "id='feedback' name='feedback' className='form-control width-full mb-2'", + "spot": "NO_SPOT" + }, + { + "textarea": "id=':rn:' name='' className='prc-Textarea-TextArea-13q4j overtype-input'", + "spot": { + "domain": "github.com", + "number": 523, + "slug": "diffplug/selfie", + "title": "TODO_TITLE", + "type": "GH_ISSUE_ADD_COMMENT", + "unique_key": "github.com:diffplug/selfie:523" + } + } + ] +} +``` + +- this output means that this page is simulating the url `https://github.com/diffplug/selfie/issues/523` +- every textarea on the page is represented +- `NO_SPOT` means that the spot was not enhanced +- `type: GH_ISSUE_ADD_COMMENT` means that it was enhanced by whichever implementation of `CommentEnhancer` returns the spot type `GH_ISSUE_ADD_COMMENT` +- if you search for that string in `src/lib/enhancers` you will find the correct one +- the `tryToEnhance` method returned a `CommentSpot`, and that whole data is splatted out above + +If you make a change to the code of the enhancer, you can click the button with id `gitcasso-rebuild-btn`. It will trigger a rebuild of the browser extension, and then refresh the page. You'll be able to see the effects of your change in the `gitcasso-comment-spots` div described above. + +When writing `tryToEnhance` methods, don't hedge your bets and write lots of fallback code or strings of `?.`. Have a specific piece of data you want to get, use non-null `!` assertions where necessary to be clear about getting. The data they are extracting is going to change over time, and it's easier to fix broken ones if you know exactly what used to work. If the code has lots of branching paths, it's harder to tell what it was doing. \ No newline at end of file diff --git a/tests/corpus-view.ts b/tests/corpus-view.ts index 464bf59..eff2a71 100644 --- a/tests/corpus-view.ts +++ b/tests/corpus-view.ts @@ -477,28 +477,28 @@ function createCommentSpotDisplayScript(urlParts: ReturnType function updateCommentSpotDisplay() { const textareas = document.querySelectorAll('textarea'); - const spotsFound = []; + const allTextAreas = []; for (const textarea of textareas) { - const forValue = 'id=' + textarea.id + ' name=' + textarea.name + ' className=' + textarea.className; + const forValue = "id='" + textarea.id + "' name='" + textarea.name + "' className='" + textarea.className + "'"; const enhancedItem = window.gitcassoTextareaRegistry ? window.gitcassoTextareaRegistry.get(textarea) : undefined; if (enhancedItem) { - spotsFound.push({ - for: forValue, + allTextAreas.push({ + textarea: forValue, spot: enhancedItem.spot, - title: enhancedItem.enhancer.tableTitle(enhancedItem.spot), }); } else { - spotsFound.push({ - for: forValue, + allTextAreas.push({ + textarea: forValue, spot: 'NO_SPOT', }); } } - - console.log('Enhanced textareas:', spotsFound.filter(s => s.spot !== 'NO_SPOT').length); - console.log('All textareas on page:', textareas.length); - commentSpotDisplay.innerHTML = '
${urlParts.href}\\n' + JSON.stringify(spotsFound, null, 2) + '
'; + const harness = { + url: '${urlParts.href}', + allTextAreas: allTextAreas + } + commentSpotDisplay.innerHTML = '
' + JSON.stringify(harness, null, 1) + '
'; } // Initial update @@ -508,9 +508,6 @@ function createCommentSpotDisplayScript(urlParts: ReturnType setTimeout(updateCommentSpotDisplay, 400); setTimeout(updateCommentSpotDisplay, 800); - // Update display periodically - setInterval(updateCommentSpotDisplay, 2000); - document.body.appendChild(commentSpotDisplay); ` } @@ -540,7 +537,7 @@ function createGitcassoScript( ): string { const contentScriptSetup = contentScriptCode ? // Direct embedding (for HTML corpus) - ` + ` // Set up mocked location window.gitcassoMockLocation = { host: '${urlParts.host}', @@ -567,7 +564,7 @@ function createGitcassoScript( } ` : // Fetch-based loading (for HAR corpus) - ` + ` // Fetch and patch the content script to remove webextension-polyfill issues fetch('/chrome-mv3-dev/content-scripts/content.js') .then(response => response.text()) From c9912c47653e0e372ae76240bc0a7f97dafb2aee Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 18 Sep 2025 11:22:26 -0700 Subject: [PATCH 02/10] Implement title for `GH_ISSUE_ADD_COMMENT`. --- src/lib/enhancers/github/githubIssueAddComment.tsx | 6 +++--- tests/lib/enhancers/github.test.ts | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/lib/enhancers/github/githubIssueAddComment.tsx b/src/lib/enhancers/github/githubIssueAddComment.tsx index a36de96..f3b8f9e 100644 --- a/src/lib/enhancers/github/githubIssueAddComment.tsx +++ b/src/lib/enhancers/github/githubIssueAddComment.tsx @@ -42,7 +42,7 @@ export class GitHubIssueAddCommentEnhancer implements CommentEnhancer { "domain": "github.com", "number": 523, "slug": "diffplug/selfie", - "title": "TODO_TITLE", + "title": "[jvm] docs for VCR", "type": "GH_ISSUE_ADD_COMMENT", "unique_key": "github.com:diffplug/selfie:523", }, - "title": "TITLE_TODO", + "title": "[jvm] docs for VCR", "upperDecoration": { "domain": "github.com", "number": 56, "slug": "diffplug/gitcasso", - "title": "TODO_TITLE", + "title": "what about the draft?", "type": "GH_ISSUE_ADD_COMMENT", "unique_key": "github.com:diffplug/gitcasso:56", }, - "title": "TITLE_TODO", + "title": "what about the draft?", "upperDecoration": { "domain": "github.com", "number": 56, "slug": "diffplug/gitcasso", - "title": "TODO_TITLE", + "title": "what about the draft?", "type": "GH_ISSUE_ADD_COMMENT", "unique_key": "github.com:diffplug/gitcasso:56", }, - "title": "TITLE_TODO", + "title": "what about the draft?", "upperDecoration": Date: Thu, 18 Sep 2025 11:30:18 -0700 Subject: [PATCH 03/10] Correct titles for Issue and PR Add Comment. --- src/lib/enhancers/github/githubIssueAddComment.tsx | 2 +- src/lib/enhancers/github/githubPRAddComment.tsx | 6 +++--- tests/lib/enhancers/github.test.ts | 14 ++++++++++---- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/lib/enhancers/github/githubIssueAddComment.tsx b/src/lib/enhancers/github/githubIssueAddComment.tsx index f3b8f9e..9158c1e 100644 --- a/src/lib/enhancers/github/githubIssueAddComment.tsx +++ b/src/lib/enhancers/github/githubIssueAddComment.tsx @@ -42,7 +42,7 @@ export class GitHubIssueAddCommentEnhancer implements CommentEnhancer { "domain": "github.com", "number": 517, "slug": "diffplug/selfie", - "title": "TODO_TITLE", + "title": "Add "VCR" functionality + #517", "type": "GH_PR_ADD_COMMENT", "unique_key": "github.com:diffplug/selfie:517", }, - "title": "TITLE_TODO", + "title": "Add "VCR" functionality + #517", "upperDecoration": { "domain": "github.com", "number": 58, "slug": "diffplug/gitcasso", - "title": "TODO_TITLE", + "title": "Feat/expand corpus + + #58", "type": "GH_PR_ADD_COMMENT", "unique_key": "github.com:diffplug/gitcasso:58", }, - "title": "TITLE_TODO", + "title": "Feat/expand corpus + + #58", "upperDecoration": Date: Thu, 18 Sep 2025 11:40:40 -0700 Subject: [PATCH 04/10] Implement title extraction for new issues. --- src/lib/enhancers/github/githubIssueNewComment.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/lib/enhancers/github/githubIssueNewComment.tsx b/src/lib/enhancers/github/githubIssueNewComment.tsx index 3169755..cd81c09 100644 --- a/src/lib/enhancers/github/githubIssueNewComment.tsx +++ b/src/lib/enhancers/github/githubIssueNewComment.tsx @@ -9,6 +9,7 @@ interface GitHubIssueNewCommentSpot extends CommentSpot { type: 'GH_ISSUE_NEW_COMMENT' domain: string slug: string // owner/repo + title: string } export class GitHubIssueNewCommentEnhancer implements CommentEnhancer { @@ -17,9 +18,12 @@ export class GitHubIssueNewCommentEnhancer implements CommentEnhancer Date: Thu, 18 Sep 2025 11:41:48 -0700 Subject: [PATCH 05/10] Oops! Looks like new issues have the same problem that regular issues had, where there's a feedback form on initial pageload. --- tests/lib/enhancers/github.test.ts | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/tests/lib/enhancers/github.test.ts b/tests/lib/enhancers/github.test.ts index 4a29bfe..60e8809 100644 --- a/tests/lib/enhancers/github.test.ts +++ b/tests/lib/enhancers/github.test.ts @@ -153,26 +153,8 @@ describe('github', () => { expect(enhancements(document, window)).toMatchInlineSnapshot(` [ { - "for": "id=feedback name=feedback className=form-control width-full mb-2 overtype-input", - "spot": { - "domain": "github.com", - "slug": "diffplug/selfie", - "type": "GH_ISSUE_NEW_COMMENT", - "unique_key": "github.com:diffplug/selfie:new", - }, - "title": "New Issue", - "upperDecoration": - - New Issue - - - - diffplug/selfie - - - , + "for": "id=feedback name=feedback className=form-control width-full mb-2", + "spot": "NO_SPOT", }, ] `) From 548710ce84301b54082813a5d83d36611f93a927 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 18 Sep 2025 11:47:21 -0700 Subject: [PATCH 06/10] Add a test for new issue creation where the fields are prepopulated. --- tests/corpus/_corpus-index.ts | 5 + tests/corpus/gh_issue_new_populated.html | 1586 ++++++++++++++++++++++ tests/lib/enhancers/github.test.ts | 29 + 3 files changed, 1620 insertions(+) create mode 100644 tests/corpus/gh_issue_new_populated.html diff --git a/tests/corpus/_corpus-index.ts b/tests/corpus/_corpus-index.ts index d985669..628106d 100644 --- a/tests/corpus/_corpus-index.ts +++ b/tests/corpus/_corpus-index.ts @@ -17,6 +17,11 @@ export const CORPUS: Record = { type: 'html', url: 'https://github.com/diffplug/gitcasso/issues/56', }, + gh_issue_new_populated: { + description: 'a new issue wiht some fields filled out', + type: 'html', + url: 'https://github.com/diffplug/gitcasso/issues/new', + }, gh_issue_populated_comment: { description: 'comment text box has some text', type: 'html', diff --git a/tests/corpus/gh_issue_new_populated.html b/tests/corpus/gh_issue_new_populated.html new file mode 100644 index 0000000..85f6804 --- /dev/null +++ b/tests/corpus/gh_issue_new_populated.html @@ -0,0 +1,1586 @@ + + + + + + + + + + + + + + + +New Issue + +
+
+ +
+ Skip to content + + + + + + + + +
+
+ + + + + + +
+
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + +
View cavia-porcellus's profile

Create new issue

Add a description
Markdown input: edit mode selected.

Metadata

Assignees

No one -

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone
    Remember, contributions to this repository should follow its contributing guidelines.
    +
    +
    +
    +
    +
    + + + + + + + + +
    +
    New Issue
    +
    14 results
    + + \ No newline at end of file diff --git a/tests/lib/enhancers/github.test.ts b/tests/lib/enhancers/github.test.ts index 60e8809..aad4c06 100644 --- a/tests/lib/enhancers/github.test.ts +++ b/tests/lib/enhancers/github.test.ts @@ -114,6 +114,35 @@ describe('github', () => { ] `) }) + withCorpus('gh_issue_new_populated').it('has enhancement on initial page load', async () => { + expect(enhancements(document, window)).toMatchInlineSnapshot(` + [ + { + "for": "id=:r34: name=null className=prc-Textarea-TextArea-13q4j focus-visible overtype-input", + "spot": { + "domain": "github.com", + "slug": "diffplug/gitcasso", + "title": "New issue title", + "type": "GH_ISSUE_NEW_COMMENT", + "unique_key": "github.com:diffplug/gitcasso:new", + }, + "title": "New issue title", + "upperDecoration": + + New Issue + + + + diffplug/gitcasso + + + , + }, + ] + `) + }) withCorpus('gh_issue_populated_comment').it('should create the correct spot object', async () => { expect(enhancements(document, window)).toMatchInlineSnapshot(` [ From 64508ff8d6feb0e26a95968897a01e5c3217d031 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 18 Sep 2025 11:48:16 -0700 Subject: [PATCH 07/10] Tweak claude's instructions. --- .claude/commands/corpus-loop.md | 19 +++++++++++++++++-- CLAUDE.md | 2 +- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/.claude/commands/corpus-loop.md b/.claude/commands/corpus-loop.md index 6662d62..fe602c1 100644 --- a/.claude/commands/corpus-loop.md +++ b/.claude/commands/corpus-loop.md @@ -1,6 +1,6 @@ --- argument-hint: [corpus_slug] -description: uses Playwright MCP and the `corpus:view` dev environment to help with parsing page elements +description: uses Playwright MCP and the `corpus:view` to parse page elements --- - using Playwright MCP, navigate to `http://localhost:3001/corpus/$1/gitcasso` @@ -39,4 +39,19 @@ description: uses Playwright MCP and the `corpus:view` dev environment to help w If you make a change to the code of the enhancer, you can click the button with id `gitcasso-rebuild-btn`. It will trigger a rebuild of the browser extension, and then refresh the page. You'll be able to see the effects of your change in the `gitcasso-comment-spots` div described above. -When writing `tryToEnhance` methods, don't hedge your bets and write lots of fallback code or strings of `?.`. Have a specific piece of data you want to get, use non-null `!` assertions where necessary to be clear about getting. The data they are extracting is going to change over time, and it's easier to fix broken ones if you know exactly what used to work. If the code has lots of branching paths, it's harder to tell what it was doing. \ No newline at end of file +## Common extraction workflow + +If you see `"title": "TODO_TITLE"` or similar hardcoded `TODO` values in the JSON output, this indicates the enhancer needs some kind of extraction implemented: + +1. **Find the enhancer**: Search for the `type` value (e.g., `GH_ISSUE_ADD_COMMENT`) in `src/lib/enhancers/` +2. **Implement extraction**: Replace hardcoded title with DOM extraction: + ```javascript + const title = document.querySelector('main h1')!.textContent.replace(/\s*#\d+$/, '').trim() + ``` +4. **Test with rebuild**: Click the 🔄 button to rebuild and verify the title appears correctly in the JSON + +## Extraction code style + +- Don't hedge your bets and write lots of fallback code or strings of `?.`. Have a specific piece of data you want to get, use non-null `!` assertions where necessary to be clear about getting. +- If a field is empty, represent it with an empty string. Don't use placeholders when extracting data. +- The pages we are scraping are going to change over time, and it's easier to fix broken ones if we know exactly what used to work. If the code has lots of branching paths, it's harder to tell what it was doing. \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md index 2edfa38..2fbb37a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,3 +1,3 @@ -Please refer to `CONTRIBUTING.md` and `README.md`. +Refer to `CONTRIBUTING.md` for the project's architecture and useful commands. Whenever you complete a task, if you wish some info had been provided to you ahead of time instead of figuring it out from scratch, you have permission to edit this `CLAUDE.md` to add any helpful context. From b32f900b24728bb41d1e51cd77f0099802fa6d8c Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 18 Sep 2025 11:48:21 -0700 Subject: [PATCH 08/10] Format fixup. --- .gitignore | 6 +----- src/lib/enhancers/github/githubIssueAddComment.tsx | 5 ++++- src/lib/enhancers/github/githubPRAddComment.tsx | 5 ++++- tests/corpus-view.ts | 4 ++-- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index 4ce6898..76301ea 100644 --- a/.gitignore +++ b/.gitignore @@ -17,9 +17,5 @@ dist/ .DS_Store Thumbs.db -# playright +# playwright .playwright-mcp/ -browser-extension/dist-playground/ -browser-extension/playwright-report/ -browser-extension/playwright/ -browser-extension/test-results/ diff --git a/src/lib/enhancers/github/githubIssueAddComment.tsx b/src/lib/enhancers/github/githubIssueAddComment.tsx index 9158c1e..70f7fed 100644 --- a/src/lib/enhancers/github/githubIssueAddComment.tsx +++ b/src/lib/enhancers/github/githubIssueAddComment.tsx @@ -42,7 +42,10 @@ export class GitHubIssueAddCommentEnhancer implements CommentEnhancer response.text()) From 1c391832a57b576503bf0ee24e54f9528839e24f Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 18 Sep 2025 12:20:17 -0700 Subject: [PATCH 09/10] parse out the title and branch/repo information for new PRs. --- .../enhancers/github/githubPRNewComment.tsx | 30 ++++++++++++++----- tests/lib/enhancers/github.test.ts | 12 +++++--- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/lib/enhancers/github/githubPRNewComment.tsx b/src/lib/enhancers/github/githubPRNewComment.tsx index c3f5818..ae5d3da 100644 --- a/src/lib/enhancers/github/githubPRNewComment.tsx +++ b/src/lib/enhancers/github/githubPRNewComment.tsx @@ -8,7 +8,11 @@ import { prepareGitHubHighlighter } from './githubHighlighter' interface GitHubPRNewCommentSpot extends CommentSpot { type: 'GH_PR_NEW_COMMENT' domain: string - slug: string // owner/repo/base-branch/compare-branch + slug: string // owner/repo + title: string + head: string // branch name where changes are implemented + head_repo?: string // repository where changes were made (for cross-repo PRs) + base: string // branch you want changes pulled into } export class GitHubPRNewCommentEnhancer implements CommentEnhancer { @@ -38,13 +42,25 @@ export class GitHubPRNewCommentEnhancer implements CommentEnhancer { { "for": "id=pull_request_body name=pull_request[body] className=js-comment-field js-paste-markdown js-task-list-field js-quick-submit FormControl-textarea CommentBox-input js-size-to-fit size-to-fit js-session-resumable js-saved-reply-shortcut-comment-field CommentBox-input--large overtype-input", "spot": { + "base": "main", "domain": "github.com", - "slug": "diffplug/selfie/main...cavia-porcellus:selfie:main", + "head": "cavia-porcellus:selfie:main", + "head_repo": undefined, + "slug": "diffplug/selfie", + "title": "Update README.md", "type": "GH_PR_NEW_COMMENT", - "unique_key": "github.com:diffplug/selfie/main...cavia-porcellus:selfie:main", + "unique_key": "github.com:diffplug/selfie:main...cavia-porcellus:selfie:main", }, - "title": "TITLE_TODO", + "title": "Update README.md", "upperDecoration": New PR @@ -96,7 +100,7 @@ describe('github', () => { className="font-mono text-muted-foreground text-sm" > - diffplug/selfie/main...cavia-porcellus:selfie:main + diffplug/selfie , From 95ae87121cee134daa8a29758bf5d9c9373afd58 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 18 Sep 2025 12:25:54 -0700 Subject: [PATCH 10/10] Remove the `head_repo` stuff, it's a bit optimisitc right now. --- src/lib/enhancers/github/githubPRNewComment.tsx | 17 +++++------------ tests/lib/enhancers/github.test.ts | 1 - 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/lib/enhancers/github/githubPRNewComment.tsx b/src/lib/enhancers/github/githubPRNewComment.tsx index ae5d3da..76a4a36 100644 --- a/src/lib/enhancers/github/githubPRNewComment.tsx +++ b/src/lib/enhancers/github/githubPRNewComment.tsx @@ -10,8 +10,7 @@ interface GitHubPRNewCommentSpot extends CommentSpot { domain: string slug: string // owner/repo title: string - head: string // branch name where changes are implemented - head_repo?: string // repository where changes were made (for cross-repo PRs) + head: string // `user:repo:branch` where changes are implemented base: string // branch you want changes pulled into } @@ -44,23 +43,17 @@ export class GitHubPRNewCommentEnhancer implements CommentEnhancer { "base": "main", "domain": "github.com", "head": "cavia-porcellus:selfie:main", - "head_repo": undefined, "slug": "diffplug/selfie", "title": "Update README.md", "type": "GH_PR_NEW_COMMENT",