Commit Graph

45 Commits

Author SHA1 Message Date
starmen1265 d1497ca550 feat(05-02): integrate ArchiveProcessor into Pipeline
- Add ArchiveInput creation in Pipeline.run()
- Import ArchiveInput in pipeline.py
- Add archive_file and skipped to output field recording
- Add ArchiveProcessor to CLI processors list
- Update PipelineConfig steps to include archive
2026-03-16 23:19:23 +08:00
starmen1265 63dd88279c feat(05-02): implement ArchiveProcessor
- Create ArchiveProcessor with STEP_NAME = archive
- Implement process() method with idempotent execution
- Add _find_existing_archive() for duplicate detection
- Add _ask_overwrite() using rich.prompt with fallback
- Only copy md files (not json) to archive directory
- Export ArchiveProcessor in __init__.py
2026-03-16 23:18:24 +08:00
starmen1265 9c74f51b43 feat(05-02): add ArchiveInput and ArchiveOutput schemas
- Add ArchiveInput with content_dir, analysis_file, content_type fields
- Add ArchiveOutput with archive_file, skipped, platform fields
- Update PipelineConfig default steps to include archive step
2026-03-16 23:17:29 +08:00
starmen1265 10f4dfa22e feat(05-01): update Pipeline to use configurable intermediate directory
- Change default output_dir from cwd to settings.intermediate_path
- Reorder settings initialization before output_dir assignment
- Maintain output_dir parameter for testing/custom override

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 23:13:04 +08:00
starmen1265 c5b2c66bc7 feat(05-01): add KB_INTERMEDIATE_PATH config to KBSettings
- Add intermediate_path field with default ~/work/intermediate/analysis/
- Follow pydantic-settings naming convention for env var override
- Users can customize via KB_INTERMEDIATE_PATH environment variable

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 23:12:36 +08:00
starmen1265 f358c52578 fix(zhihu): 修复文章归档格式问题
PR Test / lint (pull_request) Successful in 1s
1. author 字段清理零宽度空格和换行符,修复 Obsidian 解析
2. 扩展 content_type 条件,answer/zhuanlan 使用文章模板
3. 读取 content.md 时去除 YAML frontmatter
4. generate_frontmatter 正确推断 platform 为 zhihu

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 18:19:42 +08:00
starmen1265 84e9ada055 restore: 恢复误删的技能目录并修复导入方式
PR Test / lint (pull_request) Successful in 1s
- 恢复 kb-zhihu-metadata, kb-bilibili-metadata, kb-deep-analyzer
- 修改 zhihu.py 和 analyze.py 使用 sys.path 方式导入
- 删除符号链接 kb_zhihu_metadata

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 17:27:48 +08:00
starmen1265 c8cdcb4631 fix(bilibili): correct metadata and filename in archive
PR Test / lint (pull_request) Successful in 1s
- Add _normalize_metadata() to flatten nested metadata structure
- Fix generate_frontmatter() to use correct metadata fields
- Change _sanitize_filename() to return standardized "bilibili_{bvid}" format

Fixes: analysis.md frontmatter showing "未命名"/0/"未知" instead of actual values
Fixes: audio filename using video title instead of platform_bvid format

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 13:48:28 +08:00
starmen1265 dd9d4cdf90 fix(analyze): extract text from Whisper JSON format
- Handle Whisper transcription format (array of segments with text)
- Extract full text from transcription array before passing to DeepAnalyzer
- Fix offsets parsing to support both dict and list formats

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 00:20:25 +08:00
starmen1265 0b215dabe7 feat(download): add video download capability for videos without official subtitles
- Add download_video() to BilibiliAdapter using yt-dlp
- Add bilibili_cookie config to Settings
- Update DownloadProcessor to call video download for bilibili videos
- Add idempotency check to ASRProcessor for existing subtitle files
- Fix indentation error in asr.py

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 00:09:16 +08:00
starmen1265 60b0eaec93 feat(download): add video download capability for videos without official subtitles
- When content_type is video and no official subtitle available:
  - Download video using yt-dlp
  - Extract audio for Whisper fallback
- Update content_file with actual video path

