4.0 KiB
4.0 KiB
PRD: 知识库索引面板 (Knowledge Index Panel)
Problem Statement
用户每次用 /knowledge-absorber 学习后,会在项目根目录生成 knowledge_YYYYMMDD_Title/ 文件夹。目前有 2 个知识条目,预计每月增长 5-10 个。所有条目散落在根目录,没有跨条目的导航或搜索能力。想找之前学过的内容只能手动翻目录,搜索成本随条目数线性上升。
Solution
在项目根目录生成一个 纯静态的 knowledge-index.html,浏览器直接打开即可使用。它能自动发现所有 knowledge 条目,提供标签关联和全文搜索。不需要任何服务器、数据库或外部依赖。
User Stories
- As a 学习者, I want to see all my knowledge entries on one page with dates, so that I can quickly find what I studied and when
- As a 学习者, I want to search across all knowledge entries by keyword, so that I can find "that thing about Redis" in 2 seconds instead of manually opening 10 folders
- As a 学习者, I want to click a tag like "Claude Code" and see all related entries, so that I can review interconnected topics
- As a 学习者, I want the index to auto-discover new knowledge entries, so that I don't need to manually update anything after running
/knowledge-absorber - As a 学习者, I want the page to work offline by just double-clicking the HTML file, so that I can use it without internet or any setup
- As a 学习者, I want to see which entries are related to each other via shared tags, so that I can discover connections between topics I've studied
- As a 学习者, I want the search to highlight matching text, so that I can see at a glance why an entry matched my query
- As a 学习者, I want to see a count of entries per tag, so that I know which topics I've studied most
Implementation Decisions
- Single HTML file: All CSS and JS inlined in
knowledge-index.html. No external files or CDN dependencies - Manifest-based discovery: A JavaScript array inside the HTML lists all known knowledge directory names. Browser security sandbox prevents dynamic directory listing via
fetch() - YAML frontmatter parsing: Regex-based extraction from
.mdfiles. Simple key:value parsing only — no full YAML spec support - Client-side search: All
.mdcontent loaded into memory at page init. Real-time filtering withString.includes(), case-insensitive.<mark>tags for highlighting - Tag system: In-memory
Map<tag, entry[]>built at load time. Click to filter, click again to deselect - Related Content: Computed from shared tags, displayed per-entry
- No pagination: Designed for < 50 entries. Full list rendered at once
- UTF-8 encoding: All files assumed UTF-8.
fetch()handles encoding detection
Testing Decisions
- What makes a good test: Test external behavior — "user types keyword → correct entries appear" — not internal state
- Test with real data: Use existing 2 knowledge entries (
knowledge_20260417_Waza,knowledge_20260518_mattpocock_skills) as test fixtures - Edge cases to verify:
- Missing directory (manifest lists a name that doesn't exist) → skip gracefully
- Malformed YAML → display directory name as fallback
- Empty tags array → no tag badges rendered
- No search results → show "没有找到相关条目" message
- Browser CORS when opened via
file://protocol → document the workaround
Out of Scope
- Google Drive / cloud sync
- Editing knowledge entries
- Full YAML 1.2 spec compliance
- Pagination or virtual scrolling
- Fuse.js or other fuzzy search libraries (keep it zero-dependency)
- Dark mode toggle (can add later, not in v1)
Further Notes
- The manifest maintenance problem (adding new entries) can be solved in a future iteration by modifying the
/knowledge-absorberskill to auto-append to the manifest array - The
file://protocol CORS limitation on Chrome means users may need to serve viapython -m http.serveror similar for full functionality - Tag counts provide a natural "learning heatmap" — most-studied topics bubble to the top