# M7.7 — `mem source` CLI | Field | Value | |---|---| | Phase | M7 — Source connectors | | Size | M — 1–3 days | | Status | ⬜ Not started | | Flags | — | | Spec | inlined below | | Blocks | M7.8, M7.10 | | Depends | M7.6 | ## Goal Provide CLI commands to manage source connectors: sync documents, check status, list connectors, add/remove connectors. ## Facts (inlined — no spec read needed) ``` mem source list # all registered connectors + health mem source status # drift report per connector, no mutations mem source sync --all # sync all connectors mem source sync --name homelab-vault # sync one connector mem source sync --name homelab-vault --dry-run # show plan, no mutations mem source add --kind paperless --name docs --config '{"base_url":"...","token":"..."}' mem source rm --name old-source # deregister + tombstone all chunks mem source health # connectivity check per connector ``` **Output format.** CLI outputs human-readable tables by default, `--json` for machine consumption. Example: ``` $ mem source list NAME KIND DOCS LAST SYNC HEALTH homelab-vault obsidian 42 2026-08-26T10:00:00Z ✅ reachable homelab-paperless paperless 127 2026-08-26T09:00:00Z ✅ reachable infra-docs git_repo 18 2026-08-25T20:00:00Z ⚠️ pull failed $ mem source status NAME NEW CHANGED UNCHANGED REMOVED homelab-vault 0 2 40 0 homelab-paperless 3 0 124 0 infra-docs 1 1 16 0 ``` ## Steps 1. Add `Source` subcommand group to clap CLI in `mem-cli/src/main.rs`. 2. Implement `cmd_source_list()` — load registry, health check each, tabulate. 3. Implement `cmd_source_status()` — load registry, run drift report per connector, tabulate. 4. Implement `cmd_source_sync()` — load registry, run sync engine for selected connector(s), report results. 5. Implement `cmd_source_add()` — validate kind, parse config, register in `connectors.yaml`, run initial health check. 6. Implement `cmd_source_rm()` — tombstone all chunks from connector, remove from `connectors.yaml`. 7. Implement `cmd_source_health()` — connectivity check per connector. 8. Add `--dry-run` to sync (show plan only). 9. Add `--json` flag for machine-readable output. ## Acceptance - All subcommands execute without panic. - `sync --dry-run` shows plan without mutations. - `add` validates kind exists in registry before writing config. - `rm` tombstones chunks and removes config entry. - `status` shows drift without mutations. - Exit codes: 0 on success, non-zero on failure. ## Verify **Harness:** `VecConnector` registered in registry, temp connectors.yaml. **Integration test** — `tests/it_source_cli.rs`: 1. `a1_list_shows_connectors` — register two connectors; assert list output contains both names and kinds. 2. `a2_status_shows_drift` — modify connector docs; assert status shows correct new/changed/unchanged/removed counts. 3. `a3_sync_processes_changes` — sync with changes; assert documents processed. 4. `a4_sync_dry_run_no_mutations` — sync --dry-run; assert no log entries written. 5. `a5_add_registers_connector` — add a new connector; assert it appears in list. 6. `a6_add_bad_kind_fails` — add with unknown kind; assert non-zero exit. 7. `a7_rm_tombstones_and_deregisters` — rm a connector; assert tombstone records written and connector removed from list. 8. `a8_health_reports_status` — assert health output includes reachable/unreachable. 9. `a9_json_output` — assert --json flag produces valid JSON. **Command:** `cargo test --test it_source_cli` **False pass:** - Testing `list` without checking that connectors are actually registered (not just config parsed). ## Traps - `sync --all` with a broken connector should not halt all syncs. Sync each independently, report failures per connector at the end. - `rm` without `--yes` should prompt for confirmation (destructive operation). - Don't write `connectors.yaml` atomically — a crash mid-write corrupts config. Write to temp file, then rename. --- Background: [DESIGN.md](../DESIGN.md) — source connectors, CLI commands