This enables the pipeline to handle videos that don't have
official Bilibili subtitles.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 00:04:56 +08:00
starmen1265 729f4650d5 fix(pipeline): populate results for skipped steps and support old file naming
- When a step is skipped (already completed), ask user if they want to re-run
- If skipping, scan content_dir for existing files and populate results
- Support both new naming (platform_id_subtitle.json) and old naming (platform_id.json)
- This fixes the issue where analyze step couldn't find subtitle files
  when ASR step was skipped

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 23:49:34 +08:00
starmen1265 f24841996a fix(analyze): include original text for zhihu answer/zhuanlan types
知乎回答(answer)和专栏(zhuanlan)的原文没有被追加到分析报告中。
代码只在 content_type == "article" 时设置和追加原文。

修复:
- deep_analyzer.py: 扩展条件支持 answer, zhuanlan 类型
- analyze.py: 同步扩展原文追加条件

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 23:41:42 +08:00
starmen1265 8ad64a4d1b fix(asr): use content_dir for subtitle output instead of video_path
PR Test / lint (pull_request) Successful in 2s
- Add content_dir field to ASRInput schema
- Pass content_dir from pipeline when creating ASRInput
- Modify _try_official_subtitle to use content_dir for output
- Modify _run_whisper_basic to use content_dir for output
- Add validation for empty video_path in Whisper fallback

Root cause: DownloadProcessor sets content_file="" for video types,
causing Path("").parent to resolve to current directory instead of
content directory. Subtitle files were written to wrong location.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 22:59:24 +08:00
starmen1265 5d06056b43 fix(download): handle formatted duration strings in metadata
PR Test / lint (pull_request) Successful in 1s
Parse duration strings like "12:34" or "01:23:45" into seconds.
Previously only integer duration values were handled.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 18:17:03 +08:00
starmen1265 368e946cd1 fix(bilibili): avoid nested asyncio.run() in async context
BilibiliAdapter._fetch_metadata_with_retry() now calls the underlying
async methods directly instead of sync wrappers that use asyncio.run().
This prevents "asyncio.run() cannot be called from a running event loop"
error when the adapter is called from within an already-running event loop.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 18:17:03 +08:00
starmen1265 ec2d12a05b feat(04-05): implement Pipeline.run() method
- Add async run() method to Pipeline class
- Execute processors sequentially with state persistence
- Handle step-specific input types (Parse, Download, ASR, Analyze)
- Support skip_completed for resumable workflows
- Return PipelineOutput with results and content_dir

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 23:46:54 +08:00
starmen1265 0dfb51e9aa feat(04-04): create Pipeline class with processor initialization
- Pipeline class initializes with processors list
- Validates processor STEP_NAME matches config.steps
- _parse_url method parses URLs using LinkParser
- _get_content_dir creates content directory from parsed URL

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 23:38:17 +08:00
starmen1265 789d1f43e0 feat(04-04): add PipelineInput/Output/Config schemas
- PipelineInput: url (required), output_dir, skip_completed
- PipelineOutput: success, error_message, results, content_dir
- PipelineConfig: steps, output_dir, skip_completed, max_retries

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 23:37:35 +08:00
starmen1265 029718e7e0 feat(04-03): export AnalyzeProcessor from processors module
- Add AnalyzeProcessor to __init__.py exports
- Update module docstring

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 23:32:53 +08:00
starmen1265 0b7d8707bf feat(04-03): implement AnalyzeProcessor with DeepAnalyzer integration
- AnalyzeProcessor wraps existing DeepAnalyzer for pipeline integration
- Loads metadata and content from JSON files
- Generates analysis reports as Markdown with frontmatter
- Records state on success and failure
- Supports both video and article content types

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 23:32:31 +08:00
starmen1265 51644997e4 feat(04-03): add AnalyzeInput and AnalyzeOutput schemas
- AnalyzeInput extends StepInput with metadata_file, content_file, content_type, output_file
- AnalyzeOutput extends StepOutput with analysis_file, summary, main_topics, key_insights, tags, stats
- Supports both video and article content types

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 23:28:30 +08:00
starmen1265 ec268f7d17 feat(04-02): add content downloading and module export for DownloadProcessor
TDD GREEN phase:
- DownloadProcessor downloads article/answer/zhuanlan content
- Video content is skipped (handled by ASR in Phase 3)
- Content files saved with correct naming convention
- DownloadProcessor exported from kb_pipeline.processors
- All 17 tests pass

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 23:24:00 +08:00
starmen1265 fc6fba76b2 feat(04-02): implement DownloadProcessor with metadata fetching
TDD GREEN phase:
- DownloadProcessor inherits from BaseProcessor
- Fetches metadata from Bilibili and Zhihu adapters
- Saves metadata to content_dir as JSON
- Records state on success/failure
- Skips step if already completed (idempotency)
- All metadata tests pass

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 23:22:48 +08:00
starmen1265 1e012366e1 feat(04-02): add DownloadInput and DownloadOutput schemas
TDD GREEN phase:
- DownloadInput extends StepInput with content_dir and content_type
- DownloadOutput extends StepOutput with metadata_file, content_file, title, author, duration
- Supports video, article, answer, zhuanlan content types
- All schema validation tests pass

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 23:18:29 +08:00
starmen1265 06d36fc440 feat(04-01): implement ParseProcessor and update module exports
- ParseProcessor wraps LinkParser for URL parsing
- Returns ParseOutput with platform, content_type, content_id
- Records state when state_manager is provided
- Handles unknown URLs with success=False
- Export BaseProcessor, ParseProcessor, ASRProcessor from __init__.py

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 23:14:32 +08:00
starmen1265 efddef98d3 feat(04-01): add ParseInput and ParseOutput schemas
- ParseInput extends StepInput with url field
- ParseOutput extends StepOutput with platform, content_type, content_id, resolved_url, original_url
- Tests for schema validation and inheritance

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 23:11:44 +08:00
starmen1265 3ad2576aed test(04-01): add failing tests for BaseProcessor abstract class
- Test BaseProcessor cannot be instantiated directly
- Test subclass must implement process() method
- Test state_manager attribute is provided
- Test STEP_NAME class attribute requirement

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 23:10:52 +08:00
starmen1265 406c6cbbc6 feat(03-01): implement ASRProcessor with official subtitle download
- Create processors module with ASRProcessor class
- Implement _try_official_subtitle for B站字幕下载
- Support process() method with subtitle-first strategy
- Add helper functions for whisper.cpp integration

