@@ -93,6 +95,12 @@ Before running a harvest, the agent MUST verify/edit these fields:
|-------|-----------|-------------|
| `vaultPath` | ✅ Yes | Absolute path to the Obsidian vault root. Must exist and be writable. Replace the template placeholder `/path/to/your/obsidian/vault`. |
| `registryWindowDays` | Optional | Dedup sliding window in days (default `7`). |
| `push.enabled` | Optional | Enable pushing finalized archives to the News Hub backend (default `false`). |
| `push.endpoint` | Optional* | News Hub API base URL, e.g. `http://localhost:8080/api/v1`. *Required when `push.enabled` is `true`. |
| `push.batchSize` | Optional | Articles per push batch (default `10`, API max 10). |
| `push.autoPushAfterFinalize` | Optional | When `true` (default), `finalize.js` auto-chains into `push.js`. Set `false` to push manually only. |
| `push.retry` | Optional | `{ maxAttempts, baseDelayMs }` for exponential backoff on 5xx/network errors (defaults `5` / `1000`). |
| `chromium.cdpPort` | Optional | CDP debug port (default `9222`). Only relevant for `browser` sources. |
| `chromium.headless` | Optional | Launch headless (`true`, default) or with a window (`false`). Set `false` if a site's anti-bot detects headless. |
| `chromium.executablePath` | Optional | Full path to the browser binary. Set only if auto-discovery fails (non-standard install location). `null` = auto-discover. |
This writes each `<中文标题>.md`, patches the sentinel links in the 原文.md files, updates `registry.json` + `index.md` with real titles, and removes `.manifest.json` + `.summaries.json`.
> **Auto-push (optional).** If `config.push.enabled` is `true`, finalize automatically chains into `push.js`, which uploads the day directory to the News Hub backend (images to MinIO via `POST /assets`, then articles via `POST /articles`). A push failure **never** aborts finalize — the local archive is already complete; re-push with `node scripts/push.js "<dayDir>"` once the backend is reachable. To push manually instead, set `push.autoPushAfterFinalize: false`.
### Flow C — Push to News Hub (finalize → remote sync)
After a day directory is finalized, push it to the News Hub backend:
```bash
node scripts/push.js "<dayDir>" # push (resumes from failures via .syncstate.json)
node scripts/push.js "<dayDir>" --status # read-only sync status report
node scripts/push.js "<dayDir>" --force # ignore ledger, re-push all articles
```
`push.js` reads `registry.json` for metadata, parses each 原文.md / 摘要.md (markdown + the four summary sections), uploads images to MinIO (SHA-256 deduped), and batch-pushes articles (≤10/batch, idempotent via `Idempotency-Key`). It writes a `.syncstate.json` ledger per day directory so re-running resumes only failed/missing articles. Exit code `2` means partial failure (some articles still in error). See the backend API at `news-hub/docs/API.md`.
### Flow B — Preview (read-only, no archive)
For "返回最新文章数据" / "看看最新文章" requests where the user does **not** ask to save: