# Star Chart After Search Rate Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Build a minimal Chrome MV3 extension that captures the two after-search-rate metrics on Xingtu creator detail pages and logs one structured final result per route. **Architecture:** The extension uses an isolated content script to manage route state, inject a page-context hook, receive `postMessage` results, and print deduplicated structured output. Shared pure utilities handle star ID parsing, route key generation, label normalization, result shaping, and JSON extraction so the network hook stays thin and testable. **Tech Stack:** TypeScript, Vitest, tsup, Chrome Extension Manifest V3 --- ## Implementation Notes - Current workspace is **not** a git repository, so worktree and commit steps are replaced with explicit verification notes. - Keep scope to the detail page experiment only. - Follow TDD strictly: test first, verify red, implement minimal code, verify green. ## Planned File Map - Create: `package.json` - Create: `tsconfig.json` - Create: `vitest.config.ts` - Create: `scripts/build.mjs` - Create: `src/manifest.json` - Create: `src/content/index.ts` - Create: `src/content/route-state.ts` - Create: `src/page/hook.ts` - Create: `src/page/network-interceptor.ts` - Create: `src/shared/extract-after-search-rates.ts` - Create: `src/shared/get-star-id.ts` - Create: `src/shared/message-types.ts` - Create: `src/shared/normalize-rate-label.ts` - Create: `src/shared/result-types.ts` - Create: `src/shared/route-key.ts` - Create: `tests/extract-after-search-rates.test.ts` - Create: `tests/get-star-id.test.ts` - Create: `tests/route-key.test.ts` - Create: `tests/content-bridge.test.ts` - Create: `tests/page-hook.test.ts` - Create: `README.md` ### Task 1: Bootstrap the Tooling and Build Layout **Files:** - Create: `package.json` - Create: `tsconfig.json` - Create: `vitest.config.ts` - Create: `scripts/build.mjs` - Create: `src/manifest.json` - [ ] **Step 1: Write the failing build-shape test** Create `tests/build-layout.test.ts` that asserts: - `src/manifest.json` exists and includes one content script match for `https://*.xingtu.cn/ad/creator/author-homepage/*` - build script copies manifest and emits `dist/manifest.json` - [ ] **Step 2: Run the test to verify it fails** Run: `npm test -- tests/build-layout.test.ts` Expected: FAIL because project files and scripts do not exist yet - [ ] **Step 3: Create the minimal tooling files** Implement: - `package.json` with `build`, `test`, and `test:run` - `tsconfig.json` - `vitest.config.ts` - `scripts/build.mjs` - `src/manifest.json` - [ ] **Step 4: Run the test to verify it passes** Run: `npm test -- tests/build-layout.test.ts` Expected: PASS - [ ] **Step 5: Verify build output** Run: `npm run build` Expected: `dist/manifest.json` exists and TypeScript entrypoints build without errors - [ ] **Step 6: Commit** Skip: repository is not initialized as git; record the verification output instead ### Task 2: Implement and Test Shared Extraction Utilities **Files:** - Create: `src/shared/extract-after-search-rates.ts` - Create: `src/shared/get-star-id.ts` - Create: `src/shared/normalize-rate-label.ts` - Create: `src/shared/result-types.ts` - Create: `src/shared/route-key.ts` - Create: `tests/extract-after-search-rates.test.ts` - Create: `tests/get-star-id.test.ts` - Create: `tests/route-key.test.ts` - [ ] **Step 1: Write the failing utility tests** Add tests covering: - parsing page star ID from matching and non-matching URLs - route key creation with incrementing navigation sequence - exact-key extraction - label/value extraction with synonymous labels - text fallback extraction in a bounded subtree - partial match stays `success: false` - unrelated payload returns `matched: false` - [ ] **Step 2: Run the tests to verify they fail** Run: `npm test -- tests/get-star-id.test.ts tests/route-key.test.ts tests/extract-after-search-rates.test.ts` Expected: FAIL because utility modules do not exist yet - [ ] **Step 3: Implement the minimal utilities** Implement: - URL parsing for `pageStarId` - `routeKey` helper - label normalization helper - extraction function with `exact-key`, `label-value`, `text-fallback`, and `none` - shared types for results - [ ] **Step 4: Run the tests to verify they pass** Run: `npm test -- tests/get-star-id.test.ts tests/route-key.test.ts tests/extract-after-search-rates.test.ts` Expected: PASS - [ ] **Step 5: Refactor only if needed** Keep utility files focused and remove duplication without changing behavior - [ ] **Step 6: Re-run the utility tests** Run: `npm test -- tests/get-star-id.test.ts tests/route-key.test.ts tests/extract-after-search-rates.test.ts` Expected: PASS - [ ] **Step 7: Commit** Skip: repository is not initialized as git; record the verification output instead ### Task 3: Implement and Test the Content Bridge **Files:** - Create: `src/content/index.ts` - Create: `src/content/route-state.ts` - Create: `src/shared/message-types.ts` - Modify: `src/shared/result-types.ts` - Create: `tests/content-bridge.test.ts` - [ ] **Step 1: Write the failing content bridge tests** Add tests covering: - route state initialization from the current URL - navigation sequence increment on route changes - stale route messages are ignored - duplicate final results are not logged twice - a later success result can replace an earlier failure result - [ ] **Step 2: Run the test to verify it fails** Run: `npm test -- tests/content-bridge.test.ts` Expected: FAIL because content bridge files do not exist yet - [ ] **Step 3: Implement the minimal content bridge** Implement: - route state tracking - page-hook injection via `