fix: close review findings for auto-sync, sync PFResult, and global actions

Remove invalid sync --key path from OCR auto-refresh, surface memory rebuild
failures in sync PFResult instead of swallowing them, and complete the
persistent Global action group with Status + Repair.
This commit is contained in:
Research Assistant 2026-05-16 23:48:34 +08:00
parent f2046e381d
commit cef93fa588
2 changed files with 36 additions and 3 deletions

View file

@ -1766,6 +1766,21 @@ class PaperForgeStatusView extends ItemView {
const action = ACTIONS.find(a => a.id === 'paperforge-doctor');
if (action) this._runAction(action, globalDoctorBtn);
});
const globalStatusBtn = btnsRow.createEl('button', { cls: 'paperforge-contextual-btn' });
globalStatusBtn.createEl('span', { cls: 'paperforge-contextual-btn-icon', text: '\u2139' });
globalStatusBtn.createEl('span', { text: 'Refresh Status' });
globalStatusBtn.addEventListener('click', () => {
this._fetchStats();
});
const globalRepairBtn = btnsRow.createEl('button', { cls: 'paperforge-contextual-btn' });
globalRepairBtn.createEl('span', { cls: 'paperforge-contextual-btn-icon', text: '\u21BA' });
globalRepairBtn.createEl('span', { text: 'Repair Issues' });
globalRepairBtn.addEventListener('click', () => {
const action = ACTIONS.find(a => a.id === 'paperforge-repair');
if (action) this._runAction(action, globalRepairBtn);
});
}
/* ── System Status Row helper ── */
@ -4837,7 +4852,9 @@ module.exports = class PaperForgePlugin extends Plugin {
const pyResult = resolvePythonExecutable(vaultPath, this.settings);
if (!pyResult.path) { this._autoSyncRunning = false; return; }
const cmd = `"${pyResult.path}" -m paperforge --vault "${vaultPath}" sync --key "${entry.name}"`;
// `paperforge sync` has no `--key` selector. Fall back to a full sync
// so OCR state changes still propagate into the canonical index.
const cmd = `"${pyResult.path}" -m paperforge --vault "${vaultPath}" sync`;
exec(cmd, { timeout: 30000, encoding: 'utf-8' }, () => {
this._autoSyncRunning = false;
this._memoryStatusText = null;

View file

@ -257,6 +257,7 @@ class SyncService:
index_count = 0
orphaned = 0
flat_cleaned = 0
memory_rebuild_error: Exception | None = None
if not selection_only:
from paperforge.worker._domain import load_domain_config
@ -297,8 +298,9 @@ class SyncService:
if get_memory_db_path(self.vault).exists():
build_from_index(self.vault)
except Exception:
pass
except Exception as exc:
memory_rebuild_error = exc
logger.error("Failed to rebuild memory DB after sync: %s", exc)
if not json_output:
print(f"index-refresh: {index_count} entries in index")
@ -306,6 +308,8 @@ class SyncService:
print(f"index-refresh: {total} formal note(s) in literature")
all_errors = list(selection_result.get("errors", []))
if memory_rebuild_error is not None:
all_errors.append(f"memory rebuild failed: {memory_rebuild_error}")
is_ok = selection_result.get("failed", 0) == 0 and len(all_errors) == 0
result = PFResult(
@ -321,6 +325,18 @@ class SyncService:
if _export_code != "ok":
result.warnings.append(f"BBT exports: {_export_code}")
if memory_rebuild_error is not None:
result.error = PFError(
code=ErrorCode.SYNC_FAILED,
message=f"Sync completed but memory rebuild failed: {memory_rebuild_error}",
details={"phase": "memory_rebuild", "exception_type": type(memory_rebuild_error).__name__},
suggestions=["Run paperforge memory build to rebuild the memory DB from the cleaned canonical index."],
)
result.next_actions.append({
"command": "paperforge memory build",
"reason": "Rebuild memory DB so it matches the cleaned canonical index",
})
return result
# ── Legacy passthrough (backward-compat for commands/sync.py) ──