commit 714745bb36c8784fae8bb34b2cdf4da53c382cbd Author: wangshaoqing Date: Wed Apr 15 15:17:42 2026 +0800 chore: initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1d03d10 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +node_modules/ +dist/ +.DS_Store +.vscode/ +*.log diff --git a/README.md b/README.md new file mode 100644 index 0000000..473202f --- /dev/null +++ b/README.md @@ -0,0 +1,33 @@ +# Star Chart Search Enhancer + +一个最小化的 Chrome MV3 实验插件,用来在巨量星图的达人详情页拦截页面自己的网络响应,并尝试提取两个“看后搜率”指标。 + +## 开发命令 + +```bash +npm install +npm test +npm run build +``` + +## 加载插件 + +1. 先执行 `npm run build` +2. 打开 `chrome://extensions` +3. 打开“开发者模式” +4. 选择“加载已解压的扩展程序” +5. 选择本项目的 `dist/` 目录 + +## 手工验证 + +1. 打开巨量星图的达人详情页 +2. 刷新页面一次,确保内容脚本和页面 hook 都能尽早注入 +3. 打开该页面的 DevTools Console +4. 观察是否出现带有 `[star-chart-search-enhancer]` 前缀的日志 +5. 找到 `result` 日志,核对其中两个看后搜率是否与达人详情页右侧展示一致 + +## 当前范围 + +- 只支持巨量星图达人详情页 +- 只输出到控制台,不改页面 UI +- 成功时输出结构化结果,超时也会输出一个明确失败结果 diff --git a/docs/superpowers/plans/2026-04-15-star-chart-after-search-rate-implementation.md b/docs/superpowers/plans/2026-04-15-star-chart-after-search-rate-implementation.md new file mode 100644 index 0000000..bb3deb3 --- /dev/null +++ b/docs/superpowers/plans/2026-04-15-star-chart-after-search-rate-implementation.md @@ -0,0 +1,278 @@ +# 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 `