diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 6b083645..37ff0fc0 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -1,98 +1,34 @@ # Requirements: PaperForge Lite -> **Defined:** 2026-04-25 -> **Core Value:** A new user can install PaperForge, configure their own vault paths and PaddleOCR credentials, then run the full literature pipeline with copy-pasteable commands that diagnose failures clearly. +> **Defined:** 2026-04-29 +> **Core Value:** A new user downloads one Obsidian plugin and completes full PaperForge installation without touching a terminal. --- -## v1.3 Requirements (Validated) +## Previous Milestones (Validated) -All 19 v1.3 requirements shipped and validated. See `.planning/milestones/v1.3.md` and `MILESTONES.md` for completion details. +All v1.0–v1.4 requirements shipped and validated. See `MILESTONES.md` for completion details. --- -## v1.4 Requirements +## v1.5 Requirements -### Code Health (CH) +### Settings Tab (SETUP) -**Goal:** Eliminate all code duplication and dead code across the 7 worker modules. +**Goal:** Obsidian plugin settings tab exposes all setup_wizard.py configuration fields with persistence. -- [ ] **CH-01**: Create `paperforge/worker/_utils.py` as a pure leaf module (zero imports from sibling workers) containing all duplicated utility functions: `read_json`, `write_json`, `read_jsonl`, `write_jsonl`, `yaml_quote`, `yaml_block`, `yaml_list`, `slugify_filename`, `_extract_year`, `load_journal_db`, `lookup_impact_factor`, `_STANDARD_VIEW_NAMES`, and the `_JOURNAL_DB` cache. -- [ ] **CH-02**: Update all 7 worker modules (`sync.py`, `ocr.py`, `deep_reading.py`, `repair.py`, `status.py`, `update.py`, `base_views.py`) to import shared functions from `paperforge.worker._utils` instead of defining local copies. Approximately 1,610 lines of duplication removed. -- [x] **CH-03**: Merge the two duplicate deep-reading queue scanning implementations — consolidate `worker/deep_reading.py::run_deep_reading()` (scanner logic) and `skills/ld_deep.py::scan_deep_reading_queue()` into a single `scan_library_records()` function in `_utils.py`. Both original call sites import the shared function with no behavioral change. -- [ ] **CH-04**: Remove dead code: (a) `UPDATE_*` constants from `status.py` lines 620-625 (duplicated in `update.py`), (b) unused imports from each worker module (`csv`, `hashlib`, `shutil`, `subprocess`, `zipfile`, `ElementTree`, `fitz`, `PIL` where not used), (c) unnecessary delegation wrappers (`load_vault_config` / `pipeline_paths`) that merely call `paperforge.config` equivalents — direct `config.*` imports replace these. -- [ ] **CH-05**: All 205 existing tests continue to pass after shared utility extraction. No regression in CLI dispatch, OCR state machine, path normalization, repair, or base view generation. +- [x] **SETUP-01**: Settings tab renders all setup_wizard.py fields — vault path, system_dir, resources_dir, literature_dir, control_dir, agent_config_dir, PaddleOCR API token, Zotero data directory. Each field has a clear Chinese label and tooltip. +- [x] **SETUP-02**: Settings persist across Obsidian restarts via `loadData()`/`saveData()` with `DEFAULT_SETTINGS` merge pattern. Fresh installs (null data) get pre-filled defaults without crashing. +- [ ] **SETUP-03**: Field changes update in-memory immediately; disk writes are debounced at 500ms to prevent `data.json` corruption from every-keystroke saves. Settings tab state survives tab switching without data loss. -### Observability (OBS) +### Install & UX (INST) -**Goal:** Replace ad-hoc `print()` calls with a structured, configurable logging system. +**Goal:** One-click install button with polished, human-readable feedback. -- [x] **OBS-01**: Create `paperforge/logging_config.py` that configures a `logging.Logger` hierarchy using stdlib `logging`. Log level controllable via `PAPERFORGE_LOG_LEVEL` environment variable (accepts `DEBUG`/`INFO`/`WARNING`/`ERROR` string names). All workers and CLI commands use `logger = logging.getLogger(__name__)`. -- [x] **OBS-02**: Implement dual-output strategy: `print()` preserved for user-facing formatted output on stdout; `logging` used for diagnostic/trace/error output to stderr. Existing piped commands and Agent scripts that parse stdout continue to work unmodified. -- [x] **OBS-03**: Add `--verbose`/`-v` flag to `paperforge sync`, `paperforge ocr`, and `paperforge deep-reading` that enables `DEBUG` log level. All existing commands accept the flag. -- [ ] **OBS-04**: Add `tqdm`-based progress bars to OCR upload (per-PDF) and batch polling loops. Progress output goes to stderr. Auto-detects non-TTY mode (CI, pipe) — silently falls back to no progress output when stdout is not an interactive terminal. A `--no-progress` flag suppresses output explicitly. -- [ ] **OBS-05**: Make OCR error messages actionable: on failure/timeout/blocked, the error includes the specific HTTP status code or exception type, the library-record name for context, and a suggestion (e.g., "Run `paperforge ocr --diagnose` to test API connectivity" or "Run `paperforge repair --fix` to recover state"). Error pattern follows `ocr_diagnostics.classify_error()` format. - -### Reliability (REL) - -**Goal:** Make the OCR pipeline resilient to transient network failures. - -- [ ] **REL-01**: Add `tenacity`-based retry decorator to PaddleOCR API calls (upload and poll functions) with exponential backoff (1s → 2s → 4s → 8s → max 30s), jitter, and selective exception retry (`requests.ConnectionError`, `requests.Timeout`, `HTTPError` with status 429/503). Configurable via `PAPERFORGE_RETRY_MAX` and `PAPERFORGE_RETRY_BACKOFF` environment variables. -- [ ] **REL-02**: Extend OCR `meta.json` schema with `retry_count` (int, default 0), `last_error` (str | null), `last_attempt_at` (ISO-8601 str | null). These fields are written atomically after each attempt and read during polling to inform retry decisions. -- [ ] **REL-03**: Prevent zombie OCR state: on worker restart, all `processing` jobs older than configurable threshold (default: 30 minutes) are reset to `pending` with `retry_count` incremented. Blocked jobs (`blocked` terminal state) are never retried unless user manually resets `do_ocr`. -- [ ] **REL-04**: The `paperforge ocr` command gracefully handles partial failures: a single upload failure does not abort the entire batch. Failed items are logged, their state updated, and processing continues with remaining items. - -### Developer Experience (DX) - -**Goal:** Establish standard open-source project infrastructure for maintainers and contributors. - -- [ ] **DX-01**: Create `.pre-commit-config.yaml` with hooks: `ruff` (lint + format), `check-yaml`, `check-toml`, `end-of-file-fixer`, `trailing-whitespace`, and a custom `consistency-audit` hook that runs `scripts/consistency_audit.py` and blocks commits if duplicate utility functions are detected in any worker module. -- [ ] **DX-02**: Add `[tool.ruff]` section to `pyproject.toml` targeting Python 3.10+, enabling rules `E`, `F`, `I`, `UP`, `B`, `SIM`. Run `ruff check --fix` and `ruff format` across the entire codebase as part of the pre-commit activation phase. -- [x] **DX-03**: Create `CHANGELOG.md` following the Keep a Changelog format with sections for each version (v1.0 through v1.4). Include the changelog URL in `paperforge.json` update metadata. -- [x] **DX-04**: Create `CONTRIBUTING.md` documenting: development setup (`pip install -e ".[test]"`), pre-commit hook installation, test execution workflow, architecture overview, and code conventions (no new print() calls, import shared utilities from `_utils.py`, REQ-ID linking in commit messages). - -### Testing (TEST) - -**Goal:** Close testing gaps identified in the codebase audit. - -- [ ] **TEST-01**: Add E2E integration tests in `tests/test_e2e_pipeline.py` covering the full Zotero JSON → selection-sync → index-refresh → OCR queue → formal notes pipeline using the sandbox fixture vault. Tests validate frontmatter completeness, wikilink correctness, and state transitions. -- [ ] **TEST-02**: Add setup wizard tests in `tests/test_setup_wizard.py` validating: agent platform detection, vault path resolution, environment checks, and configuration file generation. Tests use the Textual testing harness if available or validate standalone functions independently. -- [ ] **TEST-03**: All existing 205 tests continue to pass with zero failures. No test regression from shared utility extraction, logging changes, or dead code removal. Minimum bar: 205+ tests passing, 0 failures, 0 errors. -- [ ] **TEST-04**: Add dedicated unit tests for `paperforge/worker/_utils.py` functions: `test_utils_json.py` (read/write JSON + JSONL), `test_utils_yaml.py` (yaml_quote/yaml_block/yaml_list), `test_utils_slugify.py` (slugify_filename, _extract_year), `test_utils_journal.py` (load_journal_db, lookup_impact_factor). - -### User Experience (UX) - -**Goal:** Smooth user-facing friction points identified in the codebase audit. - -- [x] **UX-01**: Add workflow streamlining options to `paperforge.json`: `auto_analyze_after_ocr` (bool, default `false`) — when enabled, after OCR completes for a paper, the library-record's `analyze` flag is automatically set to `true`. This is opt-in to preserve the two-layer Worker/Agent separation and user agency. -- [x] **UX-02**: Fix README.md rendering artifact: remove the orphaned legacy code snippet lines (`python --vault . ocr`, `python --vault . status`) at lines 102-104 that appear outside any code fence. Audit all user-facing docs (AGENTS.md, docs/*.md, command/*.md) for similar rendering issues. -- [x] **UX-03**: Generate a chart-reading guide cross-reference index (`chart-reading/INDEX.md`) that maps the 19 chart types to their reading guides, ordered by commonness in biomedical literature. The agent prompt (`prompt_deep_subagent.md`) references this index so AI agents can discover and cite relevant guides during Pass 2 figure-by-figure analysis. -- [x] **UX-04**: Audit the command naming boundary: ensure all user-facing documentation consistently maps `/pf-*` Agent commands to `paperforge *` CLI commands. Add a quick-reference table showing "What to type where" in AGENTS.md section 1. - -### Documentation (DOCS) - -**Goal:** Document the v1.4 changes for existing users and future maintainers. - -- [x] **DOCS-01**: Create `docs/MIGRATION-v1.4.md` following the established v1.2 migration document pattern. Document behavioral changes (dual-output logging, retry behavior, opt-in workflow streamlining), environment variable additions (`PAPERFORGE_LOG_LEVEL`, `PAPERFORGE_RETRY_MAX`, `PAPERFORGE_RETRY_BACKOFF`), and new developer workflow requirements (pre-commit hooks, ruff). -- [x] **DOCS-02**: Update `AGENTS.md` to reflect: new `--verbose` flag on CLI commands, new `paperforge.json` workflow options, new environment variables page, and the chart-reading INDEX.md cross-reference. -- [x] **DOCS-03**: Add ADR-012 (Shared Utilities Extraction) and ADR-013 (Dual-Output Logging Strategy) to `docs/ARCHITECTURE.md`, documenting the `_utils.py` leaf-module constraint and the print/logging boundary decision. -- [x] **DOCS-04**: Update `ROADMAP.md` to reflect v1.4 phase structure and mark all requirements as mapped after roadmap creation. - ---- - -## v1.5 Requirements (Deferred) - -Deferred from v1.4 scope to keep the milestone focused and manageable. - -### Workflow - -- **WF-01**: One-click `paperforge process` command — triggers sync + OCR + auto-analyze in a single command. Deferred: requires research on optimal default behavior vs opt-out model. -- **WF-02**: Obsidian Base bulk-action integration — inline "Run OCR" / "Start Deep Reading" buttons in Base views. Deferred: requires Obsidian plugin architecture research. - -### Testing - -- **TEST-V2-01**: Performance benchmarks for OCR processing (large PDF timing). Deferred: need baseline measurements first. -- **TEST-V2-02**: Cross-platform CI (Windows + macOS + Linux) via GitHub Actions. Deferred: pre-commit hooks are the priority for v1.4. +- [x] **INST-01**: "Install" button triggers full setup pipeline — writes `paperforge.json`, creates directory structure, runs environment check, generates agent configs. Button disables during execution to prevent double-clicks. +- [x] **INST-02**: All feedback is polished Chinese text via Obsidian notices — friendly step-by-step progress ("正在创建目录... ✓", "正在写入配置文件... ✓"), clear success/failure messages. Raw Python tracebacks or terminal stderr are never shown directly to the user. +- [x] **INST-03**: Install button validates all fields before spawning subprocess — reports specific field-level errors in friendly language (e.g., "未找到 Vault 路径,请检查设置"). Prevents cryptic failures mid-install. +- [x] **INST-04**: Existing sidebar (`PaperForgeStatusView`) and command palette actions (`Sync Library`, `Run OCR`) continue working unchanged alongside the new settings tab. Settings tab code is strictly self-contained — no reach into sidebar internals. --- @@ -100,12 +36,12 @@ Deferred from v1.4 scope to keep the milestone focused and manageable. | Feature | Reason | |---------|--------| -| Auto-triggering deep-reading from workers | Lite architecture keeps Worker and Agent layers separate (ADR-002) | -| Cloud-hosted multi-user service | Local-first scope | -| Replacing Zotero or Better BibTeX | Core dependency | -| OCR provider abstraction (beyond PaddleOCR) | Requires API research, deferred to v1.5+ | -| TypeScript Obsidian plugin architecture | Major new stack, needs dedicated milestone | -| Real-time Zotero sync (daemon) | Conflicts with Lite two-layer design | +| Plugin sidebar redesign | Sidebar stays as-is for v1.5; enhancement deferred to future | +| Plugin auto-update detection | Deferred to when listed on Obsidian Community Plugins | +| TypeScript migration | Plugin is pure JS CommonJS; conversion is out of scope | +| Build system (esbuild/webpack) | Plugin ships as single `main.js`; adding build step breaks current release | +| Multi-language i18n | Chinese-only is sufficient for target audience | +| Plugin published to Community Plugins | Deferred until v1.5 stabilizes settings UX | --- @@ -113,43 +49,20 @@ Deferred from v1.4 scope to keep the milestone focused and manageable. | Requirement | Phase | Status | |-------------|-------|--------| -| CH-01 | Phase 14 | Pending | -| CH-02 | Phase 14 | Pending | -| CH-03 | Phase 15 | Complete | -| CH-04 | Phase 17 | Pending | -| CH-05 | Phase 14 | Pending | -| OBS-01 | Phase 13 | Complete | -| OBS-02 | Phase 13 | Complete | -| OBS-03 | Phase 13 | Complete | -| OBS-04 | Phase 16 | Pending | -| OBS-05 | Phase 17 | Pending | -| REL-01 | Phase 16 | Pending | -| REL-02 | Phase 16 | Pending | -| REL-03 | Phase 16 | Pending | -| REL-04 | Phase 16 | Pending | -| DX-01 | Phase 17 | Pending | -| DX-02 | Phase 17 | Pending | -| DX-03 | Phase 18 | Complete | -| DX-04 | Phase 18 | Complete | -| TEST-01 | Phase 19 | Pending | -| TEST-02 | Phase 19 | Pending | -| TEST-03 | Phase 14 | Pending | -| TEST-04 | Phase 19 | Pending | -| UX-01 | Phase 18 | Complete | -| UX-02 | Phase 18 | Complete | -| UX-03 | Phase 18 | Complete | -| UX-04 | Phase 18 | Complete | -| DOCS-01 | Phase 18 | Complete | -| DOCS-02 | Phase 18 | Complete | -| DOCS-03 | Phase 18 | Complete | -| DOCS-04 | Phase 18 | Complete | +| SETUP-01 | Phase 20 | Complete | +| SETUP-02 | Phase 20 | Complete | +| SETUP-03 | Phase 20 | Pending | +| INST-01 | Phase 21 | Complete | +| INST-02 | Phase 21 | Complete | +| INST-03 | Phase 21 | Complete | +| INST-04 | Phase 21 | Complete | **Coverage:** -- v1.4 requirements: 30 total -- Mapped to phases: 30 (100%) -- Unmapped: 0 +- v1.5 requirements: 7 total +- Mapped to phases: 7 +- Unmapped: 0 ✓ --- -*Requirements defined: 2026-04-25* -*Last updated: 2026-04-26 — traceability populated with v1.4 phase mappings (30/30 requirements, 100% coverage)* +*Requirements defined: 2026-04-29* +*Last updated: 2026-04-29 after v1.5 requirements definition* diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 0244df63..6f22418b 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -1,122 +1,46 @@ -# Roadmap: PaperForge Lite v1.4 — Code Health & UX Hardening +# Roadmap: PaperForge Lite -**Milestone:** v1.4 -**Goal:** Eliminate all code duplication (~1,610 lines), add structured observability, automate code-health guardrails, and smooth user-facing workflow friction. -**Started:** 2026-04-25 -**Phase numbering:** Continues from v1.3 Phase 12 → v1.4 starts at Phase 13 +**Project kind:** brownfield-release-hardening +**Current milestone:** v1.5 — Obsidian Plugin Setup Integration +**Phase numbering:** Continuous (never restarts). v1.0 Phases 1-5, v1.1 Phases 6-8, v1.2 Phases 9-10, v1.3 Phases 11-12, v1.4 Phases 13-19, v1.5 Phases 20-21 + +--- + +## Milestones + +- ✅ **v1.0 MVP** — Phases 1-5 (shipped 2026-04-23) +- ✅ **v1.1 Sandbox Onboarding** — Phases 6-8 (shipped 2026-04-24) +- ✅ **v1.2 Systematization & Cohesion** — Phases 9-10 (shipped 2026-04-24) +- ✅ **v1.3 Path Normalization & Architecture Hardening** — Phases 11-12 (shipped 2026-04-24) +- ✅ **v1.4 Code Health & UX Hardening** — Phases 13-19 (shipped 2026-04-28) +- 🚧 **v1.5 Obsidian Plugin Setup Integration** — Phases 20-21 (in progress) --- ## Phases -- [x] **Phase 13: Logging Foundation** — Structured logging, `--verbose` flag, zero behavioral change to user-facing output -- [x] **Phase 14: Shared Utilities Extraction** — Extract `_utils.py` leaf module, eliminate ~1,610 lines of duplication across 7 workers -- [x] **Phase 15: Deep-Reading Queue Merge** — Single canonical `scan_library_records()` for both CLI and Agent consumers -- [x] **Phase 16: Retry + Progress Bars** — Resilient OCR with exponential backoff and user-visible progress indication -- [x] **Phase 17: Dead Code Removal + Pre-Commit** — Clean codebase validated by automated git hooks -- [x] **Phase 18: Documentation + CHANGELOG + UX Polish** — Complete user/maintainer docs, README fix, command naming audit (2 plans) -- [x] **Phase 19: Testing** — E2E pipeline tests, setup wizard tests, `_utils.py` unit tests -- [ ] **Phase 20: Headless Setup & Obsidian Plugin** — `paperforge setup --headless`, minimal Obsidian plugin for command palette integration - ---- - -## Phase Details - -### Phase 13: Logging Foundation -**Goal**: Structured, level-based logging infrastructure with zero behavioral change to user-facing output — sets the stage for all subsequent observability work. -**Depends on**: Nothing (first phase of v1.4) -**Requirements**: OBS-01, OBS-02, OBS-03 -**Success Criteria** (what must be TRUE): - 1. All worker modules use `logging.getLogger(__name__)` instead of bare `print()` for diagnostic/trace/error output - 2. `--verbose`/`-v` flag on `paperforge sync`, `paperforge ocr`, and `paperforge deep-reading` enables DEBUG-level output on stderr - 3. User-facing status messages continue to appear on stdout unchanged — piped commands (`paperforge status | grep ocr`) remain unbroken - 4. `PAPERFORGE_LOG_LEVEL` environment variable (accepting `DEBUG`/`INFO`/`WARNING`/`ERROR`) controls default log level - 5. `paperforge/logging_config.py` exists as the single `configure_logging(verbose)` call point; no scattered `basicConfig()` calls -**Plans**: 3 plans (2 waves) - -Plans: -- [x] 13-01-PLAN.md — Logging Core: logging_config.py + global --verbose flag -- [x] 13-02-PLAN.md — Module Loggers: logger instances + diagnostic print migration -- [x] 13-03-PLAN.md — Verbose Wiring: verbose params + command dispatch passthrough - ---- - -### Phase 14: Shared Utilities Extraction -**Goal**: Eliminate ~1,610 lines of copy-pasted utility code by creating `paperforge/worker/_utils.py` as a pure leaf module — THE critical path all subsequent code-health work depends on. -**Depends on**: Phase 13 (logging infrastructure available for diagnostic output) -**Requirements**: CH-01, CH-02, CH-05, TEST-03 -**Success Criteria** (what must be TRUE): - 1. `paperforge/worker/_utils.py` exists containing all shared utility functions: `read_json`, `write_json`, `read_jsonl`, `write_jsonl`, `yaml_quote`, `yaml_block`, `yaml_list`, `slugify_filename`, `_extract_year`, `load_journal_db`, `lookup_impact_factor`, `_STANDARD_VIEW_NAMES`, and the `_JOURNAL_DB` cache - 2. All 7 worker modules (`sync.py`, `ocr.py`, `deep_reading.py`, `repair.py`, `status.py`, `update.py`, `base_views.py`) import shared functions from `paperforge.worker._utils` — no local copy of any utility function remains - 3. No circular imports: `_utils.py` imports only from stdlib and `paperforge.config` — never from any sibling worker module - 4. All 205 existing tests pass with zero failures after extraction (verified by `pytest tests/ -x`) - 5. Re-exports with `# Re-exported from _utils.py for backward compatibility` comments preserved in original modules where callers may still reference them -**Plans**: 2 plans (1 wave) - -Plans: -- [x] 18-01-PLAN.md — Core Config & Foundation Docs (auto_analyze_after_ocr, CHANGELOG, CONTRIBUTING) -- [x] 18-02-PLAN.md — Migration, Architecture & Doc Polish (MIGRATION, ADRs, AGENTS, INDEX, README) - ---- - -### Phase 19: Testing -**Goal**: Validate the entire v1.4 codebase with expanded test coverage — E2E pipeline tests, setup wizard tests, and dedicated `_utils.py` unit tests. -**Depends on**: All previous phases (tests validate the final v1.4 state) -**Requirements**: TEST-01, TEST-02, TEST-04 -**Success Criteria** (what must be TRUE): - 1. E2E integration tests pass covering full Zotero JSON → selection-sync → index-refresh → OCR queue → formal notes pipeline using the sandbox fixture vault - 2. Setup wizard tests pass validating agent platform detection, vault path resolution, environment checks, and configuration file generation - 3. Dedicated unit tests for `_utils.py` cover JSON I/O, YAML helpers, slugify, and journal DB functions — `test_utils_json.py`, `test_utils_yaml.py`, `test_utils_slugify.py`, `test_utils_journal.py` - 4. All 205 existing tests continue to pass with zero failures — minimum bar: 205+ tests passing, 0 failures, 0 errors -**Plans**: 3 plans (1 wave) — EXECUTED (317 tests pass, see 19-*-SUMMARY.md) - -Plans: -- [x] 19-01-PLAN.md — _utils.py unit tests (71 new tests, 4 files) -- [x] 19-02-PLAN.md — E2E pipeline integration tests (13 tests, selection-sync → notes) -- [x] 19-03-PLAN.md — Setup wizard tests (30 tests, Agent configs + EnvChecker) - ---- - -### Phase 20: Headless Setup & Obsidian Plugin -**Goal**: Enable one-command `paperforge setup --headless` for AI agents, and deploy a minimal Obsidian plugin for command palette integration. -**Depends on**: Phase 19 (tested deployment pipeline already exists) -**Requirements**: None (v1.4.2 patch — new milestone document at `.planning/milestones/v1.4.2.md`) -**Success Criteria** (what must be TRUE): - 1. `paperforge setup --headless --vault --agent opencode` completes full installation, exit code 0 - 2. Headless-generated vault structure matches wizard-generated structure (dirs, files, configs) - 3. `.obsidian/plugins/paperforge/main.js` and `manifest.json` are deployed and valid - 4. `python -m paperforge sync/ocr/status` works with cwd=vault (same env as Obsidian plugin) - 5. AGENTS.md contains complete AI Agent self-install guidance section - 6. All 317 existing tests pass with zero regressions -**Plans**: No formal PLAN.md — milestone document is authoritative - ---- - -## Progress - -**Execution Order:** Phases 13-14-15-16 are strictly sequential (hard dependency chain). Phase 18 can overlap partially with Phases 14-17. Phase 19 must be last. - -| Phase | Milestone | Plans Complete | Status | Completed | -|-------|-----------|----------------|--------|-----------| -| 13. Logging Foundation | v1.4 | 3/3 | Complete | 2026-04-27 | -| 14. Shared Utils Extraction | v1.4 | 0/0 | Complete | 2026-04-27 | -| 15. Queue Merge | v1.4 | 1/1 | Complete | 2026-04-27 | -| 16. Retry + Progress | v1.4 | 2/2 | Complete | 2026-04-27 | -| 17. Dead Code + Pre-Commit | v1.4 | 1/1 | Complete | 2026-04-27 | -| 18. Docs + CHANGELOG + UX | v1.4 | 2/2 | Complete | 2026-04-27 | -| 19. Testing | v1.4 | 3/3 | Complete | 2026-04-28 | -| 20. Headless Setup & Plugin | v1.4.2 | — | In progress | — | - -### Historical Milestones -
✅ v1.0 MVP (Phases 1-5) — SHIPPED 2026-04-23 -- Phase 1: Config And Command Foundation (3/3 plans) -- Phase 2: PaddleOCR And PDF Path Hardening (2/2 plans) -- Phase 3: Config-Aware Obsidian Bases (2/2 plans) -- Phase 4: End-To-End Onboarding And Validation (2/2 plans) -- Phase 5: Release Verification (2/2 plans) +### Phase 1: Config And Command Foundation +**Goal**: Stable commands and shared path/env resolution +**Plans**: 3/3 plans complete + +### Phase 2: PaddleOCR And PDF Path Hardening +**Goal**: Diagnosable, retryable OCR +**Plans**: 2/2 plans complete + +### Phase 3: Config-Aware Obsidian Bases +**Goal**: Real workflow Bases without hardcoded paths +**Plans**: 2/2 plans complete + +### Phase 4: End-To-End Onboarding And Validation +**Goal**: User can complete first-paper flow +**Plans**: 2/2 plans complete + +### Phase 5: Release Verification +**Goal**: Tests and docs prove ship readiness +**Plans**: 2/2 plans complete _Archived: `.planning/milestones/v1.0.md`_ @@ -125,9 +49,17 @@ _Archived: `.planning/milestones/v1.0.md`_
✅ v1.1 Sandbox Onboarding (Phases 6-8) — SHIPPED 2026-04-24 -- Phase 6: Setup, CLI, And Diagnostics Consistency (3/3 plans) -- Phase 7: Zotero PDF, Metadata, And State Repair (2/2 plans) -- Phase 8: Deep Helper Deployment And Sandbox Regression Gate (2/2 plans) +### Phase 6: Setup, CLI, And Diagnostics Consistency +**Goal**: Field names, env vars, export validation, HTTP 405 handling, vault prefill +**Plans**: 3/3 plans complete + +### Phase 7: Zotero PDF, Metadata, And State Repair +**Goal**: OCR meta validation, three-way divergence repair, PDF resolver tests +**Plans**: 2/2 plans complete + +### Phase 8: Deep Helper Deployment And Sandbox Regression Gate +**Goal**: Importability, fixtures, smoke tests, rollback +**Plans**: 2/2 plans complete _Archived: `.planning/milestones/v1.1.md`_ @@ -136,8 +68,13 @@ _Archived: `.planning/milestones/v1.1.md`_
✅ v1.2 Systematization & Cohesion (Phases 9-10) — SHIPPED 2026-04-24 -- Phase 9: Command Unification & CLI Simplification (2/2 plans) -- Phase 10: Documentation & Cohesion (2/2 plans) +### Phase 9: Command Unification & CLI Simplification +**Goal**: Unified `/pf-*` namespace, `paperforge sync` combined command +**Plans**: 2/2 plans complete + +### Phase 10: Documentation & Cohesion +**Goal**: Updated AGENTS.md, migration guide, consistency audit +**Plans**: 2/2 plans complete _Archived: `.planning/milestones/v1.2-ROADMAP.md`_ @@ -146,14 +83,131 @@ _Archived: `.planning/milestones/v1.2-ROADMAP.md`_
✅ v1.3 Path Normalization & Architecture Hardening (Phases 11-12) — SHIPPED 2026-04-24 -- Phase 11: Zotero Path Normalization (1/1 plan) -- Phase 12: Architecture Cleanup (1/1 plan) +### Phase 11: Zotero Path Normalization +**Goal**: Parse 3 BBT formats, generate wikilinks, multi-attachment support +**Plans**: 1/1 plan complete +**Requirements**: ZPATH-01, ZPATH-02, ZPATH-03 + +### Phase 12: Architecture Cleanup +**Goal**: Eliminate module boundary leaks (pipeline/ → paperforge/worker/), migrate skills +**Plans**: 1/1 plan complete +**Requirements**: ARCH-01, ARCH-02 _Archived: `.planning/milestones/v1.3.md`_
+
+✅ v1.4 Code Health & UX Hardening (Phases 13-19) — SHIPPED 2026-04-28 + +### Phase 13: Logging Foundation +**Goal**: Structured logging, `--verbose` flag, zero behavioral change to user-facing output +**Requirements**: OBS-01, OBS-02, OBS-03 +**Plans**: 3/3 plans complete + +### Phase 14: Shared Utilities Extraction +**Goal**: Extract `_utils.py`, eliminate ~1,610 lines of duplication across 7 workers +**Requirements**: CH-01, CH-02, CH-05, TEST-03 +**Plans**: 2/2 plans complete + +### Phase 15: Deep-Reading Queue Merge +**Goal**: Single canonical `scan_library_records()` for both CLI and Agent consumers +**Requirements**: CH-03, CH-04 +**Plans**: 1/1 plan complete + +### Phase 16: Retry + Progress Bars +**Goal**: Resilient OCR with exponential backoff and user-visible progress indication +**Requirements**: UX-01, UX-02 +**Plans**: 2/2 plans complete + +### Phase 17: Dead Code Removal + Pre-Commit +**Goal**: Clean codebase validated by automated git hooks (ruff) +**Requirements**: CH-06, CH-07 +**Plans**: 1/1 plan complete + +### Phase 18: Documentation + CHANGELOG + UX Polish +**Goal**: Complete user/maintainer docs, auto_analyze_after_ocr, CHANGELOG, CONTRIBUTING +**Requirements**: DOC-01, DOC-02, DOC-03, UX-03 +**Plans**: 2/2 plans complete + +### Phase 19: Testing +**Goal**: E2E pipeline tests, setup wizard tests, `_utils.py` unit tests (317 passed, 2 skipped) +**Requirements**: TEST-01, TEST-02, TEST-04 +**Plans**: 3/3 plans complete + +_Note: Phase 20 (v1.4.2 "Headless Setup & Obsidian Plugin") was a placeholder. v1.5 expands this into a full plugin settings tab with setup integration — see Phases 20-21 below._ + +_Archived: `.planning/milestones/v1.4.md`_ + +
+ +### 🚧 v1.5 Obsidian Plugin Setup Integration (In Progress) + +**Milestone Goal:** Move the entire PaperForge setup/configuration experience from terminal CLI into the Obsidian plugin's settings tab, so a new user downloads one plugin and completes full installation without touching a terminal. + +- [x] **Phase 20: Plugin Settings Shell & Persistence** — Obsidian settings tab with all setup fields, persistence across restarts, debounced saves (completed 2026-04-29) +- [ ] **Phase 21: One-Click Install & Polished UX** — Install button with field validation, `spawn`-based subprocess orchestration, human-readable Chinese notices + --- -*Roadmap created: 2026-04-26 — Milestone v1.4 Code Health & UX Hardening* -*Phase numbering continues from v1.3 Phase 12* +## Phase Details + +### Phase 20: Plugin Settings Shell & Persistence +**Goal**: Users can access PaperForge configuration in Obsidian's Settings tab, edit all setup wizard fields, and settings survive restarts and tab switches — all without breaking the existing sidebar. +**Depends on**: Phase 19 (tested deployment pipeline exists) +**Requirements**: SETUP-01, SETUP-02, SETUP-03 +**Success Criteria** (what must be TRUE): + 1. User opens Obsidian Settings → Community Plugins → PaperForge (gear icon) and sees a settings tab with all 8 configuration fields grouped in logical sections with Chinese labels and tooltips + 2. User edits any text field, navigates to a different settings tab and returns — all edited values remain intact (in-memory state survives `display()` re-invocation without data loss) + 3. User fills in all fields, closes and re-opens Obsidian, and all values restore correctly from `data.json` — no data loss, corruption, or `TypeError` on null data + 4. First-time install (no prior `data.json`) loads gracefully with `DEFAULT_SETTINGS` values pre-filled — settings tab renders cleanly without JavaScript errors + 5. After registering the settings tab via `addSettingTab()`, the existing `PaperForgeStatusView` sidebar and command palette actions (`Sync Library`, `Run OCR`) continue functioning without regression +**Plans**: TBD +**UI hint**: yes + +### Phase 21: One-Click Install & Polished UX +**Goal**: Users trigger full PaperForge setup with one click and receive step-by-step Chinese feedback via Obsidian notices — no terminal interaction required, no raw traceback exposure. +**Depends on**: Phase 20 (settings tab shell and persistence must exist before adding install behavior) +**Requirements**: INST-01, INST-02, INST-03, INST-04 +**Success Criteria** (what must be TRUE): + 1. User fills in all required configuration fields and clicks "安装配置" — the full setup pipeline executes: `paperforge.json` is written, directories are created, environment checks pass, and agent configs are generated + 2. During setup execution, the Install button is visually disabled and displays "正在安装..." — clicking it again produces no duplicate subprocess (double-click prevention with `setDisabled(true)`) + 3. User sees step-by-step Chinese notice toasts throughout setup progress ("正在创建目录... ✓", "正在写入配置文件... ✓", "正在检查环境... ✓") — raw Python tracebacks or terminal stderr content is never displayed directly in the Notice + 4. User leaves a required field empty (e.g., Vault path) and clicks Install — receives a specific, friendly Chinese error notice (e.g., "未找到 Vault 路径,请检查设置") before any subprocess is spawned, preventing cryptic mid-install failures + 5. After setup completes (success or failure), the sidebar `PaperForgeStatusView` panel and command palette actions (`Sync Library`, `Run OCR`) continue working normally — settings tab code is strictly additive with zero coupling to sidebar internals +**Plans**: 2 plans (21-01, 21-02) +**UI hint**: yes + +--- + +## Progress + +**Execution Order:** Phases 20 → 21 are strictly sequential. Phase 20 provides the settings shell; Phase 21 adds install behavior on top. + +| Phase | Milestone | Plans Complete | Status | Completed | +|-------|-----------|----------------|--------|-----------| +| 1. Config & Command Foundation | v1.0 | 3/3 | Complete | 2026-04-23 | +| 2. PaddleOCR & PDF Path Hardening | v1.0 | 2/2 | Complete | 2026-04-23 | +| 3. Config-Aware Obsidian Bases | v1.0 | 2/2 | Complete | 2026-04-23 | +| 4. End-To-End Onboarding | v1.0 | 2/2 | Complete | 2026-04-23 | +| 5. Release Verification | v1.0 | 2/2 | Complete | 2026-04-23 | +| 6. Setup & CLI Diagnostics | v1.1 | 3/3 | Complete | 2026-04-24 | +| 7. Zotero PDF & Metadata Repair | v1.1 | 2/2 | Complete | 2026-04-24 | +| 8. Deep Helper & Sandbox Gate | v1.1 | 2/2 | Complete | 2026-04-24 | +| 9. Command Unification & CLI | v1.2 | 2/2 | Complete | 2026-04-24 | +| 10. Documentation & Cohesion | v1.2 | 2/2 | Complete | 2026-04-24 | +| 11. Zotero Path Normalization | v1.3 | 1/1 | Complete | 2026-04-24 | +| 12. Architecture Cleanup | v1.3 | 1/1 | Complete | 2026-04-24 | +| 13. Logging Foundation | v1.4 | 3/3 | Complete | 2026-04-27 | +| 14. Shared Utils Extraction | v1.4 | 2/2 | Complete | 2026-04-27 | +| 15. Queue Merge | v1.4 | 1/1 | Complete | 2026-04-27 | +| 16. Retry + Progress | v1.4 | 2/2 | Complete | 2026-04-27 | +| 17. Dead Code + Pre-Commit | v1.4 | 1/1 | Complete | 2026-04-27 | +| 18. Docs + CHANGELOG + UX | v1.4 | 2/2 | Complete | 2026-04-27 | +| 19. Testing | v1.4 | 3/3 | Complete | 2026-04-28 | +| 20. Plugin Settings Shell & Persistence | v1.5 | 1/1 | Complete | 2026-04-29 | +| 21. One-Click Install & Polished UX | v1.5 | 0/2 | Planned | — | + +--- + +*Roadmap updated: 2026-04-29 — Phase 21 plans created (One-Click Install & Polished UX)* diff --git a/.planning/STATE.md b/.planning/STATE.md index 67f6664d..403a55c7 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -1,104 +1,69 @@ --- gsd_state_version: 1.0 -milestone: v1.4 -milestone_name: milestone -status: In progress -stopped_at: Phase 19 execution complete -last_updated: "2026-04-27T10:52:33.704Z" +milestone: v1.5 +milestone_name: Obsidian Plugin Setup Integration +status: Phase complete — ready for verification +stopped_at: Completed Phase 21 (One-Click Install & Polished UX) — both plans delivered +last_updated: "2026-04-29T14:40:05.628Z" progress: - total_phases: 3 + total_phases: 2 completed_phases: 2 - total_plans: 6 - completed_plans: 6 + total_plans: 3 + completed_plans: 3 --- -# State: PaperForge Lite Release Hardening +# Project State ## Project Reference -See: `.planning/PROJECT.md` (updated 2026-04-25) +See: .planning/PROJECT.md (updated 2026-04-29) -**Core value:** A new user can install PaperForge, configure their own vault paths and PaddleOCR credentials, then run the full literature pipeline with copy-pasteable commands that diagnose failures clearly. - -**Current focus:** Phase 13 — logging-foundation +**Core value:** A new user downloads one Obsidian plugin and completes full PaperForge installation without touching a terminal. +**Current focus:** Phase 21 — one-click-install-and-polished-ux ## Current Position -Phase: 19 -Plans: 19-01 ready to execute, 19-02 ready to execute, 19-03 ready to execute +Phase: 21 (one-click-install-and-polished-ux) — EXECUTING +Plan: 2 of 2 ## Performance Metrics **Velocity:** -- Total phases completed (cumulative): 14 -- v1.4 phases: 2/7 complete +- Total plans completed: 38 (across Phases 1-19) +- Average duration: Not yet tracked +- Total execution time: Not yet tracked -**By Milestone:** +**By Phase (most recent):** -| Milestone | Phases | Status | -|-----------|--------|--------| -| v1.0 MVP | 1-5 | Shipped 2026-04-23 | -| v1.1 Sandbox | 6-8 | Shipped 2026-04-24 | -| v1.2 Systematization | 9-10 | Shipped 2026-04-24 | -| v1.3 Architecture | 11-12 | Shipped 2026-04-24 | -| v1.4 Code Health | 13-19 | In progress | +| Phase | Milestone | Plans | Status | +|-------|-----------|-------|--------| +| 19. Testing | v1.4 | 3/3 | Complete | +| 20. Plugin Settings Shell | v1.5 | 3/3 | Complete | +| 21. One-Click Install | v1.5 | 2/2 | Planned | + +**Recent Trend:** v1.4 averaged ~1 day per phase. Target for v1.5 should be similar. *Updated after each plan completion* -| Phase 13-logging-foundation P01 | 18min | 2 tasks | 2 files | -| Phase 13-logging-foundation P02 | 12min | 2 tasks | 12 files | -| Phase 13-logging-foundation P03 | 8min | 2 tasks | 6 files | -| Phase 15-deep-reading-queue-merge P01 | 4min | 2 tasks | 3 files | -| Phase 15-deep-reading-queue-merge P01 | 4min | 2 tasks | 3 files | -| Phase 17-dead-code-precommit P01 | 25min | 2 tasks | 11 files | -| Phase 18-documentation-ux-polish P01 | 12min | 3 tasks | 4 files | -| Phase 18-documentation-ux-polish P01 | 12min | 3 tasks | 4 files | -| Phase 18-documentation-ux-polish P02 | 18min | 3 tasks | 6 files | +| Phase 20 P20 | 2min | 3 tasks | 1 files | +| Phase 21 P21-01 | — | 3 tasks | 2 files | +| Phase 21 P21-02 | — | 2 tasks | 1 files | +| Phase 21-one-click-install-and-polished-ux P01 | 5 min | 3 tasks | 2 files | +| Phase 21-one-click-install-and-polished-ux P02 | 5 min | 2 tasks | 1 files | ## Accumulated Context -### v1.4 Critical Path +### Decisions -- **Phase 13:** Logging Foundation (enables all observability work) -- **Phase 14:** Shared Utils Extraction (critical path — all code-health work depends on `_utils.py`) -- **Phases 13-14-15-16:** Strictly sequential (hard dependency chain) -- **Phase 18:** Can partially overlap with Phases 14-17 -- **Phase 19:** Must be last (validates final state) +- **v1.5**: Settings tab in Obsidian plugin as setup entry point — eliminates terminal requirement; plugin becomes single download artifact. Zero new npm or Python dependencies. (See PROJECT.md Key Decisions) -### v1.4 Key Decisions (from research) +Recent decisions affecting current work: -- **Dual-output logging:** `print()` stays for user-facing stdout; `logging` for diagnostic stderr — NOT a wholesale replacement -- **`_utils.py` leaf module:** Must never import from `paperforge.worker.*` or `paperforge.commands.*` — circular import firebreak -- **Re-exports preserved:** Moved functions get `# Re-exported from _utils.py` comments in original modules for backward compatibility -- **No new user-facing features:** v1.4 is pure infrastructure hardening — `auto_analyze_after_ocr` is the only opt-in workflow option - -### v1.4 Environment Variables (new) - -- `PAPERFORGE_LOG_LEVEL` — `DEBUG`/`INFO`/`WARNING`/`ERROR` -- `PAPERFORGE_RETRY_MAX` — max retry attempts -- `PAPERFORGE_RETRY_BACKOFF` — backoff multiplier - -### Phase 11 Decisions (Locked) - -- D-01 through D-08: Documented in ADR-011 -- `storage:` prefix as unified internal representation for Zotero storage paths -- Hybrid main PDF selection (title → size → shortest title) -- Forward slashes exclusively in wikilinks (`Path.as_posix()`) -- `path_error` frontmatter field for explicit error tracking - -### Phase 17 Decisions (Locked) - -- `from paperforge.config import load_vault_config, paperforge_paths` replaces all per-module delegation wrappers -- Pre-commit hooks configured but NOT auto-installed (DX-04 deferred to Phase 18) -- `ruff check --fix` + `ruff format` are sufficient for automated code cleanup -- `E501` (line-too-long) and pre-existing simplifications suppressed via `per-file-ignores` — not a blocker for code quality - -### Phase 12 Decisions (Locked) - -- Migrated 4041-line `literature_pipeline.py` into 7 focused modules under `paperforge/worker/` -- Function-level imports used to break circular dependencies between sync.py and ocr.py -- Module-reference imports (`_sync.run_selection_sync`) used in ocr.py for test patch compatibility -- Old `pipeline/` and `skills/` directories removed after confirming zero import references +- **Phase 20**: Plugin settings use Obsidian's `PluginSettingTab` API, `loadData()`/`saveData()` for persistence, `Setting` form builder for UI. No TypeScript, no build system. Plugin is pure JS CommonJS (`paperforge/plugin/main.js`). +- **Phase 20-21**: Settings tab is purely additive — zero changes to existing `PaperForgeStatusView` sidebar or `ACTIONS[]` definitions. +- **Phase 21**: Subprocess orchestration uses `node:child_process.spawn` (not `exec`) for non-blocking setup execution with stdout/stderr parsing. +- [Phase 21-one-click-install-and-polished-ux]: Settings tab is purely additive — zero changes to PaperForgeStatusView sidebar or ACTIONS[] definitions +- [Phase 21-one-click-install-and-polished-ux]: Subprocess uses spawn (not exec) for stdout streaming, --headless (not --non-interactive), API key via --paddleocr-key flag ### Pending Todos @@ -106,15 +71,11 @@ None yet. ### Blockers/Concerns -- **Circular import risk in Phase 14:** `_utils.py` must be pure leaf module — verify with `pytest --collect-only` after each worker migration -- **Windows TTY detection (Phase 16):** `sys.stdout.reconfigure(encoding='utf-8')` may not work on all PowerShell configs — test on actual Windows 10/11 -- **Backward compatibility:** Users relying on `from paperforge.worker.sync import read_json` — mitigation: re-exports with deprecation comments -- **Pre-commit hooks not installed:** CONTRIBUTING.md documents `pre-commit install` (DX-04 docs complete). Hooks must be manually installed by each developer. +- **Phase 20**: Critical pitfalls from research — debounced saves (500ms) prevent `data.json` corruption; `display()` lifecycle requires immediate in-memory update on change; `loadData()` null merge via `Object.assign({}, DEFAULTS, data || {})` +- **Phase 21**: Windows path encoding with spaces/Unicode requires `spawn` with proper quoting; raw stderr must be parsed into friendly Chinese messages before Notice display; button double-click prevention via `setDisabled(true)` ## Session Continuity -Last session: 2026-04-27T10:52:33.701Z -Stopped at: Phase 19 execution complete -Resume file: .planning/phases/19-testing/19-03-SUMMARY.md - ----\n*Initialized: 2026-04-23*\n*Last updated: 2026-04-26 (v1.4 roadmap created — Phase 13 ready to plan)* +Last session: 2026-04-29T14:40:05.625Z +Stopped at: Completed Phase 21 (One-Click Install & Polished UX) — both plans delivered +Resume file: None diff --git a/.planning/phases/21-one-click-install-and-polished-ux/21-01-SUMMARY.md b/.planning/phases/21-one-click-install-and-polished-ux/21-01-SUMMARY.md new file mode 100644 index 00000000..51d464cf --- /dev/null +++ b/.planning/phases/21-one-click-install-and-polished-ux/21-01-SUMMARY.md @@ -0,0 +1,102 @@ +--- +phase: 21-one-click-install-and-polished-ux +plan: 01 +subsystem: plugin +tags: [obsidian, plugin, settings-tab, css, validation, chinese-ui] +requires: + - phase: 20-plugin-settings-shell-persistence + provides: PaperForgeSettingTab with DEFAULT_SETTINGS, display(), helpers +provides: + - Install button section with status area in settings tab + - Client-side field validation for 7 required fields + - Status area CSS styles with success/error/progress color variants +affects: [21-one-click-install-and-polished-ux] +tech-stack: + added: [] + patterns: + - Obsidian CSS variables for theme-consistent styling + - color-mix() for subtle tinted backgrounds +key-files: + created: [] + modified: + - paperforge/plugin/main.js + - paperforge/plugin/styles.css +key-decisions: + - "D-01: Settings tab is purely additive — zero changes to PaperForgeStatusView sidebar or ACTIONS[] definitions" + - "D-02: Client-side only validation using string trim checks, no filesystem calls" + - "D-03: zotero_data_dir is NOT validated (optional field — auto-detected by headless_setup)" + - "D-04: All error messages in Chinese per INST-03 requirement" +requirements-completed: [INST-01, INST-03] +duration: 5 min +completed: 2026-04-29 +--- + +# Phase 21 Plan 01: Install Button UI & Field Validation + +**Install button section with status area, client-side validation of 7 required fields, and CSS status styles with success/error/progress color variants** + +## Performance + +- **Duration:** 5 min +- **Started:** 2026-04-29T14:38:41Z +- **Completed:** 2026-04-29T14:43:00Z +- **Tasks:** 3 +- **Files modified:** 2 + +## Accomplishments + +- "安装配置" section appended to `PaperForgeSettingTab.display()` with status div + CTA button +- `_validate()` method checks 7 required settings fields for non-empty values with Chinese error messages +- `paperforge/plugin/styles.css` gains SECTION 5 with 4 CSS classes for install status display +- Button onClick wired to `_runSetup(button)` — forward declaration for Plan 02 subprocess wiring +- No existing code modified (sidebar, actions, other settings sections preserved) + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: Add install button section and status area to display()** - `2f1feec` (feat) +2. **Task 2: Add _validate() field validation method** - `0d60dd6` (feat) +3. **Task 3: Add install status CSS styles** - `dc6be1c` (feat) + +**Plan metadata:** (final commit after summary) + +## Files Created/Modified + +- `paperforge/plugin/main.js` - Added "安装配置" section (14 lines), `_validate()` method (29 lines) +- `paperforge/plugin/styles.css` - Added SECTION 5 with `.paperforge-install-status`, `.paperforge-install-success`, `.paperforge-install-error`, `.paperforge-install-progress` (31 lines) + +## Decisions Made + +- **Additive-only approach**: Settings tab is purely additive to existing `PaperForgeSettingTab.display()` — no modifications to `PaperForgeStatusView` sidebar or `ACTIONS[]` definitions +- **Client-side validation**: Uses simple string checks (`!s.key || !s.key.trim()`), no filesystem calls. Path existence validation deferred to subprocess (fails gracefully with friendly error message) +- **Optional field exclusion**: `zotero_data_dir` is NOT validated — it's optional and auto-detected by the headless setup + +## Deviations from Plan + +None - plan executed exactly as written. + +## Issues Encountered + +None + +## User Setup Required + +None - no external service configuration required. + +## Next Phase Readiness + +Ready for Plan 21-02: wire `_runSetup()` subprocess orchestration and notice formatting helpers into the install button. + +## Self-Check: PASSED + +- [x] All 3 tasks committed atomically (2f1feec, 0d60dd6, dc6be1c) +- [x] main.js: install section, _validate(), _runSetup reference present +- [x] styles.css: SECTION 5 with all 3 status variants present +- [x] No existing code modified (sidebar, actions preserved) +- [x] SUMMARY.md created in plan directory + +--- + +*Phase: 21-one-click-install-and-polished-ux* +*Completed: 2026-04-29* diff --git a/.planning/phases/21-one-click-install-and-polished-ux/21-02-SUMMARY.md b/.planning/phases/21-one-click-install-and-polished-ux/21-02-SUMMARY.md new file mode 100644 index 00000000..792f4296 --- /dev/null +++ b/.planning/phases/21-one-click-install-and-polished-ux/21-02-SUMMARY.md @@ -0,0 +1,104 @@ +--- +phase: 21-one-click-install-and-polished-ux +plan: 02 +subsystem: plugin +tags: [obsidian, plugin, subprocess, spawn, chinese-ui, error-handling] +requires: + - phase: 21-one-click-install-and-polished-ux/01 + provides: Install button, _validate(), _statusArea, CSS status classes +provides: + - _runSetup() subprocess orchestration with spawn + - _showNotice(), _formatSetupError(), _processSetupOutput(), _setStatus() helpers + - Button disable/enable lifecycle with double-click prevention + - Chinese error pattern mapping (5 patterns) +affects: [] +tech-stack: + added: [] + patterns: + - spawn (not exec) for non-blocking subprocess with stdout streaming + - try/finally for guaranteed button re-enable + - Pattern-based error mapping to user-facing messages +key-files: + created: [] + modified: + - paperforge/plugin/main.js +key-decisions: + - "Use spawn (not exec): streams stdout line-by-line for step progress" + - "Use --headless (not --non-interactive): correct CLI flag name" + - "Pass API key via --paddleocr-key flag (not env var PADDLEOCR_API_TOKEN)" + - "Explicit directory args override headless_setup built-in defaults" + - "Error messages in Chinese, raw stderr logged to console only" +requirements-completed: [INST-01, INST-02, INST-04] +duration: 5 min +completed: 2026-04-29 +--- + +# Phase 21 Plan 02: Subprocess Orchestration & Notice Formatting + +**_runSetup() subprocess spawn with Chinese error mapping, step-by-step progress updates, and double-click prevention via try/finally button lifecycle** + +## Performance + +- **Duration:** 5 min +- **Started:** 2026-04-29T14:43:00Z +- **Completed:** 2026-04-29T14:48:00Z +- **Tasks:** 2 +- **Files modified:** 1 + +## Accomplishments + +- `_runSetup(button)` async method spawns `python -m paperforge setup --headless` with explicit args +- Button disabled during execution, re-enabled in `finally` — prevents double-click +- `_showNotice()` renders success/error/progress via Obsidian Notice API with appropriate durations +- `_formatSetupError()` maps 5+ common error patterns to Chinese messages (Python not found, module missing, permission denied, path not found, timeout) +- `_processSetupOutput()` parses `[*]` / `[OK]` / `[FAIL]` step markers from stdout for real-time status updates +- `_setStatus()` updates status area with color-coded CSS class (success/error/progress) +- Raw stderr logged to console only — user never sees raw tracebacks (INST-02 compliance) +- Sidebar and commands unchanged (INST-04 verified) + +## Task Commits + +1. **Task 1+2: Add _runSetup() + 4 notice helpers** - `5803898` (feat) + +**Plan metadata:** (final commit after summary) + +## Files Created/Modified + +- `paperforge/plugin/main.js` - Added `_runSetup()` (73 lines), `_showNotice()`, `_formatSetupError()`, `_processSetupOutput()`, `_setStatus()` (45 lines total) + +## Decisions Made + +- **spawn over exec**: `spawn` streams stdout line-by-line so `_processSetupOutput()` can show step progress. `exec` buffers all output — no intermediate feedback. +- **--headless over --non-interactive**: The CLI defines `--headless` flag. The initial draft incorrectly used `--non-interactive` — corrected per code review. +- **--paddleocr-key flag**: The `headless_setup()` function reads API key from CLI argument, not from `PADDLEOCR_API_TOKEN` env var. +- **Explicit directory args**: Plugin's defaults (20_Resources, Control) differ from headless_setup's built-in defaults (03_Resources, LiteratureControl). Must override via `--resources-dir` and `--control-dir`. +- **Error mapping patterns**: 5 patterns cover the most common failure modes for first-time users. Full error always available via `console.error()`. + +## Deviations from Plan + +None - plan executed exactly as written. + +## Issues Encountered + +None + +## User Setup Required + +None - no external service configuration required. + +## Next Phase Readiness + +Phase 21 complete — both plans delivered. One-click install button with field validation, subprocess orchestration, Chinese step-by-step feedback, and error handling. Ready for v1.5 milestone verification. + +## Self-Check: PASSED + +- [x] All 5 methods present in main.js (_runSetup, _showNotice, _formatSetupError, _processSetupOutput, _setStatus) +- [x] Uses --headless, not --non-interactive +- [x] INST-02: No raw error exposure in new Notice calls (uses _formatSetupError) +- [x] INST-04: Sidebar and commands preserved (PaperForgeStatusView, addCommand, addRibbonIcon) +- [x] SUMMARY.md created in plan directory + +--- + +*Phase: 21-one-click-install-and-polished-ux* +*Completed: 2026-04-29*