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
22 changes: 22 additions & 0 deletions .docs/done/2026-06-20-box-resize/completion-summary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Completion Summary: Box Resize After Creation

## What changed

- Added `src/lib/boxResize.ts` with handle geometry, crossing normalization, and
bounds/min-size constraints.
- Wired resize state and pointer lifecycle into the editor; resize handles render
for the selected box in move mode.
- Box move behavior is preserved when dragging the body.

## Validation

- Unit tests cover crossing/flip and clamp behavior (`tests/boxResize.test.ts`),
with handle-position and cursor-mapping tests added during the world-class
hardening sweep.
- `npm run test` and `npm run build` pass.

## Deferred

- Manual in-browser QA (create → resize from corners/edges → move; verify
export/share include resized boxes). Not runnable in CI; track in the next
manual smoke test.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Completion Summary: FIREHOSE Compliance Alignment

## What changed

- Established the per-change folder format under `.docs/doing/`
(`proposal.md` / `spec.md` / `design.md` / `tasks.md`).
- Removed the legacy `.docs/doing/current-task.md` single-file tracker.
- Confirmed `.docs/` is not git-ignored and remains source-of-truth.

## Validation

- `.docs/` structure follows the FIREHOSE folder format.

## Follow-ups

- None.
55 changes: 55 additions & 0 deletions .docs/done/2026-06-20-world-class-hardening/completion-summary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Completion Summary: World-Class Hardening Sweep

## What changed

**Dependency security**

- Upgraded Vite 5→8, Vitest 2→4, @vitejs/plugin-react 4→6, TypeScript→5.9, and
refreshed `@types/chrome`; added `@types/node`. `npm audit` went from 10
advisories (1 critical, 3 high, 5 moderate, 1 low) to **0**.

**Foundational hardening**

- Restored type-checking (`tsc --noEmit` was failing and unenforced); fixed the
tsconfig and the illegal `chrome`-as-type casts in the storage test.
- Added ESLint (flat config: typescript-eslint + react-hooks) and Prettier, with
a one-time formatting pass.
- CI now runs `typecheck`, `lint`, `format:check`, `test`, `build`, and
`npm audit --audit-level=high`; CI Node bumped to 22; added `.nvmrc` and an
`engines` field.
- Fixed the editor arrow-head color bug (markers inherited page text color).
- Hardened `download()` with a guard, try/catch, and status messaging.
- Extracted pure helpers to `src/lib/feedback.ts`; test count 17 → 26 (LLM
prompt, box-handle geometry, binary base64 round-trip).

**Permission tightening**

- Removed the unused `web_accessible_resources` block (eliminates an
extension-fingerprinting vector; no functional impact — verified in `dist`).
- Documented every permission's rationale and the local-only data posture in
`SECURITY.md` and `README.md`.

**Polish & features**

- Added real extension icons (16/32/48/128) via a reproducible, dependency-free
generator (`scripts/generate-icons.mjs`), wired into the manifest.
- Editor keyboard shortcuts: Esc to deselect, Delete/Backspace to remove the
selected annotation (ignored while typing).
- Added a "Saved Shares" panel (list / open / delete) over existing storage APIs.
- Doc cleanup: fixed the stale `CONTRIBUTING.md` reference, aligned it with the
FIREHOSE workflow + new gates, archived two completed change folders, and
synced the TODO docs.

## Risks / follow-ups