- All 5 processor tests passing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 19:22:23 +08:00
starmen1265 b2330c32c8 test(03-01): add ASRInput and ASROutput schemas
- Add ASRInput schema with video_path and content_type fields
- Add ASROutput schema with tool/has_subtitle/output_files/segments/text/duration_seconds/speakers
- Create test_processors directory with conftest fixtures
- Add comprehensive schema tests (8 test cases)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 19:20:17 +08:00
starmen1265 c4beb3ef3c feat(02-03): implement ZhihuAdapter for answer and zhuanlan content
- Implement ZhihuAdapter class inheriting PlatformAdapter
- Support answer URL content extraction
- Support zhuanlan (article) URL content extraction
- Add cookie-based authentication from KBSettings
- Detect login page redirects (expired cookies)
- Return AuthError for missing/expired cookies
- Format content with YAML frontmatter
- Update package exports to include ZhihuAdapter

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 18:24:55 +08:00
starmen1265 a6f4d34625 test(02-03): add failing tests for ZhihuAdapter
- Test answer content extraction
- Test zhuanlan (article) content extraction
- Test cookie-based authentication
- Test login page detection
- Test AuthError handling for missing/expired cookies

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 18:24:37 +08:00
starmen1265 b74f6a0c73 feat(02-02): implement BilibiliAdapter for video and article metadata
- Implement PlatformAdapter interface for Bilibili platform
- Add video metadata extraction (BV号)
- Add article metadata extraction (CV号)
- Add automatic retry on network errors (3 attempts)
- Add state recording for failed steps
- Add content type identification from URL
- Add output filename generation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 18:23:11 +08:00
starmen1265 3f42bfaf0d test(02-02): add failing tests for PlatformAdapter base class
- Add test for abstract class instantiation prevention
- Add test for incomplete implementation detection
- Add test for complete implementation instantiation
- Add test for async method signatures
- Add shared fixtures for platform tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 18:19:24 +08:00
starmen1265 b8339c636a feat(02-01): export LinkParser and IdempotencyChecker from package root
- Add LinkParser and ParsedLink to __init__.py exports
- Add IdempotencyChecker to __init__.py exports
- Update __all__ list with new public APIs
- All 23 tests passing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 18:14:06 +08:00
starmen1265 bd29425d28 feat(02-01): add IdempotencyChecker for file existence checking
- Create IdempotencyChecker class with check_exists method
- Check for metadata JSON and content Markdown files
- Return tuple of (all_exist, existing_files)
- Follow naming convention: {platform}_{content_id}_{type}.{ext}
- Add get_expected_files helper method
- Add 8 unit tests covering all scenarios

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 18:13:35 +08:00
starmen1265 dd94f068e7 feat(02-01): add LinkParser and ParsedLink for unified URL parsing
- Create ParsedLink dataclass with platform, content_type, content_id fields
- Implement LinkParser class with regex-based URL parsing
- Support Bilibili video/article URLs (with/without www)
- Support Zhihu answer/zhuanlan URLs
- Support b23.tv short link resolution with requests.head
- Return None for unrecognized URLs (no exceptions)
- Add 15 unit tests covering all supported URL types

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 18:12:16 +08:00
starmen1265 770225439b feat(01-03): export all public APIs from package root
- Export error types (KBError, NetworkError, ValidationError, SystemError, AuthError, ErrorType)
- Export config (KBSettings, get_settings)
- Export retry (retry_on_network_error)
- Clean import interface for users

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 17:20:38 +08:00
starmen1265 74adaf3a79 feat(01-03): implement retry mechanism with tenacity
- retry_on_network_error decorator for automatic retry
- Max 3 attempts with exponential backoff (2s, 4s, max 10s)
- Only retries on NetworkError
- Logs retry attempts via before_sleep_log
- Reraises original exception after max attempts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 17:19:42 +08:00
starmen1265 0dbb0c4cb6 refactor(01-01): export WorkflowStateManager from kb_pipeline
Add WorkflowStateManager to package exports for easier imports.
Users can now use: from kb_pipeline import WorkflowStateManager

