docs(01-06): complete vite.config.ts collapse plan
- 01-06-SUMMARY.md: detailed write-up — 226 → 21 lines, Outcome A reconciliation (dist/src/offscreen/index.html), full dist layout for Plan 07's smoke test, T-1-NEW-06-01 / T-1-NEW-06-02 grep gates - STATE.md: completed_plans 5 → 6, percent 71 → 86, current plan advanced 6 → 7, two new decisions logged, session stopped_at updated - ROADMAP.md: Phase 1 plan progress row 4/7 → 6/7; 01-06-PLAN.md checked off REQ-video-ring-buffer remains unchecked — Plan 07 owns the ffprobe gate. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -72,7 +72,7 @@ directory + `vite.config.ts` inline string + `src/background/`.
|
|||||||
- [x] 01-03-PLAN.md — Offscreen recorder TDD: ring buffer + codec strict-mode + getDisplayMedia + track-ended cleanup; D-13 fallback skeleton pre-staged
|
- [x] 01-03-PLAN.md — Offscreen recorder TDD: ring buffer + codec strict-mode + getDisplayMedia + track-ended cleanup; D-13 fallback skeleton pre-staged
|
||||||
- [x] 01-04-PLAN.md — Port keepalive + OFFSCREEN_READY handshake (TDD): replaces alarms keepalive on offscreen side
|
- [x] 01-04-PLAN.md — Port keepalive + OFFSCREEN_READY handshake (TDD): replaces alarms keepalive on offscreen side
|
||||||
- [x] 01-05-PLAN.md — SW shrink: delete legacy buffer + alarms + IndexedDB + tabCapture paths; wire SW-side onConnect host
|
- [x] 01-05-PLAN.md — SW shrink: delete legacy buffer + alarms + IndexedDB + tabCapture paths; wire SW-side onConnect host
|
||||||
- [ ] 01-06-PLAN.md — Build pipeline collapse: delete vite.config.ts inline plugin + top-level offscreen/ dir; declare rollupOptions.input
|
- [x] 01-06-PLAN.md — Build pipeline collapse: delete vite.config.ts inline plugin + top-level offscreen/ dir; declare rollupOptions.input
|
||||||
- [ ] 01-07-PLAN.md — Manual smoke + ffprobe D-12 acceptance gate; commit regression fixture
|
- [ ] 01-07-PLAN.md — Manual smoke + ffprobe D-12 acceptance gate; commit regression fixture
|
||||||
|
|
||||||
### Phase 2: Stabilize DOM + event capture privacy
|
### Phase 2: Stabilize DOM + event capture privacy
|
||||||
@@ -224,7 +224,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5.
|
|||||||
|
|
||||||
| Phase | Plans Complete | Status | Completed |
|
| Phase | Plans Complete | Status | Completed |
|
||||||
|-------|----------------|--------|-----------|
|
|-------|----------------|--------|-----------|
|
||||||
| 1. Stabilize video pipeline | 4/7 | In Progress| |
|
| 1. Stabilize video pipeline | 6/7 | In Progress| |
|
||||||
| 2. Stabilize DOM + event capture privacy | 0/TBD | Not started | - |
|
| 2. Stabilize DOM + event capture privacy | 0/TBD | Not started | - |
|
||||||
| 3. Stabilize export pipeline | 0/TBD | Not started | - |
|
| 3. Stabilize export pipeline | 0/TBD | Not started | - |
|
||||||
| 4. SPEC §10 smoke verification | 0/TBD | Not started | - |
|
| 4. SPEC §10 smoke verification | 0/TBD | Not started | - |
|
||||||
|
|||||||
@@ -3,15 +3,15 @@ gsd_state_version: 1.0
|
|||||||
milestone: v2.0.0
|
milestone: v2.0.0
|
||||||
milestone_name: milestone
|
milestone_name: milestone
|
||||||
status: executing
|
status: executing
|
||||||
stopped_at: Completed Plan 01-05 — SW shrink + onConnect host wired (T-1-04 sender check, OFFSCREEN_READY handshake, port-based buffer fetch, IDB orphan cleanup, hasDocument re-sync); 9/9 tests still green; Plan 06 next (vite.config.ts collapse)
|
stopped_at: Completed Plan 01-06 — vite.config.ts collapse (226 -> 21 lines), orphan offscreen/ dir deleted, dist build green, crxjs Outcome A confirmed and SW URL reconciled (chrome.runtime.getURL('src/offscreen/index.html')); 9/9 tests still green; Plan 07 next (ffprobe acceptance gate)
|
||||||
last_updated: "2026-05-15T16:06:29.434Z"
|
last_updated: "2026-05-15T16:16:50.760Z"
|
||||||
last_activity: 2026-05-15
|
last_activity: 2026-05-15
|
||||||
progress:
|
progress:
|
||||||
total_phases: 5
|
total_phases: 5
|
||||||
completed_phases: 0
|
completed_phases: 0
|
||||||
total_plans: 7
|
total_plans: 7
|
||||||
completed_plans: 5
|
completed_plans: 6
|
||||||
percent: 71
|
percent: 86
|
||||||
---
|
---
|
||||||
|
|
||||||
# Project State
|
# Project State
|
||||||
@@ -28,12 +28,12 @@ no server, no password leaks.
|
|||||||
## Current Position
|
## Current Position
|
||||||
|
|
||||||
Phase: 1 (Stabilize Video Pipeline) — EXECUTING
|
Phase: 1 (Stabilize Video Pipeline) — EXECUTING
|
||||||
Plan: 6 of 7
|
Plan: 7 of 7
|
||||||
Status: Ready to execute
|
Status: Ready to execute
|
||||||
Last activity: 2026-05-15
|
Last activity: 2026-05-15
|
||||||
REQUIREMENTS.md, ROADMAP.md, STATE.md written)
|
REQUIREMENTS.md, ROADMAP.md, STATE.md written)
|
||||||
|
|
||||||
Progress: [███████░░░] 71%
|
Progress: [█████████░] 86%
|
||||||
|
|
||||||
## Performance Metrics
|
## Performance Metrics
|
||||||
|
|
||||||
@@ -64,6 +64,7 @@ Progress: [███████░░░] 71%
|
|||||||
| Phase 1 P03 | 8min | 3 tasks | 5 files |
|
| Phase 1 P03 | 8min | 3 tasks | 5 files |
|
||||||
| Phase 01 P04 | 4min | 3 tasks | 1 files |
|
| Phase 01 P04 | 4min | 3 tasks | 1 files |
|
||||||
| Phase 01 P05 | 8min | 2 tasks | 1 files |
|
| Phase 01 P05 | 8min | 2 tasks | 1 files |
|
||||||
|
| Phase 1 P06 | 3min | 2 tasks | 2 files |
|
||||||
|
|
||||||
## Accumulated Context
|
## Accumulated Context
|
||||||
|
|
||||||
@@ -98,6 +99,8 @@ current work:
|
|||||||
- [Phase ?]: [Phase 01-05]: Added chrome.offscreen.hasDocument() in initialize() — Rule 2 robustness, audit P1 #8 mitigation across SW respawns
|
- [Phase ?]: [Phase 01-05]: Added chrome.offscreen.hasDocument() in initialize() — Rule 2 robustness, audit P1 #8 mitigation across SW respawns
|
||||||
- [Phase ?]: [Phase 01-05]: SW is now a pure coordinator — onConnect host bound to 'video-keepalive' port with T-1-04 sender check; getVideoBufferFromOffscreen replaces synchronous SW-local buffer fetch; OFFSCREEN_READY handshake closes the audit P1 #12 race
|
- [Phase ?]: [Phase 01-05]: SW is now a pure coordinator — onConnect host bound to 'video-keepalive' port with T-1-04 sender check; getVideoBufferFromOffscreen replaces synchronous SW-local buffer fetch; OFFSCREEN_READY handshake closes the audit P1 #12 race
|
||||||
- [Phase ?]: [Phase 01-05]: indexedDB.deleteDatabase('VideoRecorderDB') in onInstalled — T-1-NEW-05-02 / RESEARCH.md Runtime State Inventory cleanup of orphaned IDB from pre-Phase-01 builds
|
- [Phase ?]: [Phase 01-05]: indexedDB.deleteDatabase('VideoRecorderDB') in onInstalled — T-1-NEW-05-02 / RESEARCH.md Runtime State Inventory cleanup of orphaned IDB from pre-Phase-01 builds
|
||||||
|
- [Phase ?]: [Phase 01-06]: Collapsed vite.config.ts from 226 -> 21 lines (RESEARCH.md Example B verbatim); deleted 174-line inline copy-offscreen plugin (audit P0 #1 root cause) and the orphan offscreen/ top-level directory (D-08)
|
||||||
|
- [Phase ?]: [Phase 01-06]: crxjs Outcome A confirmed — dist/src/offscreen/index.html (preserves src/ prefix from rollupOptions.input key). SW URL adjusted to chrome.runtime.getURL('src/offscreen/index.html'); RESEARCH.md Pitfall 5 binding empirically verified
|
||||||
|
|
||||||
### Pending Todos
|
### Pending Todos
|
||||||
|
|
||||||
@@ -120,7 +123,7 @@ Items acknowledged and carried forward from previous milestone close:
|
|||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-05-15T16:06:29.412Z
|
Last session: 2026-05-15T16:16:50.743Z
|
||||||
Stopped at: Completed Plan 01-05 — SW shrink + onConnect host wired (T-1-04 sender check, OFFSCREEN_READY handshake, port-based buffer fetch, IDB orphan cleanup, hasDocument re-sync); 9/9 tests still green; Plan 06 next (vite.config.ts collapse)
|
Stopped at: Completed Plan 01-06 — vite.config.ts collapse (226 -> 21 lines), orphan offscreen/ dir deleted, dist build green, crxjs Outcome A confirmed and SW URL reconciled (chrome.runtime.getURL('src/offscreen/index.html')); 9/9 tests still green; Plan 07 next (ffprobe acceptance gate)
|
||||||
intel synthesis. Coverage validated: 11/11 v1 REQs mapped.
|
intel synthesis. Coverage validated: 11/11 v1 REQs mapped.
|
||||||
Resume file: .planning/phases/01-stabilize-video-pipeline/01-06-PLAN.md
|
Resume file: None
|
||||||
|
|||||||
307
.planning/phases/01-stabilize-video-pipeline/01-06-SUMMARY.md
Normal file
307
.planning/phases/01-stabilize-video-pipeline/01-06-SUMMARY.md
Normal file
@@ -0,0 +1,307 @@
|
|||||||
|
---
|
||||||
|
phase: 01-stabilize-video-pipeline
|
||||||
|
plan: 06
|
||||||
|
subsystem: build-pipeline
|
||||||
|
tags: [vite, crxjs, rollup-input, mv3, offscreen-document, dead-code-deletion, build-config, p0-1, audit-p2-17, audit-p2-18, d-07, d-08]
|
||||||
|
|
||||||
|
# Dependency graph
|
||||||
|
requires:
|
||||||
|
- phase: 01-stabilize-video-pipeline
|
||||||
|
provides: "Plan 03 created src/offscreen/index.html + src/offscreen/recorder.ts (the crxjs-managed entry that replaces the orphan offscreen/ dir); Plan 05 left chrome.runtime.getURL('offscreen/index.html') in src/background/index.ts:45 for Plan 06 to reconcile against the actual crxjs emit path"
|
||||||
|
provides:
|
||||||
|
- "Collapsed vite.config.ts: 226 → 21 lines (-205). The 174-line inline copy-offscreen plugin (audit P0 #1 root cause) is GONE."
|
||||||
|
- "Orphan offscreen/ top-level directory deleted (offscreen/index.ts + offscreen/index.html — both dead per D-08)."
|
||||||
|
- "rollupOptions.input.offscreen wired to src/offscreen/index.html (RESEARCH.md Example B); crxjs picks up the recorder.ts module via the HTML <script> reference."
|
||||||
|
- "Outcome A confirmed: crxjs PRESERVES the src/ prefix in the bundled output — dist/src/offscreen/index.html, NOT dist/offscreen/index.html."
|
||||||
|
- "src/background/index.ts line 45 reconciled: chrome.runtime.getURL('src/offscreen/index.html') now matches the actual emit path (RESEARCH.md Pitfall 5 binding)."
|
||||||
|
- "Clean dist/ layout: manifest.json + service-worker-loader.js + 7 hashed assets/*.js bundles + bundled HTML for offscreen and popup + icons."
|
||||||
|
affects: [01-07-ffprobe-gate]
|
||||||
|
|
||||||
|
# Tech tracking
|
||||||
|
tech-stack:
|
||||||
|
added: []
|
||||||
|
patterns:
|
||||||
|
- "Minimal vite config pattern: crx() + rollupOptions.input — the canonical crxjs MV3 idiom (discussions #919 and #1060)."
|
||||||
|
- "Build-time path binding: the SW's chrome.runtime.getURL string MUST equal the rollup input key path (Pitfall 5). Verified empirically post-build, not inferred."
|
||||||
|
- "Build-config attack-surface reduction: deleting an inline plugin that called this.emitFile with a stringified JS payload removes a string-injection vector (T-1-NEW-06-01)."
|
||||||
|
|
||||||
|
key-files:
|
||||||
|
created: []
|
||||||
|
modified:
|
||||||
|
- "vite.config.ts (226 → 21 lines; the entire inline copy-offscreen plugin block, the misplaced publicDir+copyPublicDir keys, and the manualChunks:undefined shape are all gone; replaced with RESEARCH.md Example B verbatim)"
|
||||||
|
- "src/background/index.ts:45 (1-line change; getURL('offscreen/index.html') → getURL('src/offscreen/index.html') to match crxjs Outcome-A emit path)"
|
||||||
|
deleted:
|
||||||
|
- "offscreen/index.ts (60 lines of dead tabCapture-era recorder; replaced by src/offscreen/recorder.ts per D-07 / D-08)"
|
||||||
|
- "offscreen/index.html (10 lines; replaced by src/offscreen/index.html created by Plan 03)"
|
||||||
|
- "offscreen/ top-level directory (now empty; rmdir'd)"
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "Outcome A obtained: crxjs preserves the 'src/' prefix from the rollupOptions.input key. dist/src/offscreen/index.html is the emitted path, not dist/offscreen/index.html. RESEARCH.md Pitfall 5 documented both possibilities; the runtime verification settled it. SW URL string was updated accordingly (1-line fix in src/background/index.ts:45)."
|
||||||
|
- "No path adjustment via 'leaving the SW URL unchanged' (Outcome B) was used — that would have required some non-crxjs build trick to strip the src/ prefix, and there's no benefit. Outcome A is the canonical crxjs behavior; matching the SW URL to it is the simplest correct path."
|
||||||
|
- "Followed the plan's verbatim Example-B vite.config.ts (with double quotes per the plan body, which differ from the codebase's prior single-quote style — but the plan body specifies double quotes, and Prettier hasn't yet established a project-wide rule, so verbatim was preferred over style-rewrap)."
|
||||||
|
- "Did NOT mark REQ-video-ring-buffer complete: per the prompt and Plan 05's precedent, Plan 07's ffprobe gate is the requirement-satisfaction proof."
|
||||||
|
|
||||||
|
patterns-established:
|
||||||
|
- "crxjs entry pattern: HTML in rollupOptions.input → crxjs binds the HTML's <script type=module> ref → bundled output preserves the input key path. The SW resolves the runtime URL via chrome.runtime.getURL(<same-key>)."
|
||||||
|
- "Two-step verification flow for any future build-config change: (1) edit vite.config.ts, (2) rm -rf dist && npm run build, (3) inspect dist/ for the actual emit paths, (4) reconcile any SW/manifest references that hard-code paths. This avoids the Pitfall 5 class of 'works locally because no one ran the build' bugs."
|
||||||
|
|
||||||
|
requirements-completed: [] # REQ-video-ring-buffer remains pending Plan 07 ffprobe gate
|
||||||
|
|
||||||
|
# Metrics
|
||||||
|
duration: 3min
|
||||||
|
completed: 2026-05-15
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 01 Plan 06: Vite Config Collapse Summary
|
||||||
|
|
||||||
|
**Collapsed `vite.config.ts` from 226 lines to 21 by deleting the 174-line inline `copy-offscreen` plugin (audit P0 #1) and the dead `offscreen/` top-level directory; wired the new `src/offscreen/index.html` entry via `rollupOptions.input`; verified the crxjs emit path against the SW's `chrome.runtime.getURL(...)` string (Pitfall 5) and adjusted the SW URL to `src/offscreen/index.html` to match Outcome A.**
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
- **Duration:** ~3 min
|
||||||
|
- **Started:** 2026-05-15T16:09:24Z
|
||||||
|
- **Completed:** 2026-05-15T16:11:30Z
|
||||||
|
- **Tasks:** 2 (vite.config.ts rewrite + dead-code deletion; build verification + path reconciliation)
|
||||||
|
- **Commits:** 2 (one per task)
|
||||||
|
- **Files modified:** 2 (`vite.config.ts`, `src/background/index.ts`)
|
||||||
|
- **Files deleted:** 2 (`offscreen/index.ts`, `offscreen/index.html`) + 1 dir (`offscreen/`)
|
||||||
|
|
||||||
|
## Before / After
|
||||||
|
|
||||||
|
| Snapshot | vite.config.ts lines | Notes |
|
||||||
|
|----------|----------------------|-------|
|
||||||
|
| Pre-Plan 06 | **226** | Inline copy-offscreen plugin (lines 13-216) + misplaced publicDir/copyPublicDir + manualChunks:undefined shape. |
|
||||||
|
| Post-Task 1 | **21** | RESEARCH.md Example B verbatim — crx() + rollupOptions.input.offscreen. The plan's `wc -l vite.config.ts ≤ 30` ceiling is comfortably met. |
|
||||||
|
|
||||||
|
```
|
||||||
|
$ find offscreen/ 2>&1 || echo absent
|
||||||
|
bfs: error: offscreen/: No such file or directory.
|
||||||
|
absent
|
||||||
|
```
|
||||||
|
|
||||||
|
## Task 1: vite.config.ts rewrite + offscreen/ deletion
|
||||||
|
|
||||||
|
**Commit:** `23e69d0 refactor(01-06): delete inline copy-offscreen plugin and orphan offscreen/ directory`
|
||||||
|
|
||||||
|
**Deletions:**
|
||||||
|
- `offscreen/index.ts` (60 lines — orphan dead-code from tabCapture era; D-08 explicit DELETE target; audit P2 #18)
|
||||||
|
- `offscreen/index.html` (10 lines — replaced by `src/offscreen/index.html` per D-07 / Plan 03)
|
||||||
|
- `offscreen/` directory (rmdir after the two file deletes; verified empty first)
|
||||||
|
- `vite.config.ts` inline `copy-offscreen` plugin (174 lines, lines 13-216): the `this.emitFile`-based emitter for both the offscreen HTML and the stringified JS module that ran the tabCapture-era chromeMediaSource + IndexedDB recording. T-1-NEW-06-01 mitigation.
|
||||||
|
- `vite.config.ts` misplaced `publicDir: 'public'` / `copyPublicDir: true` (audit P2 #17 — there is no `public/` directory in this repo)
|
||||||
|
- `vite.config.ts` `rollupOptions.output.manualChunks: undefined` (no longer needed; crxjs handles chunking)
|
||||||
|
|
||||||
|
**Replacement — final `vite.config.ts`:**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import { crx } from '@crxjs/vite-plugin';
|
||||||
|
import manifest from './manifest.json';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [
|
||||||
|
crx({
|
||||||
|
manifest,
|
||||||
|
contentScripts: {
|
||||||
|
injectCss: false,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
build: {
|
||||||
|
rollupOptions: {
|
||||||
|
input: {
|
||||||
|
offscreen: 'src/offscreen/index.html',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**Acceptance gates (all PASS):**
|
||||||
|
|
||||||
|
| Gate | Expected | Actual |
|
||||||
|
|------|----------|--------|
|
||||||
|
| `test ! -f offscreen/index.ts` | exit 0 | PASS |
|
||||||
|
| `test ! -f offscreen/index.html` | exit 0 | PASS |
|
||||||
|
| `test ! -d offscreen` | exit 0 | PASS |
|
||||||
|
| `grep -c "copy-offscreen" vite.config.ts` | 0 | 0 |
|
||||||
|
| `grep -c "this.emitFile" vite.config.ts` | 0 | 0 (T-1-NEW-06-01 grep gate) |
|
||||||
|
| `grep -c "VideoRecorderDB" vite.config.ts` | 0 | 0 |
|
||||||
|
| `grep -c "openIndexedDB" vite.config.ts` | 0 | 0 |
|
||||||
|
| `grep -c "chromeMediaSource" vite.config.ts` | 0 | 0 |
|
||||||
|
| `grep -c "rollupOptions" vite.config.ts` | 1 | 1 |
|
||||||
|
| `grep -c "src/offscreen/index.html" vite.config.ts` | 1 | 1 |
|
||||||
|
| `wc -l vite.config.ts` | ≤ 30 | 21 |
|
||||||
|
| `npx tsc --noEmit` | exit 0 | PASS |
|
||||||
|
| `npx vitest run` | 9/9 PASS | 9/9 PASS |
|
||||||
|
|
||||||
|
## Task 2: Build verification + offscreen URL reconciliation
|
||||||
|
|
||||||
|
**Commit:** `6aeeda4 fix(01-06): align ensureOffscreen URL with crxjs emit path`
|
||||||
|
|
||||||
|
### `npm run build` output (excerpt)
|
||||||
|
|
||||||
|
```
|
||||||
|
> ai-call-extension@1.0.0 build
|
||||||
|
> tsc && vite build
|
||||||
|
|
||||||
|
vite v5.4.21 building for production...
|
||||||
|
transforming...
|
||||||
|
✓ 59 modules transformed.
|
||||||
|
rendering chunks...
|
||||||
|
computing gzip size...
|
||||||
|
dist/service-worker-loader.js 0.04 kB
|
||||||
|
dist/icons/icon16.png 0.08 kB
|
||||||
|
dist/icons/icon48.png 0.12 kB
|
||||||
|
dist/icons/icon128.png 0.31 kB
|
||||||
|
dist/assets/index.ts-loader-BkeIfRno.js 0.34 kB
|
||||||
|
dist/src/offscreen/index.html 0.39 kB │ gzip: 0.23 kB
|
||||||
|
dist/src/popup/index.html 0.76 kB │ gzip: 0.51 kB
|
||||||
|
dist/manifest.json 1.14 kB │ gzip: 0.55 kB
|
||||||
|
dist/assets/index-BXJP9H5s.css 1.08 kB │ gzip: 0.54 kB
|
||||||
|
dist/assets/modulepreload-polyfill-B5Qt9EMX.js 0.71 kB │ gzip: 0.40 kB
|
||||||
|
dist/assets/logger-D8-HRtHy.js 1.04 kB │ gzip: 0.32 kB
|
||||||
|
dist/assets/index.html-BR0hR1fK.js 2.27 kB │ gzip: 1.04 kB
|
||||||
|
dist/assets/offscreen-SqX0ET3Q.js 3.03 kB │ gzip: 1.42 kB
|
||||||
|
dist/assets/index.ts-BcLq5y3Q.js 73.79 kB │ gzip: 24.04 kB
|
||||||
|
dist/assets/index.ts-D-8Ku9Ua.js 104.47 kB │ gzip: 32.91 kB
|
||||||
|
✓ built in 1.09s
|
||||||
|
```
|
||||||
|
|
||||||
|
### `find dist -type f | sort` — full layout for Plan 07's manual smoke load
|
||||||
|
|
||||||
|
```
|
||||||
|
dist/assets/index-BXJP9H5s.css
|
||||||
|
dist/assets/index.html-BR0hR1fK.js
|
||||||
|
dist/assets/index.ts-BcLq5y3Q.js
|
||||||
|
dist/assets/index.ts-D-8Ku9Ua.js
|
||||||
|
dist/assets/index.ts-loader-BkeIfRno.js
|
||||||
|
dist/assets/logger-D8-HRtHy.js
|
||||||
|
dist/assets/modulepreload-polyfill-B5Qt9EMX.js
|
||||||
|
dist/assets/offscreen-SqX0ET3Q.js
|
||||||
|
dist/icons/icon128.png
|
||||||
|
dist/icons/icon16.png
|
||||||
|
dist/icons/icon48.png
|
||||||
|
dist/manifest.json
|
||||||
|
dist/service-worker-loader.js
|
||||||
|
dist/src/offscreen/index.html
|
||||||
|
dist/src/popup/index.html
|
||||||
|
```
|
||||||
|
|
||||||
|
### Outcome identification — RESEARCH.md Pitfall 5
|
||||||
|
|
||||||
|
The bundled offscreen HTML lands at `dist/src/offscreen/index.html` (crxjs **preserved** the `src/` prefix from the rollup input key). `dist/offscreen/index.html` does NOT exist. This is **Outcome A** per the plan's dichotomy.
|
||||||
|
|
||||||
|
**SW URL adjustment:** Plan 05 left `chrome.runtime.getURL('offscreen/index.html')` at `src/background/index.ts:45`. Under Outcome A this would have produced `ERR_FILE_NOT_FOUND` at `chrome.offscreen.createDocument` time and broken Plan 07's manual smoke load. The one-line edit:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
- const url = chrome.runtime.getURL('offscreen/index.html');
|
||||||
|
+ const url = chrome.runtime.getURL('src/offscreen/index.html');
|
||||||
|
```
|
||||||
|
|
||||||
|
The committed SW URL string and the actual `dist/` emit path now match — verified empirically, not inferred.
|
||||||
|
|
||||||
|
### `dist/manifest.json` permissions verification
|
||||||
|
|
||||||
|
```
|
||||||
|
$ node -e "const m=require('./dist/manifest.json'); const p=m.permissions; \
|
||||||
|
console.log('Has desktopCapture:', p.includes('desktopCapture')); \
|
||||||
|
console.log('Has tabCapture:', p.includes('tabCapture'));"
|
||||||
|
|
||||||
|
Has desktopCapture: true
|
||||||
|
Has tabCapture: false
|
||||||
|
```
|
||||||
|
|
||||||
|
The post-D-A6 manifest amendment propagated correctly through crxjs into the bundled `dist/manifest.json` — `desktopCapture` present, `tabCapture` absent, `alarms` absent (already removed by Plan 05's manifest cleanup).
|
||||||
|
|
||||||
|
### Acceptance gates (all PASS)
|
||||||
|
|
||||||
|
| Gate | Expected | Actual |
|
||||||
|
|------|----------|--------|
|
||||||
|
| `npm run build` exit code | 0 | 0 |
|
||||||
|
| `dist/manifest.json` exists | YES | YES |
|
||||||
|
| `dist/src/offscreen/index.html` OR `dist/offscreen/index.html` | one of two | dist/src/offscreen/index.html (Outcome A) |
|
||||||
|
| `dist/manifest.json` permissions contains `desktopCapture` | YES | YES |
|
||||||
|
| `dist/manifest.json` permissions contains `tabCapture` | NO | NO |
|
||||||
|
| SW `chrome.runtime.getURL(...)` string matches dist emit | YES | YES (src/offscreen/index.html) |
|
||||||
|
| `dist/assets/` JS file count | ≥ 1 | 7 |
|
||||||
|
| `npx tsc --noEmit` post-edit | exit 0 | PASS |
|
||||||
|
| `npx vitest run` post-edit | 9/9 PASS | 9/9 PASS |
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
### Rule 1 — Bug fix (auto-applied, paired with Task 2)
|
||||||
|
|
||||||
|
**1. [Rule 1 - Bug] SW URL `chrome.runtime.getURL('offscreen/index.html')` would have 404'd against the Outcome-A dist layout**
|
||||||
|
|
||||||
|
- **Found during:** Task 2 (the planned post-build path reconciliation — this is the exact scenario RESEARCH.md Pitfall 5 calls out).
|
||||||
|
- **Issue:** Plan 05's executor left the pre-amendment string `'offscreen/index.html'` at `src/background/index.ts:45`. Once Plan 06 wired `rollupOptions.input.offscreen = 'src/offscreen/index.html'` and crxjs preserved the `src/` prefix in the emit, the SW URL no longer pointed at a real file. `chrome.offscreen.createDocument` would have returned `ERR_FILE_NOT_FOUND`. Plan 05's executor explicitly flagged this as the Task-2 runtime verification of Plan 06 (citation: STATE.md decisions block).
|
||||||
|
- **Fix:** One-line edit — `'offscreen/index.html'` → `'src/offscreen/index.html'`.
|
||||||
|
- **Files modified:** `src/background/index.ts:45`.
|
||||||
|
- **Verification:** Post-edit `npm run build` still exits 0; the committed string is `chrome.runtime.getURL('src/offscreen/index.html')` and `dist/src/offscreen/index.html` exists.
|
||||||
|
- **Committed in:** `6aeeda4` (Task 2 commit).
|
||||||
|
|
||||||
|
This was foreseen by the plan body itself (it explicitly describes the A/B outcome dichotomy and prescribes the edit conditional on which outcome obtains). It is a deviation only against the literal "Task 2 may need no commit if no path adjustment was needed" branch — Outcome A required the adjustment, so Task 2 produced its own commit. Not a true deviation in spirit; logged here for traceability.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Total deviations:** 1 auto-fixed (Rule 1 — path binding).
|
||||||
|
**Impact on plan:** Zero scope creep. The plan body anticipated exactly this fix and put it inline as Task 2 step (4). The line edit was load-bearing for Plan 07's manual smoke load.
|
||||||
|
|
||||||
|
## Issues Encountered
|
||||||
|
|
||||||
|
None. Build was clean on first run. Tests stayed at 9/9 throughout. No tsc errors. No regressions in Plan 04's port-based test suite or Plan 02 / Plan 03's ring-buffer + codec-check suites.
|
||||||
|
|
||||||
|
## TDD Gate Compliance
|
||||||
|
|
||||||
|
This plan was `type: execute` (not `type: tdd`). No RED/GREEN/REFACTOR cycle required. The existing test suite served as a regression guard — `npx vitest run` returned 9/9 PASS both at the start of the plan and after each task commit.
|
||||||
|
|
||||||
|
## Authentication Gates
|
||||||
|
|
||||||
|
None. Pure build-pipeline refactor.
|
||||||
|
|
||||||
|
## Known Stubs
|
||||||
|
|
||||||
|
None. The replacement `vite.config.ts` is complete and functional — `npm run build` produces a loadable extension. No placeholder/TODO/coming-soon markers introduced.
|
||||||
|
|
||||||
|
## Threat Flags
|
||||||
|
|
||||||
|
None. Threat surface is REDUCED, not expanded:
|
||||||
|
- T-1-NEW-06-01 (string-injected code via inline plugin): MITIGATED — the entire inline plugin with its `this.emitFile({ source: \`<JS-as-string>\` })` calls is deleted. Grep gate `grep -c "this.emitFile" vite.config.ts` returns 0.
|
||||||
|
- T-1-NEW-06-02 (orphaned root-level offscreen): MITIGATED — `offscreen/` directory absent. The post-deletion `find offscreen/` reports "No such file or directory" / "absent".
|
||||||
|
|
||||||
|
## CLAUDE.md Compliance
|
||||||
|
|
||||||
|
- No `as any` casts introduced in any modified file (vite.config.ts has no casts; the SW edit is a string literal change).
|
||||||
|
- No `@ts-ignore` introduced.
|
||||||
|
- `vite.config.ts` follows the canonical RESEARCH.md Example B form (lifted verbatim from a cited authoritative source — crxjs documentation + discussion #919).
|
||||||
|
- No new constants needed to be moved; the replacement file is small enough that no extracted-constants refactor applies.
|
||||||
|
|
||||||
|
## Next Plan Readiness — Plan 07
|
||||||
|
|
||||||
|
Plan 07 (the ffprobe acceptance gate per D-12) can now:
|
||||||
|
1. Load `dist/` unpacked into Chrome ≥ 116 (no further build needed; `dist/manifest.json` is the loadable extension).
|
||||||
|
2. Trigger the recording from popup; the offscreen at `dist/src/offscreen/index.html` will be created by the SW's `chrome.offscreen.createDocument({ url: 'chrome-extension://<id>/src/offscreen/index.html', ... })` call.
|
||||||
|
3. Run the ffprobe acceptance gate against the exported `last_30sec.webm`.
|
||||||
|
|
||||||
|
The full `dist/` listing is captured above so Plan 07's smoke test knows the exact files to expect.
|
||||||
|
|
||||||
|
> Plan 07 loads `dist/` unpacked into Chrome ≥ 116 and runs the ffprobe acceptance gate (D-12).
|
||||||
|
|
||||||
|
## Self-Check
|
||||||
|
|
||||||
|
Verified after writing this summary:
|
||||||
|
- vite.config.ts file exists: FOUND.
|
||||||
|
- src/background/index.ts file exists: FOUND.
|
||||||
|
- offscreen/ directory absent: FOUND (the absence itself was checked: `find offscreen/ 2>&1 || echo absent` → absent).
|
||||||
|
- dist/manifest.json exists: FOUND.
|
||||||
|
- dist/src/offscreen/index.html exists: FOUND.
|
||||||
|
- Commit `23e69d0` exists in git log (Task 1).
|
||||||
|
- Commit `6aeeda4` exists in git log (Task 2).
|
||||||
|
- `npx tsc --noEmit` exits 0.
|
||||||
|
- `npx vitest run` reports 9/9 PASS across 4 test files.
|
||||||
|
- `wc -l vite.config.ts` returns 21 (≤ 30 plan ceiling).
|
||||||
|
- `grep -c "copy-offscreen\|chromeMediaSource\|this.emitFile" vite.config.ts` returns 0.
|
||||||
|
- SW URL string `chrome.runtime.getURL('src/offscreen/index.html')` matches Outcome-A emit path `dist/src/offscreen/index.html`.
|
||||||
|
|
||||||
|
## Self-Check: PASSED
|
||||||
Reference in New Issue
Block a user