- `host_permissions: <all_urls>` and the static content-script registration were
kept intentionally (a general screenshot tool needs broad capture access, and
injection changes can't be verified in CI). On-demand-only injection is tracked
in `next-improvements.md`.
- Manual in-browser QA (capture/annotate/share across popup/editor/viewer) is not
runnable in CI and remains the main outstanding verification.

## Validation

- `npm run check` (typecheck + lint + test + build) and `npm run format:check`
all pass; 26/26 tests; 0 audit advisories.
49 changes: 49 additions & 0 deletions .docs/done/2026-06-20-world-class-hardening/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Design: World-Class Hardening Sweep

## Toolchain versions
Chosen for mutual compatibility and stability over bleeding edge:

- Vite `^8`, Vitest `^4`, `@vitejs/plugin-react` `^6` (clears rollup/esbuild/
postcss/yaml advisories).
- TypeScript `5.9.x` (not 6.0: keeps `typescript-eslint` 8 in its supported
range `>=4.8.4 <6.1.0` with margin).
- ESLint `9` flat config + `typescript-eslint` `8` + `eslint-plugin-react-hooks`
`6` + `eslint-config-prettier` to defer formatting to Prettier.
- `@types/node` `^22` to match the Node 22 dev / Node 20 CI runtime.

## Type-checking
`tsc --noEmit` failed because:
- node-context files (`vite.config.ts`, `tests/localStore.test.ts`) used
`node:*` modules, `__dirname`, and the `NodeJS` namespace without node types;
- tests used the ambient `chrome` namespace as a *type* (`as unknown as chrome`)
which is illegal — `chrome` is a value namespace.

Fix: add `node` to `compilerOptions.types`, add `@types/node`, and change the
test casts to `typeof chrome`. A single root `tsconfig.json` keeps the setup
simple (the project is small); `skipLibCheck` is enabled to avoid third-party
`.d.ts` noise.

## Arrow-head color bug
The SVG `<marker>` polygon uses `fill="currentColor"`, but the referencing
`<line>` never sets `color`, so heads inherit the page's default text color
instead of the annotation color. Fix: set `color` on the line via inline style
so `currentColor` resolves per annotation. The exported (canvas) path already
draws heads correctly and is unchanged.

## Permissions
Capture relies on `activeTab` + `scripting` + `tabs` + `captureVisibleTab`, plus
a static content script. Reducing `host_permissions`/`content_scripts` from
`<all_urls>` risks breaking capture and cannot be verified from CI, so those are
left intact and documented. `web_accessible_resources` is **removed entirely**:
`editor.html`/`viewer.html` open as top-level `chrome-extension://` pages, so
their `assets/*` chunks load as same-origin extension resources and never need to
be web-accessible; the content script injects no extension resources into pages.
The block was therefore dead config whose only effect was exposing `assets/*` to
every origin (an extension-fingerprinting vector). See `SECURITY.md` for the
shipped rationale.

## Local-share management
`listLocalShares()` / `deleteLocalShare()` already exist but have no UI. Add a
collapsible "Saved shares" panel to the editor that lists recent shares (page,
timestamp, size), opens the viewer, and deletes entries. Pure read/delete over
existing storage APIs — no schema change.
38 changes: 38 additions & 0 deletions .docs/done/2026-06-20-world-class-hardening/proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Proposal: World-Class Hardening Sweep

## Why
A full review found the product logic is sound and tested, but the engineering
baseline has gaps that block a "world-class" grade: type-checking is broken and
unenforced, there is no linter/formatter, the dependency tree carries 10 known
vulnerabilities, extension permissions are broader than needed, the popup ships
with no icon, and a few small correctness/UX issues remain.

## Scope
Four workstreams, ordered by risk:

1. **Dependency security** — upgrade the build/test toolchain (Vite, Vitest,
plugin-react, TypeScript, type packages) to clear all `npm audit` findings.
2. **Foundational hardening** — restore and enforce `tsc` type-checking, add
ESLint (flat config) + Prettier, wire both into CI, fix the arrow-head color
bug, harden `download()` error handling, and add tests for previously
untested pure logic.
3. **Permission tightening** — narrow `web_accessible_resources` and document
the rationale for the remaining permissions in `SECURITY.md` / `README.md`.
Conservative: capture cannot be re-verified in a real browser from CI.
4. **Polish & features** — add real extension icons, keyboard shortcuts (Esc to
deselect, Delete to remove selected), a local-share management surface, and
clean up documentation/process drift.

## Out of Scope
- React 18 → 19 and Tailwind 3 → 4 migrations (not vulnerability-driven; high
churn for no security benefit).
- Decomposing the editor component into smaller modules (large refactor; deferred
to a follow-up change).
- Cloud/hosted sharing (explicit non-goal in the PRD).

## Risks
- Major toolchain bumps (Vite 5→8, Vitest 2→4) can break the build/tests;
mitigated by running `test` + `build` + `typecheck` after each step.
- Permission changes affect runtime capture behavior that cannot be verified
here; mitigated by keeping `activeTab`/`scripting`-based capture intact and
only tightening clearly-safe surfaces.
49 changes: 49 additions & 0 deletions .docs/done/2026-06-20-world-class-hardening/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Spec: World-Class Hardening Sweep

### Requirement: Enforced type-checking

The build pipeline SHALL fail when TypeScript reports type errors.

#### Scenario: Type error is introduced

- GIVEN a change that introduces a TypeScript type error
- WHEN CI runs
- THEN `npm run typecheck` fails and the pipeline is red

### Requirement: Clean dependency audit

The project SHALL carry no known high or critical dependency vulnerabilities.

#### Scenario: Audit gate

- GIVEN the installed dependency tree
- WHEN `npm audit --audit-level=high` runs in CI
- THEN it reports no high or critical advisories

### Requirement: Minimal web-exposed surface

The extension SHALL NOT expose resources to web origins that it does not need.

#### Scenario: No web-accessible resources

- GIVEN the built `dist/manifest.json`
- WHEN it is inspected
- THEN `web_accessible_resources` is absent
- AND the editor/viewer/popup still load their own assets

### Requirement: Editor keyboard shortcuts

The editor SHALL let users deselect and delete annotations via the keyboard,
without interfering with text entry.

#### Scenario: Delete selected annotation

- GIVEN an annotation is selected and focus is not in a text field
- WHEN the user presses Delete or Backspace
- THEN the selected annotation is removed

#### Scenario: Typing a comment is unaffected

- GIVEN the comment editor is focused
- WHEN the user presses Backspace
- THEN the character is deleted from the comment, not the annotation
32 changes: 32 additions & 0 deletions .docs/done/2026-06-20-world-class-hardening/tasks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Tasks: World-Class Hardening Sweep

## 1. Dependency security
- [x] 1.1 Upgrade Vite 5→8, Vitest 2→4, @vitejs/plugin-react 4→6
- [x] 1.2 Upgrade TypeScript to 5.9.x, @types/chrome, add @types/node
- [x] 1.3 Run `npm audit`; resolve remaining findings (0 vulnerabilities)
- [x] 1.4 Verify `npm run test` and `npm run build`

## 2. Foundational hardening
- [x] 2.1 Fix tsconfig so `tsc --noEmit` passes (node types, test/config typing)
- [x] 2.2 Add `typecheck` script
- [x] 2.3 Add ESLint flat config + `lint` script
- [x] 2.4 Add Prettier config + `format`/`format:check` scripts
- [x] 2.5 Fix arrow-head color bug in editor preview
- [x] 2.6 Harden `download()` with error handling
- [x] 2.7 Add tests: external LLM prompt, base64↔blob round-trip, handle geometry
- [x] 2.8 Wire typecheck + lint into CI
- [x] 2.9 Add `engines` field + `.nvmrc`

## 3. Permission tightening
- [x] 3.1 Remove unused `web_accessible_resources` (dead config; fingerprinting vector)
- [x] 3.2 Document permission rationale in SECURITY.md and README.md

## 4. Polish & features
- [x] 4.1 Add extension icons (16/32/48/128) + manifest wiring
- [x] 4.2 Keyboard shortcuts: Esc deselect, Delete/Backspace remove selected
- [x] 4.3 Local-share management UI (list/open/delete) in editor
- [x] 4.4 Doc/process cleanup (CONTRIBUTING, archive completed changes, TODO sync)

## 5. Validation
- [x] 5.1 `npm run typecheck`, `npm run lint`, `npm run test`, `npm run build` all pass
- [x] 5.2 Completion summary added
41 changes: 25 additions & 16 deletions .docs/todo/2026-02-23-priority-todo.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,39 @@
# TODO: Monday, February 23, 2026

> **Status (updated 2026-06-20):** Most items were resolved by the world-class
> hardening sweep (`.docs/done/2026-06-20-world-class-hardening/`). Remaining
> open work is manual QA and editor integration tests. See per-item notes.

## 1. Security and Permissions (Highest Priority)
- [ ] Reduce extension scope in `public/manifest.json`:
- limit `host_permissions` from `"<all_urls>"` to explicit domains or runtime-justified patterns
- review whether static `content_scripts` on all URLs can be replaced with on-demand injection
- [ ] Document permission rationale in `SECURITY.md` and `README.md`.

- [~] Reduce extension scope in `public/manifest.json`:
- host_permissions kept at `<all_urls>` **by design** — a general screenshot
tool has no fixed site allowlist; rationale documented in `SECURITY.md`.
- removed the unused `web_accessible_resources` (fingerprinting vector).
- on-demand-only content-script injection tracked in `next-improvements.md`.
- [x] Document permission rationale in `SECURITY.md` and `README.md`.

## 2. Dependency Security Upgrades
- [ ] Address `npm audit` findings (currently 5 moderate):
- evaluate upgrade path for `vite` and `vitest` major versions
- run full regression checks after upgrades (`npm run test`, `npm run build`, manual extension smoke test)
- [ ] Add a follow-up note in `.docs/done` with final vulnerability status.

- [x] Address `npm audit` findings — upgraded Vite 5→8, Vitest 2→4, plugin-react
4→6, TypeScript 5.9; now **0 vulnerabilities**.
- [x] Final vulnerability status recorded in the world-class-hardening
completion summary.

## 3. UI Refinement Follow-ups
- [ ] Run manual QA pass across popup/editor/viewer after the Tailwind refresh:

- [ ] Run manual QA pass across popup/editor/viewer (not runnable in CI):
- popup sizing on different Chrome zoom levels
- editor timeline readability and button hierarchy
- viewer metadata readability on narrow widths
- [ ] Tweak spacing/typography only where visual regressions are observed.

## 4. Test Coverage Improvements
- [ ] Add integration-style tests for:
- annotation timeline item selection/delete flow
- cloud LLM export action path
- local share retrieval path in viewer

- [~] Added unit tests for pure logic (LLM prompt, base64 round-trip, handle
geometry). Editor integration-style tests (timeline select/delete, cloud
export, viewer retrieval) remain open — see `next-improvements.md`.

## 5. Process Cleanup
- [ ] Decide whether `.docs/doing/firehose-compliance-alignment/` should be archived to `.docs/done/`.
- [ ] Keep `.docs/todo/next-improvements.md` in sync with decisions made tomorrow.

- [x] Archived `firehose-compliance-alignment` and `box-resize` to `.docs/done/`.
- [x] Kept `.docs/todo/next-improvements.md` in sync.
15 changes: 12 additions & 3 deletions .docs/todo/next-improvements.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
# Backlog: Next Improvements

- Add keyboard shortcuts for delete/select/undo in editor.
## Open

- Improve comment badge placement to avoid overlap for long comments.
- Add import/export JSON for annotations and feedback.
- Add optional cloud-share mode behind explicit user opt-in.
- Add integration tests for annotation edit, timeline delete, and single-editor mode.
- Add user-facing storage usage indicator and cleanup tools for local shares.
- Add integration-style tests for the editor (annotation edit, timeline delete,
single-editor mode) — current coverage is unit-level on pure helpers.
- Show a total local-storage usage indicator (per-share size is shown today).
- Evaluate moving the content script fully to on-demand injection (drop the
static `<all_urls>` registration). See `SECURITY.md` → Known follow-up.

## Done (see `.docs/done/2026-06-20-world-class-hardening/`)

- Keyboard shortcuts for select/delete in the editor (Esc / Delete).
- Local-share management UI (list / open / delete).
6 changes: 5 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: npm
- run: npm ci
- run: npm run typecheck
- run: npm run lint
- run: npm run format:check
- run: npm run test
- run: npm run build
- run: npm audit --audit-level=high
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
22
6 changes: 6 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
dist/
coverage/
package-lock.json

# Planning / historical docs are prose; keep their authored formatting.
.docs/
7 changes: 7 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"printWidth": 100,
"tabWidth": 2,
"semi": true,
"singleQuote": false,
"trailingComma": "none"
}
Loading
Loading