diff --git a/.gitignore b/.gitignore index a675e4d2..c44a0519 100644 --- a/.gitignore +++ b/.gitignore @@ -21,7 +21,7 @@ config.json # Data (user-specific) 99_System/Zotero/ -99_System/LiteraturePipeline/ocr/ +99_System/PaperForge/ocr/ 00_Inbox/ 03_Resources/ diff --git a/AGENTS.md b/AGENTS.md index f26a4db1..ce71dfb9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -21,7 +21,7 @@ 1. Zotero → Edit → Preferences → Better BibTeX 2. 勾选 **"Keep updated"**(自动导出) 3. 选择导出格式:**Better BibLaTeX** 或 **Better BibTeX** -4. 导出路径设置为:`{你的Vault路径}/99_System/LiteraturePipeline/exports/library.json` +4. 导出路径设置为:`{你的Vault路径}/99_System/PaperForge/exports/library.json` 5. 点击 OK,JSON 文件会自动生成并保持同步 --- @@ -47,13 +47,13 @@ PaperForge Lite 采用 **两层设计**: ``` Zotero 添加文献 ↓ Better BibTeX 自动导出 JSON -99_System/LiteraturePipeline/exports/library.json +99_System/PaperForge/exports/library.json ↓ 运行 selection-sync 03_Resources/LiteratureControl/library-records//.md ↓ 运行 index-refresh 03_Resources/Literature// - .md(正式笔记) ↓ 用户在 library-record 中设置 do_ocr: true -运行 ocr → 99_System/LiteraturePipeline/ocr/<key>/ +运行 ocr → 99_System/PaperForge/ocr/<key>/ ↓ 用户在 library-record 中设置 analyze: true 运行 deep-reading(查看队列,确认就绪) ↓ 用户执行 Agent 命令 @@ -114,8 +114,8 @@ Zotero 添加文献 |------|------|------------| | `03_Resources/Literature/` | 正式文献笔记(含 frontmatter + 精读内容) | index-refresh 生成,Agent 写入精读 | | `03_Resources/LiteratureControl/library-records/` | 文献状态跟踪(analyze, ocr_status 等) | selection-sync 生成,用户修改状态 | -| `99_System/LiteraturePipeline/exports/` | Better BibTeX JSON 导出 | Zotero 自动导出 | -| `99_System/LiteraturePipeline/ocr/` | OCR 全文 + 图表切割 | ocr worker 生成 | +| `99_System/PaperForge/exports/` | Better BibTeX JSON 导出 | Zotero 自动导出 | +| `99_System/PaperForge/ocr/` | OCR 全文 + 图表切割 | ocr worker 生成 | | `99_System/Zotero/` | Zotero 数据目录的链接 | 安装时手动创建 junction | --- @@ -128,7 +128,7 @@ Zotero 添加文献 - **输出**:`03_Resources/LiteratureControl/library-records/<domain>/<key>.md` - **示例**: ```bash - python 99_System/LiteraturePipeline/worker/scripts/literature_pipeline.py \ + python 99_System/PaperForge/worker/scripts/literature_pipeline.py \ --vault "{vault路径}" selection-sync ``` @@ -141,7 +141,7 @@ Zotero 添加文献 ### ocr - **作用**:将 PDF 上传到 PaddleOCR API,提取全文文本和图表 - **触发条件**:library-record 中 `do_ocr: true` -- **输出**:`99_System/LiteraturePipeline/ocr/<key>/` 目录 +- **输出**:`99_System/PaperForge/ocr/<key>/` 目录 - `fulltext.md`:提取的全文(含 `<!-- page N -->` 分页标记) - `images/`:自动切割的图表图片 - `meta.json`:OCR 状态(`ocr_status: done/pending/processing/failed`) @@ -201,7 +201,7 @@ doi: "10.xxxx/xxxxx" collection_path: "子分类" # Zotero 子收藏夹路径 has_pdf: true # 是否有 PDF 附件(自动生成) pdf_path: "99_System/Zotero/..." # PDF 相对路径(自动生成) -fulltext_md_path: "99_System/LiteraturePipeline/ocr/..." +fulltext_md_path: "99_System/PaperForge/ocr/..." recommend_analyze: true # 系统推荐精读(有 PDF 时自动设为 true) analyze: false # 【用户控制】是否生成精读?设为 true 触发 do_ocr: true # 【用户控制】是否运行 OCR?设为 true 触发 @@ -249,7 +249,7 @@ pdf_link: "99_System/Zotero/..." ```bash # 在 Vault 根目录执行 -python 99_System/LiteraturePipeline/worker/scripts/literature_pipeline.py \ +python 99_System/PaperForge/worker/scripts/literature_pipeline.py \ --vault "你的Vault路径" selection-sync ``` @@ -263,7 +263,7 @@ python 99_System/LiteraturePipeline/worker/scripts/literature_pipeline.py \ ### Step 3: 运行 index-refresh ```bash -python 99_System/LiteraturePipeline/worker/scripts/literature_pipeline.py \ +python 99_System/PaperForge/worker/scripts/literature_pipeline.py \ --vault "你的Vault路径" index-refresh ``` @@ -285,7 +285,7 @@ python 99_System/LiteraturePipeline/worker/scripts/literature_pipeline.py \ ### Step 5: 运行 OCR ```bash -python 99_System/LiteraturePipeline/worker/scripts/literature_pipeline.py \ +python 99_System/PaperForge/worker/scripts/literature_pipeline.py \ --vault "你的Vault路径" ocr ``` @@ -294,7 +294,7 @@ python 99_System/LiteraturePipeline/worker/scripts/literature_pipeline.py \ ### Step 6: 检查 OCR 状态 ```bash -python 99_System/LiteraturePipeline/worker/scripts/literature_pipeline.py \ +python 99_System/PaperForge/worker/scripts/literature_pipeline.py \ --vault "你的Vault路径" deep-reading ``` @@ -326,23 +326,23 @@ Agent 会自动: ```bash # 检测 Zotero 新条目 -python 99_System/LiteraturePipeline/worker/scripts/literature_pipeline.py \ +python 99_System/PaperForge/worker/scripts/literature_pipeline.py \ --vault "你的Vault路径" selection-sync # 生成/更新正式笔记 -python 99_System/LiteraturePipeline/worker/scripts/literature_pipeline.py \ +python 99_System/PaperForge/worker/scripts/literature_pipeline.py \ --vault "你的Vault路径" index-refresh # 运行 OCR(处理 do_ocr=true 的文献) -python 99_System/LiteraturePipeline/worker/scripts/literature_pipeline.py \ +python 99_System/PaperForge/worker/scripts/literature_pipeline.py \ --vault "你的Vault路径" ocr # 查看精读队列 -python 99_System/LiteraturePipeline/worker/scripts/literature_pipeline.py \ +python 99_System/PaperForge/worker/scripts/literature_pipeline.py \ --vault "你的Vault路径" deep-reading # 查看整体状态 -python 99_System/LiteraturePipeline/worker/scripts/literature_pipeline.py \ +python 99_System/PaperForge/worker/scripts/literature_pipeline.py \ --vault "你的Vault路径" status ``` @@ -364,7 +364,7 @@ python 99_System/LiteraturePipeline/worker/scripts/literature_pipeline.py \ ### Q: OCR 一直显示 pending? - 检查 PaddleOCR API Key 是否配置正确(`.env` 文件) - 检查网络连接 -- 查看 `99_System/LiteraturePipeline/ocr/<key>/meta.json` 中的错误信息 +- 查看 `99_System/PaperForge/ocr/<key>/meta.json` 中的错误信息 ### Q: /LD-deep 提示 OCR 未完成? - 确认 library-record 中 `ocr_status: done` @@ -389,13 +389,13 @@ cd 你的Vault路径 git pull origin main # 或手动复制更新文件 -cp -r 新下载的scripts/* 99_System/LiteraturePipeline/worker/scripts/ +cp -r 新下载的scripts/* 99_System/PaperForge/worker/scripts/ ``` ### 备份注意事项 -- `03_Resources/` 和 `99_System/LiteraturePipeline/ocr/` 包含你的数据,需备份 +- `03_Resources/` 和 `99_System/PaperForge/ocr/` 包含你的数据,需备份 - `.env` 包含 API Key,不要提交到 git -- `99_System/LiteraturePipeline/exports/` 可重新生成(由 Zotero 自动导出) +- `99_System/PaperForge/exports/` 可重新生成(由 Zotero 自动导出) --- diff --git a/command/ld-deep.md b/command/ld-deep.md index ddc97421..c646b929 100644 --- a/command/ld-deep.md +++ b/command/ld-deep.md @@ -8,8 +8,8 @@ 2. 支持 Zotero key、标题片段、DOI、PMID、关键词 3. 优先搜索本地 Zotero 并锁定单篇论文 4. 绑定该论文对应的: - - `99_System/LiteraturePipeline/ocr/<KEY>/fulltext.md` - - `99_System/LiteraturePipeline/ocr/<KEY>/meta.json` + - `99_System/PaperForge/ocr/<KEY>/fulltext.md` + - `99_System/PaperForge/ocr/<KEY>/meta.json` - `03_Resources/Literature/.../KEY - Title.md` 5. 在正式文献卡片中检查或创建 `## 🔍 精读` 6. 以“研究思路 + figure-by-figure”方式一次性完成精读写回 diff --git a/command/lp-index-refresh.md b/command/lp-index-refresh.md index 447e1b1b..3855fcfa 100644 --- a/command/lp-index-refresh.md +++ b/command/lp-index-refresh.md @@ -5,7 +5,7 @@ ## Commands ```bash -python 99_System/LiteraturePipeline/worker/scripts/literature_pipeline.py --vault D:\L\Med\Research index-refresh +python 99_System/PaperForge/worker/scripts/literature_pipeline.py --vault D:\L\Med\Research index-refresh ``` ## 输出示例 diff --git a/command/lp-ocr.md b/command/lp-ocr.md index 12420a3a..11817159 100644 --- a/command/lp-ocr.md +++ b/command/lp-ocr.md @@ -5,5 +5,5 @@ ## Commands ```bash -python 99_System/LiteraturePipeline/worker/scripts/literature_pipeline.py --vault D:\L\Med\Research ocr +python 99_System/PaperForge/worker/scripts/literature_pipeline.py --vault D:\L\Med\Research ocr ``` \ No newline at end of file diff --git a/command/lp-selection-sync.md b/command/lp-selection-sync.md index 1d37cbb9..8cbdf460 100644 --- a/command/lp-selection-sync.md +++ b/command/lp-selection-sync.md @@ -5,5 +5,5 @@ ## Commands ```bash -python 99_System/LiteraturePipeline/worker/scripts/literature_pipeline.py --vault D:\L\Med\Research selection-sync +python 99_System/PaperForge/worker/scripts/literature_pipeline.py --vault D:\L\Med\Research selection-sync ``` \ No newline at end of file diff --git a/command/lp-status.md b/command/lp-status.md index cfb60588..2aef4bf2 100644 --- a/command/lp-status.md +++ b/command/lp-status.md @@ -5,7 +5,7 @@ ## 检查 exports 记录数 ```bash -python -c "import json; from pathlib import Path; data = json.loads(Path('99_System/LiteraturePipeline/exports/骨科.json').read_text('utf-8')); items = [i for i in data.get('items',[]) if i.get('itemType') != 'attachment']; print(f'骨科: {len(items)} records')" +python -c "import json; from pathlib import Path; data = json.loads(Path('99_System/PaperForge/exports/骨科.json').read_text('utf-8')); items = [i for i in data.get('items',[]) if i.get('itemType') != 'attachment']; print(f'骨科: {len(items)} records')" ``` ## 检查 library-records 总数 @@ -17,11 +17,11 @@ python -c "from pathlib import Path; count = sum(1 for _ in Path('03_Resources/L ## 检查 OCR 完成数 ```bash -python -c "from pathlib import Path; done = sum(1 for p in Path('99_System/LiteraturePipeline/ocr').glob('*/meta.json') if 'done' in Path(p).read_text('utf-8')); print(f'OCR done: {done}')" +python -c "from pathlib import Path; done = sum(1 for p in Path('99_System/PaperForge/ocr').glob('*/meta.json') if 'done' in Path(p).read_text('utf-8')); print(f'OCR done: {done}')" ``` ## 检查索引记录数 ```bash -python -c "import json; data = json.load(open('99_System/LiteraturePipeline/indexes/formal-library.json', encoding='utf-8')); print(f'Index: {len(data)} records')" +python -c "import json; data = json.load(open('99_System/PaperForge/indexes/formal-library.json', encoding='utf-8')); print(f'Index: {len(data)} records')" ``` \ No newline at end of file diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index 85903b02..679354cc 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -64,8 +64,8 @@ poetry add requests pymupdf pillow pytest Create the following directories in the Obsidian vault: ```bash -mkdir -p "{vault_path}/99_System/LiteraturePipeline/ocr" -mkdir -p "{vault_path}/99_System/LiteraturePipeline/worker/scripts" +mkdir -p "{vault_path}/99_System/PaperForge/ocr" +mkdir -p "{vault_path}/99_System/PaperForge/worker/scripts" mkdir -p "{vault_path}/99_System/Zotero" mkdir -p "{vault_path}/03_Resources/Literature" mkdir -p "{vault_path}/00_Inbox" @@ -113,7 +113,7 @@ Copy the following files from the repository to your vault: ```bash # Copy scripts -cp -r scripts/* "{vault_path}/99_System/LiteraturePipeline/worker/scripts/" +cp -r scripts/* "{vault_path}/99_System/PaperForge/worker/scripts/" # Copy templates cp -r templates/* "{vault_path}/99_System/Template/" @@ -130,7 +130,7 @@ Run validation: ```bash cd "{vault_path}" -python 99_System/LiteraturePipeline/worker/scripts/validate_setup.py +python 99_System/PaperForge/worker/scripts/validate_setup.py ``` This checks: @@ -170,7 +170,7 @@ Edit `{vault_path}/AGENTS.md`: 3. **Verify**: ```bash - python 99_System/LiteraturePipeline/worker/scripts/validate_setup.py + python 99_System/PaperForge/worker/scripts/validate_setup.py ``` --- diff --git a/docs/setup-guide.md b/docs/setup-guide.md index 3516a212..c214e7ec 100644 --- a/docs/setup-guide.md +++ b/docs/setup-guide.md @@ -118,7 +118,7 @@ Zotero ├─ 格式(Format): Better BibLaTeX ★ 重要!不是 BibTeX ├─ 勾选 [Keep updated] ★ 必须勾选 ├─ 文件名: 骨科.json ★ 建议用中文名,好识别 - └─ 保存位置: {你的Vault}/99_System/LiteraturePipeline/exports/ + └─ 保存位置: {你的Vault}/99_System/PaperForge/exports/ └─ [保存] ``` @@ -130,7 +130,7 @@ Zotero 4. 勾选右下角的 `Keep updated` 5. 点击 `...` 选择保存位置,导航到: ``` - {你的Vault根目录}/99_System/LiteraturePipeline/exports/ + {你的Vault根目录}/99_System/PaperForge/exports/ ``` 6. 文件名填写收藏夹名称,如 `骨科.json` 7. 点击保存 @@ -142,7 +142,7 @@ Zotero 导出完成后,检查文件: ```bash -ls 99_System/LiteraturePipeline/exports/ +ls 99_System/PaperForge/exports/ # 应该看到: 骨科.json 运动医学.json ... ``` diff --git a/paperforge.json b/paperforge.json index a012c56c..f02335e7 100644 --- a/paperforge.json +++ b/paperforge.json @@ -11,10 +11,10 @@ "protected_paths": [ "03_Resources/", "05_Bases/", - "99_System/LiteraturePipeline/ocr/", - "99_System/LiteraturePipeline/exports/", - "99_System/LiteraturePipeline/indexes/", - "99_System/LiteraturePipeline/candidates/", + "99_System/PaperForge/ocr/", + "99_System/PaperForge/exports/", + "99_System/PaperForge/indexes/", + "99_System/PaperForge/candidates/", ".env", "AGENTS.md" ], diff --git a/pipeline/worker/scripts/literature_pipeline.py b/pipeline/worker/scripts/literature_pipeline.py index db54af4b..8d00d774 100644 --- a/pipeline/worker/scripts/literature_pipeline.py +++ b/pipeline/worker/scripts/literature_pipeline.py @@ -1175,7 +1175,7 @@ def ensure_ocr_meta(vault: Path, row: dict) -> dict: meta.setdefault('page_count', 0) meta.setdefault('markdown_path', '') meta.setdefault('json_path', '') - meta.setdefault('assets_path', f'99_System/LiteraturePipeline/ocr/{key}/images') + meta.setdefault('assets_path', f'99_System/PaperForge/ocr/{key}/images') meta.setdefault('fulltext_md_path', '') meta.setdefault('error', '') return meta @@ -2385,10 +2385,10 @@ GITHUB_ZIP = f"https://github.com/{GITHUB_REPO}/archive/refs/heads/master.zip" PROTECTED_PATHS = { "03_Resources", "05_Bases", - "99_System/LiteraturePipeline/ocr", - "99_System/LiteraturePipeline/exports", - "99_System/LiteraturePipeline/indexes", - "99_System/LiteraturePipeline/candidates", + "99_System/PaperForge/ocr", + "99_System/PaperForge/exports", + "99_System/PaperForge/indexes", + "99_System/PaperForge/candidates", ".env", "AGENTS.md", } UPDATEABLE_PATHS = ["skills", "pipeline", "templates", "command", "scripts"] diff --git a/scripts/setup.py b/scripts/setup.py index 19f6228e..c1c1dd47 100644 --- a/scripts/setup.py +++ b/scripts/setup.py @@ -115,7 +115,7 @@ def configure_vault_paths(vault_path: Path) -> dict: } # Build derived paths - paths["pipeline_path"] = f"{paths['system_dir']}/LiteraturePipeline" + paths["pipeline_path"] = f"{paths['system_dir']}/PaperForge" paths["template_path"] = f"{paths['system_dir']}/Template" paths["literature_path"] = f"{paths['resources_dir']}/{paths['literature_dir']}" @@ -401,7 +401,7 @@ Zotero 添加文献 │ └── HIJKLMN.md │ ├── {paths['system_dir']}/ -│ ├── LiteraturePipeline/ +│ ├── PaperForge/ │ │ ├── exports/ ← Better BibTeX 自动导出的 JSON │ │ │ └── library.json │ │ ├── ocr/ ← OCR 结果(每个文献一个子目录) diff --git a/setup_wizard.py b/setup_wizard.py index b0621e5a..e53dde7d 100644 --- a/setup_wizard.py +++ b/setup_wizard.py @@ -72,6 +72,7 @@ class EnvChecker: def __init__(self, vault: Path): self.vault = vault self.manual_zotero_path: Optional[Path] = None + self.system_dir: str = "99_System" # 可由用户自定义 self.results: dict[str, CheckResult] = { "python": CheckResult("Python 版本"), "vault": CheckResult("Vault 结构"), @@ -80,6 +81,10 @@ class EnvChecker: "json": CheckResult("JSON 导出"), } + def get_exports_dir(self) -> Path: + """Get exports directory based on user config.""" + return self.vault / self.system_dir / "PaperForge" / "exports" + def check_python(self) -> CheckResult: r = self.results["python"] v = sys.version_info @@ -121,10 +126,8 @@ class EnvChecker: def check_vault(self) -> CheckResult: r = self.results["vault"] required = [ - "03_Resources/LiteratureControl/library-records", - "99_System/LiteraturePipeline/exports", - "99_System/LiteraturePipeline/ocr", - "99_System/Template", + f"{self.system_dir}/PaperForge/exports", + f"{self.system_dir}/PaperForge/ocr", ] missing = [rel for rel in required if not (self.vault / rel).exists()] if not missing: @@ -135,6 +138,12 @@ class EnvChecker: r.detail = f"缺少: {', '.join(missing)}" r.action_required = True return r + r.detail = "所有必要目录已就绪" + else: + r.passed = False + r.detail = f"缺少: {', '.join(missing)}" + r.action_required = True + return r def _find_zotero(self, manual_path: Optional[Path] = None) -> Optional[Path]: # 如果提供了手动路径,优先使用 @@ -283,7 +292,7 @@ class EnvChecker: def check_json(self) -> CheckResult: r = self.results["json"] - exports_dir = self.vault / "99_System" / "LiteraturePipeline" / "exports" + exports_dir = self.get_exports_dir() if not exports_dir.exists(): r.passed = False r.detail = f"导出目录不存在: {exports_dir}" @@ -489,9 +498,8 @@ PaperForge 的目录结构可以自定义。你可以保留默认名称,也可 {vault_path.name}/ ├── 03_Resources/ ← 文献笔记和资源 │ └── LiteratureControl/ ← 状态跟踪 -├── 99_System/ ← 系统文件 -│ ├── LiteraturePipeline/ ← 导出和 OCR -│ └── Template/ ← 模板 +└── 99_System/ ← 系统文件 + └── PaperForge/ ← 导出和 OCR ``` 修改下方名称(留空使用默认值): @@ -504,7 +512,7 @@ PaperForge 的目录结构可以自定义。你可以保留默认名称,也可 yield Static("文献子文件夹名称:", classes="step-title") yield Input(value="Literature", id="input-literature-dir") yield Horizontal( - Button("🔍 检测并创建目录", id="btn-setup-vault", variant="primary"), + Button("✓ 确认并创建目录", id="btn-setup-vault", variant="primary"), id="btn-row", ) @@ -520,18 +528,16 @@ PaperForge 的目录结构可以自定义。你可以保留默认名称,也可 "system_dir": system_dir, "resources_dir": resources_dir, "literature_dir": literature_dir, - "pipeline_path": f"{system_dir}/LiteraturePipeline", - "template_path": f"{system_dir}/Template", + "paperforge_path": f"{system_dir}/PaperForge", "literature_path": f"{resources_dir}/{literature_dir}", } - # 创建目录 + # 创建目录(使用 PaperForge 作为统一子目录) vault = self.checker.vault dirs_to_create = [ vault / resources_dir / "LiteratureControl" / "library-records", - vault / system_dir / "LiteraturePipeline" / "exports", - vault / system_dir / "LiteraturePipeline" / "ocr", - vault / system_dir / "Template", + vault / system_dir / "PaperForge" / "exports", + vault / system_dir / "PaperForge" / "ocr", ] created = [] @@ -539,7 +545,10 @@ PaperForge 的目录结构可以自定义。你可以保留默认名称,也可 d.mkdir(parents=True, exist_ok=True) created.append(str(d.relative_to(vault))) - self.set_status(f"已创建 {len(created)} 个目录", True) + # 同步更新 checker 的 system_dir + self.checker.system_dir = system_dir + + self.set_status(f"已创建 {len(created)} 个目录: {', '.join(created)}", True) self.app.post_message(StepPassed(self.step_idx)) @@ -660,21 +669,23 @@ class BBTStep(StepScreen): class JsonStep(StepScreen): - """Step 6: JSON Export""" + """Step 5: JSON 导出配置""" def compose(self) -> ComposeResult: yield from super().compose() - exports_dir = self.checker.vault / "99_System" / "LiteraturePipeline" / "exports" + vault = self.checker.vault + system_dir = getattr(self.app, 'vault_config', {}).get('system_dir', '99_System') + exports_dir = vault / system_dir / "PaperForge" / "exports" yield Markdown(f""" **Better BibTeX 自动导出**是 PaperForge 的数据来源。 **配置步骤:** 1. Zotero → 文件 → 导出库... 2. 格式选择 **Better BibLaTeX** -3. 保存到:`{exports_dir}/library.json` +3. 保存到:`{exports_dir}` 4. 勾选 **Keep updated**(自动保持更新) -**📁 子分类与 Base 管理** +📁 **子分类与 Base 管理** 你可以根据 Zotero 收藏夹结构,灵活决定如何导出: @@ -701,7 +712,6 @@ Zotero 收藏夹结构 """) yield Horizontal( Button("🔍 自动检测", id="btn-check-json", variant="primary"), - Button("📷 查看配置截图", id="btn-img-json", variant="default"), id="btn-row", ) @@ -711,8 +721,6 @@ Zotero 收藏夹结构 self.set_status(result.detail, result.passed) if result.passed: self.app.post_message(StepPassed(self.step_idx)) - elif event.button.id == "btn-img-json": - self.app.open_screenshot("json-export.png") class DeployStep(StepScreen): @@ -749,6 +757,9 @@ class DeployStep(StepScreen): def _deploy(self) -> bool: """Deploy scripts and create config files.""" vault = self.checker.vault + vault_config = getattr(self.app, 'vault_config', {}) + system_dir = vault_config.get('system_dir', '99_System') + resources_dir = vault_config.get('resources_dir', '03_Resources') # 1. 获取 agent 配置 agent_config = getattr(self.app, 'agent_config', None) @@ -758,12 +769,15 @@ class DeployStep(StepScreen): skill_dir = agent_config.get('skill_dir', '.opencode/skills') - # 2. 创建目录 + # 2. 创建目录(使用用户自定义路径) + pf_path = vault / system_dir / "PaperForge" dirs = [ + pf_path / "exports", + pf_path / "ocr", + vault / resources_dir / "LiteratureControl" / "library-records", vault / "pipeline/worker/scripts", vault / skill_dir / "literature-qa/scripts", vault / skill_dir / "literature-qa/chart-reading", - vault / "99_System/Template", ] for d in dirs: d.mkdir(parents=True, exist_ok=True) @@ -802,7 +816,7 @@ PADDLEOCR_API_KEY=your_api_key_here PADDLEOCR_API_URL=https://api.paddleocr.com/ocr """, encoding="utf-8") - # 5. 创建 paperforge.json + # 5. 创建 paperforge.json(包含用户自定义路径) pf_json = vault / "paperforge.json" if not pf_json.exists(): import json @@ -810,8 +824,42 @@ PADDLEOCR_API_URL=https://api.paddleocr.com/ocr "version": "1.0.0", "agent_platform": agent_config.get('name', 'OpenCode'), "skill_dir": skill_dir, + "system_dir": system_dir, + "resources_dir": resources_dir, + "paperforge_path": f"{system_dir}/PaperForge", }, indent=2, ensure_ascii=False), encoding="utf-8") + # 6. 验证文件完整性 + self.set_status("验证文件完整性...", None) + checks = { + "Worker 脚本": worker_dst.exists(), + "精读脚本": ld_dst.exists(), + "目录结构": (vault / resources_dir / "LiteratureControl" / "library-records").exists(), + "导出目录": (pf_path / "exports").exists(), + "OCR 目录": (pf_path / "ocr").exists(), + } + + missing = [k for k, v in checks.items() if not v] + if missing: + self.set_status(f"验证失败: {', '.join(missing)}", False) + return False + + self.set_status("文件验证通过,初始化系统...", True) + + # 7. 运行初始化命令(模拟测试) + try: + # 测试 selection-sync(会报错因为没 JSON,但测试脚本能否运行) + result = subprocess.run( + [sys.executable, str(worker_dst), "--vault", str(vault), "status"], + capture_output=True, text=True, timeout=10, + ) + if result.returncode == 0: + self.set_status("工作流脚本运行正常", True) + else: + self.set_status(f"脚本测试警告: {result.stderr[:100]}", None) + except Exception as e: + self.set_status(f"脚本测试跳过: {e}", None) + return True diff --git a/skills/literature-qa/prompt_deep_subagent.md b/skills/literature-qa/prompt_deep_subagent.md index ff3b7b05..4cb321c0 100644 --- a/skills/literature-qa/prompt_deep_subagent.md +++ b/skills/literature-qa/prompt_deep_subagent.md @@ -36,8 +36,8 @@ python {{SCRIPT}} prepare {{ZOTERO_KEY}} --vault "{{VAULT}}" --format text - 这说明该论文已经精读过。如果用户要求重新精读,通知主 agent 确认是否覆盖。 **prepare 成功后会自动生成以下文件**: -- `99_System/LiteraturePipeline/ocr/{{ZOTERO_KEY}}/figure-map.json` — 图表清单 -- `99_System/LiteraturePipeline/ocr/{{ZOTERO_KEY}}/chart-type-map.json` — 图表类型与推荐指南 +- `99_System/PaperForge/ocr/{{ZOTERO_KEY}}/figure-map.json` — 图表清单 +- `99_System/PaperForge/ocr/{{ZOTERO_KEY}}/chart-type-map.json` — 图表类型与推荐指南 **Agent 需要读取 chart-type-map.json**,为每张 figure 建立 `chart_types` 备忘列表。在 Pass 2 解析该 figure 时,根据其 chart_types 读取 `{{CHART_READING_DIR}}` 下对应的 chart-reading 指南,将关键审查问题整合进"图表质量审查"段落。 diff --git a/update.py b/update.py index fb71379c..b7d084a3 100644 --- a/update.py +++ b/update.py @@ -50,10 +50,10 @@ if sys.platform == "win32": # 用户数据保护清单(绝不动这些路径) PROTECTED_PATHS = { "03_Resources", "05_Bases", - "99_System/LiteraturePipeline/ocr", - "99_System/LiteraturePipeline/exports", - "99_System/LiteraturePipeline/indexes", - "99_System/LiteraturePipeline/candidates", + "99_System/PaperForge/ocr", + "99_System/PaperForge/exports", + "99_System/PaperForge/indexes", + "99_System/PaperForge/candidates", ".env", "AGENTS.md", }