World-class hardening: enforce type-checking, clear CVEs, tighten permissions, polish editor#2
Merged
Merged
Conversation
Upgrade Vite 5→8, Vitest 2→4, @vitejs/plugin-react 4→6, TypeScript to 5.9, and refresh @types/chrome; add @types/node. Clean reinstall resolves all 10 prior advisories (1 critical, 3 high, 5 moderate, 1 low) to zero. Tests (17/17) and build verified on the new toolchain. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PJ5c2e5VcKVhugy7TAzi4W
Type-checking was silently broken (tsc failed; CI only ran test+build via esbuild, which skips type-checking). Restore it and enforce quality gates: - tsconfig: add node types, stricter flags, skipLibCheck; tsc --noEmit now passes (fixed illegal `chrome`-as-type casts in the storage test). - ESLint flat config (typescript-eslint + react-hooks) + Prettier; convert empty shadcn interfaces to type aliases to satisfy lint. - Apply a one-time Prettier pass to source and top-level docs. - CI now runs typecheck, lint, format:check, test, build, and `npm audit --audit-level=high`; bump CI Node to 22, add .nvmrc. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PJ5c2e5VcKVhugy7TAzi4W
…ck helpers - Editor arrow-head markers filled with currentColor but the line never set color, so heads rendered in the page's default text color instead of the arrow color. Set color on the line so the head matches. - download() now mirrors the other export actions: capture-required guard, try/catch, and success/error status messaging. - Extract buildExternalLlmPrompt and annotationSummary into src/lib/feedback.ts (pure, now unit tested). - Add tests for the LLM prompt builder, box-handle geometry/cursors, and a binary base64 round-trip through local-share storage (17 → 26 tests). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PJ5c2e5VcKVhugy7TAzi4W
The manifest exposed assets/* to <all_urls> via web_accessible_resources, but nothing loads those from a foreign origin: the content script injects no extension resources into pages, and the editor/viewer load their assets as same-origin extension pages. Removing the block eliminates an extension-fingerprinting vector with no functional impact (verified the dist manifest and build). Also document the rationale for every remaining permission (and the local-only data posture) in SECURITY.md, and add a Permissions & Privacy section plus the new dev-command scripts to the README. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PJ5c2e5VcKVhugy7TAzi4W
The extension shipped with no icon (default puzzle piece). Add a camera mark in the app's emerald theme at 16/32/48/128 and wire it into the manifest (icons + action.default_icon). Icons are generated by scripts/generate-icons.mjs (pure Node + zlib, no image deps) so they are reproducible in CI via `npm run gen:icons`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PJ5c2e5VcKVhugy7TAzi4W
- Esc clears the current selection and any in-progress draw/drag/resize; Delete/Backspace removes the selected annotation (ignored while typing in a field so comment editing is unaffected). Surface the hints in the help text. - Add a 'Saved Shares' panel that lists persisted local shares (page, time, size) with open/delete actions, backed by the existing listLocalShares / deleteLocalShare APIs. Refreshes on mount and after creating a share. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PJ5c2e5VcKVhugy7TAzi4W
… changes - CONTRIBUTING referenced a non-existent .docs/doing/current-task.md; replace with the FIREHOSE per-change folder workflow and the new quality gates. - Sync next-improvements and the dated priority TODO with what the hardening sweep resolved (deps, permissions docs, tests) and what remains (manual QA, editor integration tests). - Archive completed change folders to .docs/done/: box-resize, firehose-compliance-alignment, and world-class-hardening (each with a completion summary). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PJ5c2e5VcKVhugy7TAzi4W
- engines.node: align floor with Vite 8's supported range (^20.19.0 || >=22.12.0) so Node 21/23 don't satisfy engines while Vite 8 rejects them. - design.md: correct the permissions note to reflect that web_accessible_resources was removed entirely (not narrowed); extension pages load their own assets as same-origin resources. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PJ5c2e5VcKVhugy7TAzi4W
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A full review-driven hardening sweep across four workstreams. Every commit is verified against the new gates (typecheck + lint + format + tests + build), and the final state passes
npm ciwith 0 vulnerabilities.See
.docs/done/2026-06-20-world-class-hardening/for the full proposal/spec/design/tasks/completion-summary.1 · Dependency security
@vitejs/plugin-react4→6, TypeScript→5.9; refreshed@types/chrome; added@types/node.npm audit: 10 advisories (1 critical, 3 high, 5 moderate, 1 low) → 0.2 · Foundational hardening
tscfailed; CI only ran test+build via esbuild). Restored it and fixed the failing cases.typecheck,lint,format:check,test,build, andnpm audit --audit-level=high; Node bumped to 22; added.nvmrc+engines.download(); extracted pure helpers tosrc/lib/feedback.ts. Tests 17 → 26 (LLM prompt, box-handle geometry, binary base64 round-trip).3 · Permission tightening
web_accessible_resourcesblock (exposedassets/*to every site — a fingerprinting vector with no functional use).SECURITY.md+README.md.4 · Polish & features
CONTRIBUTINGreference, archived completed change folders, synced TODOs.Verification
npm run check(typecheck + lint + test + build) andnpm run format:checkpass.npm ciclean; 0 audit advisories.Deferred (cannot run in CI)
host_permissions: <all_urls>and static content-script registration kept by design (general screenshot tool needs broad capture access); on-demand-only injection tracked innext-improvements.md.🤖 Generated with Claude Code
https://claude.ai/code/session_01PJ5c2e5VcKVhugy7TAzi4W
Generated by Claude Code