- Replace this.plugin with this.app.plugins.plugins['paperforge']
- PaperForgeStatusView does not have a plugin property
- Remove debug console.log lines
- Merge status strip + file buttons into one row (left pills, right buttons)
- Move OCR/Analyze toggles into technical details disclosure body
- Replace All Set card with compact complete state row
- Save/restore technical details expanded state to prevent toggle flash
- Delete unused _renderPaperStatusStrip and _renderPaperFilesRow methods
- UI text: use Chinese labels (打开 PDF, 打开全文, 加入 OCR, 标记精读)
- processFrontMatter triggers modify event which auto-refreshes the view
- Double refresh was resetting technical details toggle state (flash on first click)
- Discussion card only shows for papers with ai/discussion.json (currently 2Y9M3ILK only)
- Discussion card: use lastIndexOf('/') instead of path.dirname to avoid
Windows backslash separator breaking Obsidian vault path resolution
- OCR token: also check .env PADDLEOCR_API_TOKEN as fallback when plugin
settings paddleocr_api_key is empty
- Remove OCR pipeline and metric cards from global mode (moved to base)
- Add library snapshot: papers, PDFs ready, OCR done, deep-read done
- Add system status grid: runtime, index, Zotero export, OCR token
- Add issues panel with contextual Run Doctor / Repair Issues (only when issues exist)
- Add contextual Start Working actions: Open Literature Hub + Sync Library
- Add null guards to _renderStats and _renderOcr for safe backwards compat
- Replace metric cards + bar chart + health grid with workflow funnel overview
- Move OCR pipeline from global to base (same progress bar logic, new container)
- Replace health matrix with compact issue summary (only visible when issues exist)
- Add contextual action buttons: Sync Library + Run OCR
- Remove _renderCollectionHealth (replaced by inline issue summary)
- Add _extractZoteroKeyFromPath: extract key from dirname pattern '{KEY} - {title}'
- Modify _resolveModeForFile: fallback to workspace detection for any file type
- Fixes fulltext.md and other workspace files dropping to global mode
- New services/skill_deploy.py: single source of truth for agent skill deployment
- AGENT_CONFIGS with 9 platforms, all vault-local
- deploy_skills() with install/update mode (overwrite flag)
- Used by both setup wizard and update worker
- update.py: _deploy_all_skills() after pip/git/zip update
- setup_wizard.py: delegates skill deploy to shared service
- config.py: add agent_platform default
- main.js: Copy Context + Copy Collection Context now pure JS
- Uses in-memory _cachedItems / _currentPaperEntry
- No subprocess spawn, no timeout, no JSON parse errors
- testable.js: remove needsKey/needsFilter from context actions
- commands.test.mjs: update assertions for removed flags
- Move resolvePythonExecutable, getPluginVersion, classifyError, ACTIONS, etc. to src/testable.js
- main.js now requires from ./src/testable.js instead of inline duplication
- Tests import from ../src/testable.js (no obsidian dependency)
- Remove vitest obsidian mock setup (no longer needed)
- Fixes L3 Plugin Tests that failed because main.js requires 'obsidian'
- Add named exports for testable functions (resolvePythonExecutable, getPluginVersion, etc.)
- Update test imports from ../src/*.js to ../main.js
- Fix repair action test: disabled flag was removed when ACTIONS was inlined
- Add paperforgeEnrichedEnv() to enrich PATH for GUI Obsidian on macOS/Linux
- Add getPaperforgePythonCmd() preferring Homebrew/pyenv over Apple CLT Python
- Add tryExecPythonVersion() with multi-candidate fallback for pre-check
- Add scanBbtUnderProfiles() using real Zotero Profiles/extensions/ layout
- Add scanBbtDirectChildren() for safe shallow BBT folder detection
- Add macOS /Applications/Zotero.app and Linux Zotero install detection
- Use paperforgeEnrichedEnv() in setup wizard spawn calls
- Add --user flag to pip install on non-Windows
- Pass PaddleOCR key as --paddleocr-key CLI arg instead of env var
- Add Apple CLT stub Python specific error message in _formatSetupError()
Based on PR #1 by Chartreuse310
Original commit: 156f653 (improve setup modal i18n and update directory defaults)
Co-authored-by: CTZ <yoyflying@163.com>
- Add Runtime Health section in settings showing Plugin vX vs Python vY
- Add match/mismatch badge (green/red) with version comparison
- Add 'Sync Runtime' button that runs pip install --upgrade
- Add Dashboard yellow drift warning banner on version mismatch
- Extend _formatSetupError to 10 categories (pip/network/SSL/disk/Python/etc)
- Add 'Copy diagnostic' button on setup failure with env info
- Add all i18n keys in both en and zh
- Add CSS for badge states, drift banner, and diagnostic button
Part A: All 8 subprocess call sites now use resolvePythonExecutable with
settings and extraArgs propagation for py -3 support:
- _fetchVersion, _fetchStats, _runAction, _preCheck, _runInstall, _stepComplete,
_autoUpdate, command palette
- Zero bare 'python' spawn/exec calls remain
- Spaces-in-path safe via execFile instead of shell-string exec
Part B: zotero_data_dir required with validation:
- field_zotero_placeholder i18n updated to 'Required'/'必填'
- Wizard placeholder uses t() call instead of hardcoded string
- _validateStep3 checks: non-empty -> exists -> isDirectory -> has storage/
- _validate() rejects missing zotero_data_dir with validate_zotero i18n key
- zotero_data_dir always passed to --zotero-data flag (no conditional)
- Add python_path to DEFAULT_SETTINGS for storing manual override path
- Refactor resolvePythonExecutable(vaultPath, settings) to return {path, source, extraArgs}
- Manual override (settings.python_path) bypasses auto-detection when set and exists
- Detection order: manual -> .paperforge-test-venv -> .venv -> venv -> py -3 -> python -> python3
- py -3 detection uses extraArgs for proper launcher argument passing
- Stale override re-validated on plugin load; _python_path_stale flag set without clearing
- Update all existing call sites to destructure .path from new return type
- migrate_to_workspace: preserve legacy flat notes even without canonical index
- migrate_to_workspace: reconcile legacy library-record do_ocr/analyze flags including false overrides
- migrate_to_workspace: handle non-canonical legacy filenames via frontmatter title
- asset_index: only advertise fulltext_path/deep_reading_path when files exist
- asset_index: prefer note frontmatter over legacy library-records, fall back to legacy
- setup_wizard: require Python >=3.10 instead of >=3.8
- plugin main.js: align Python version messaging to 3.10+
- ocr.py: auto_analyze_after_ocr reads from formal note paths, not library-records
- HARDEN-04: Pass PADDLEOCR_API_TOKEN via env var instead of CLI --paddleocr-key
- HARDEN-05: Replace innerHTML with createEl() DOM API for directory tree rendering