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
14 changes: 14 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,20 @@ jobs:
- name: Package extension
run: npm run package

- name: Install acceptance browser
run: npx playwright install --with-deps chromium

- name: Accept exact release ZIP in browser
run: npm run test:browser

- name: Upload browser acceptance evidence
if: always()
uses: actions/upload-artifact@v4
with:
name: browser-acceptance-${{ github.sha }}
path: output/browser-acceptance/
if-no-files-found: error

- name: Verify package artifact
run: npm run verify:package

Expand Down
16 changes: 15 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,27 @@ jobs:
- name: Package extension
run: npm run package

- name: Install acceptance browser
run: npx playwright install --with-deps chromium

- name: Accept exact release ZIP in browser
run: npm run test:browser

- name: Upload browser acceptance evidence
if: always()
uses: actions/upload-artifact@v4
with:
name: browser-acceptance-${{ github.sha }}
path: output/browser-acceptance/
if-no-files-found: error

- name: Verify package artifact
run: npm run verify:package -- "$ZIP_PATH"

- name: Create draft GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release create "$GITHUB_REF_NAME" "$ZIP_PATH" "$ZIP_PATH.sha256" \
gh release create "$GITHUB_REF_NAME" "$ZIP_PATH" "$ZIP_PATH.sha256" output/browser-acceptance/acceptance.json \
--title "Dev Feedback Capture $GITHUB_REF_NAME" \
--generate-notes --draft
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Electron developers can explicitly install `@flyingchangescode/dev-feedback-elec

Run `npm ci`, `npm test`, `npm run check`, `npm run audit:dependencies`, `npm run package`, and `npm run verify:package`. The browser ZIP excludes tests, MCP code, and Node dependencies.

Before publishing, follow [docs/manual-release-checklist.md](docs/manual-release-checklist.md). Tagged GitHub releases are created as drafts; Store submission and Google approval are separate steps.
Before publishing, run the [automated exact-ZIP browser gate](docs/browser-release-acceptance.md). Tagged GitHub releases are created as drafts; Store submission and Google approval are separate steps.

Core files: `popup.*`, `content.js`, `collector.js`, `element.*`, `background.js`, `history.*`, `shared.js`, and `ai-bundle.js`.

Expand Down
40 changes: 40 additions & 0 deletions docs/browser-release-acceptance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Automated browser release acceptance

As of September 9, 2026, the owner authorizes repeatable automated acceptance to replace the human-only browser release gate. GitHub publication requires a passing gate against the exact ZIP being published. Chrome Web Store submission, listing screenshots, and Google approval remain separate.

Run from a clean checkout with Node 22 or later and the standard `unzip` utility:

```sh
npm ci
npx playwright install --with-deps chromium
npm test
npm run check
npm run audit:dependencies
npm run package
npm run test:browser
npm run verify:package
git diff --check
```

`npm run test:browser -- /absolute/path/to/package.zip` accepts an explicit ZIP. It extracts into a fresh temporary directory, loads those files with the original manifest, and verifies the ZIP digest and every extracted file before and after execution. No host permissions, content scripts, or test hooks are added to the extension. The locked Playwright dependency selects the acceptance browser. CI and release workflows run the same script after packaging; the release workflow attaches the resulting digest-bound `acceptance.json` to the draft release alongside the tested ZIP and checksum.

The harness uses Chrome for Testing's extension debugging API to invoke the actual toolbar action on the source tab. This grants real `activeTab` access and opens the native popup. Trusted browser mouse events operate popup controls; trusted keyboard and pointer events select page elements. Native popup targets require a CDP session because they are not ordinary Playwright tabs.

Coverage includes:

- Toolbar activation, keyboard selection, Escape, pointer selection, private editor context, and Save & pick next.
- Refusal to replace an open draft, keep-editing/discard dialogs, a real 500-record capacity rejection, and a successful single-record retry.
- On-page History without new tabs, note/check editing with preserved capture identity, and persistence after closing the source tab.
- Synthetic legacy Region/PDF and Visual/Add records, decoded original/proposed/redacted images, selected deletion, and preservation of hidden records.
- All five selected exports: preview contents, downloaded JSON/HTML/ZIP bytes, rendered HTML, and actual clipboard readback.
- Native restricted-page popup History with capture disabled.

Evidence is written to `output/browser-acceptance/`: a JSON report tied to the ZIP SHA-256, browser trace, synthetic screenshots, and export artifacts. Temporary profiles, server, and browsers are closed at completion. CI retains evidence even when the test fails. Do not treat partial output or an old passing report as acceptance of a different digest.

## Narrow limits

This gate exercises isolated Chrome for Testing, not every installed Chrome/Edge version. CDP toolbar activation uses the browser's real action path but does not exercise the operating system's global shortcut dispatcher; manifest/command registration and trusted in-page keyboard selection provide separate evidence. A user-customized or OS-conflicting shortcut may still need adjustment.

Legacy/capacity data is seeded through Chrome's storage debugging API. Clipboard read permission is granted only to the temporary browser context so tests can read back exports; the shipping manifest remains `storage`, `activeTab`, and `scripting`. Clipboard text is restored after readback. Screenshot and DOM assertions supplement exported-byte and persisted-record assertions; they do not certify every screen size or assistive technology.

The browser ZIP does not include the separate Electron package, local MCP companion, or unmerged SwiftUI prototype. MCP tests validate the separate companion contract; end-to-end implementation in a consumer's project and that consumer's Downloads configuration are not prerequisites for the browser ZIP's GitHub publication.
8 changes: 4 additions & 4 deletions docs/manual-release-checklist.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Manual Release Checklist
# Release Checklist

Automated checks are necessary but do not replace the exact-package unpacked-extension gate. Headless QA may use an isolated synthetic-page profile while the owner uses their Mac; record any test-only permission differences. See `docs/store-release-1.8.0.md` for the current candidate’s evidence and remaining limits.
The owner authorized automated exact-ZIP browser acceptance on September 9, 2026, replacing the human-only browser gate for GitHub releases. Follow [browser-release-acceptance.md](browser-release-acceptance.md). The historical records below do not override that authorization. Store submission, listing updates, and Google approval remain separate.

Store status on August 3, 2026: v1.7.0 is public in the Chrome Web Store, v1.7.1 was cancelled, and v1.7.2 is pending review for automatic publication. The distributed CRX contains the Browser Code icon, while the Store listing still renders the retired purple-flag artwork. Store approval is not proof that the deferred checks below passed. Keep them open and do not call these releases runtime-verified until the relevant evidence is recorded.

Expand Down Expand Up @@ -28,9 +28,9 @@ For that historical package:
- In the durable owner account, update the Store overview, screenshots, and optional video, then upload the exact verified v1.7.1 ZIP. Re-read the upload status before submitting for review.
- After publication, confirm the Store listing and a clean Google result both show the Browser Code icon, revised title, short description, public version, and current screenshots. If the retired purple-flag asset remains despite the verified ZIP icon, record the listing asset URL and escalate through Chrome Web Store support rather than claiming the refresh worked.

## Active Element release check
## Element acceptance coverage and separate integration/Store checks

The product was narrowed after hands-on review. New Region/PDF capture is removed; do not use the earlier broad workflow as an acceptance checklist for this release.
The product was narrowed after hands-on review. New Region/PDF capture is removed. The automated gate covers browser behavior below; configured MCP implementation and Store steps remain separate and are not human-only blockers to GitHub publication.

- Verify the exact release ZIP and minimal manifest permissions.
- When replacing an unpacked build in an existing test profile, enable Developer mode and use Chrome’s extension Reload control. Restarting Chrome alone can leave the old service-worker behavior active; a new manifest or files on disk is insufficient proof.
Expand Down
2 changes: 1 addition & 1 deletion docs/software-catalog-release-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The product story is: a Chromium extension for collecting structured feedback fr
- `.github/workflows/release.yml` publishes a zip asset when a matching `v*` tag is pushed.
- GitHub Release `v1.2.0` is published with `dev-feedback-capture-v1.2.0.zip`.

`product.json.downloadUrl` remains a fallback to a known published asset. Do not update it until the active browser capture core passes the manual browser gate and the matching asset is actually published. The latest-release API remains the preferred source for consumers that can resolve the newest matching asset automatically.
`product.json.downloadUrl` remains a fallback to a known published asset. Do not update it until the active browser capture core passes the automated exact-ZIP browser gate and the matching asset is actually published. The latest-release API remains the preferred source for consumers that can resolve the newest matching asset automatically.

## Catalog Metadata

Expand Down
4 changes: 3 additions & 1 deletion docs/store-release-1.8.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ Single purpose: Collect structured feedback about selected webpage elements and

## Validation and package

September 9 update: GitHub releases now use the [automated exact-ZIP browser gate](browser-release-acceptance.md). Its digest-bound report supersedes the human-only requirement and earlier test-only permission differences below. Store listing, screenshots, and submission remain separate.

Validated locally on September 5, 2026:

- `npm test`: 49 tests across extension/privacy, Electron, and MCP, plus release assertions; passed.
Expand All @@ -50,4 +52,4 @@ Validated locally on September 5, 2026:
- PDF requests returned the popup fallback. History rendered at 360px inside the popup document without creating another tab. Native popup fallback acceptance remains separate from that automated document check.
- Imported a real browser-exported JSON through an MCP SDK stdio client, listed the selected record, and built its implementation brief. The downloaded file was copied into the approved Downloads test inbox for this check; automatic inbox delivery and implementation/verification status are still separate acceptance steps.

Remaining before submission: finish the outstanding acceptance checks in the manual checklist, capture current Store screenshots, land the reviewed source and CI, update the Store listing, and record upload/review readback. The previous main artifact is superseded and must not be submitted.
Remaining before Store submission: pass the automated gate for the selected package, capture current Store screenshots, update the Store listing, and record upload/review readback. The previous main artifact is superseded and must not be submitted.
32 changes: 31 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@
"package": "node scripts/package-extension.cjs",
"verify:package": "node scripts/verify-package.cjs",
"mcp": "node mcp/cli.mjs",
"audit:dependencies": "npm audit --omit=dev --audit-level=moderate"
"audit:dependencies": "npm audit --omit=dev --audit-level=moderate",
"test:browser": "node test/browser/release-acceptance.mjs"
},
"dependencies": {
"@modelcontextprotocol/sdk": "1.29.0",
"zod": "4.4.3"
},
"devDependencies": {
"esbuild": "0.25.12"
"esbuild": "0.25.12",
"playwright": "1.63.0"
}
}
Loading
Loading