All 20 tests pass with 90% coverage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 17:17:24 +08:00
starmen1265 44b5d18113 feat(01-03): implement configuration management with pydantic-settings
- KBSettings class loading from ~/.kb_env file
- Required fields: base_path, archive_path
- Optional fields: git_root, git_user, git_email
- Secret fields: hf_token, zhihu_cookie (SecretStr)
- get_settings() singleton with lru_cache
- env_prefix "KB_" for environment variables
- Tests adjusted for proper env isolation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 17:17:10 +08:00
starmen1265 624cd76538 feat(01-01): implement WorkflowStateManager with atomic write
GREEN phase: Implement state management with:
- Atomic write pattern (temp file + os.replace)
- Backup rotation (workflow_state.json -> .bak)
- Backup fallback on corruption
- get_or_create idempotent creation

Fix test to properly create backup before corruption test.

All 20 tests pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 17:16:30 +08:00
starmen1265 d8cfee3bf1 feat(01-03): implement structured error handling
- ErrorType enum with NETWORK, VALIDATION, SYSTEM, AUTH
- KBError base class with to_dict method for serialization
- NetworkError with status_code and auto-generated suggestion
- ValidationError with validation_errors list
- SystemError with system_message
- AuthError with auth_type

All errors include step_name, input_summary, error_type, message,
and suggestion for rich debugging context.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 17:14:51 +08:00
starmen1265 2caddd792e feat(01-02): implement core pipeline schemas
- Add StepStatus enum (PENDING, RUNNING, COMPLETED, FAILED, SKIPPED)
- Add StepInput with content_id and platform validation
- Add StepOutput with success and error_message fields
- Add StepResult for step execution results
- Add StepRecord for step execution records
- Add WorkflowState with step management methods
- Add StepDefinition for step configuration
- Add pytest.ini for PYTHONPATH configuration
- TDD GREEN phase: all 28 tests pass

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 17:07:09 +08:00
starmen1265 85413bc1c6 test(01-02): add failing tests for core pipeline schemas
- Create kb_pipeline package structure
- Add test fixtures in conftest.py
- Add 28 test cases for StepInput, StepOutput, StepStatus, StepRecord, WorkflowState
- Add JSON serialization/deserialization tests
- TDD RED phase: tests fail because schemas.py not yet implemented

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 17:05:37 +08:00