When new projects are added to the config file, `lore sync` doesn't pick them up because project discovery only happens during `lore init`. Previously, users had to use `--force` to overwrite their entire config. The new `--refresh` flag reads the existing config and updates the database to match, without modifying the config file itself. Features: - Validates GitLab authentication before processing - Registers new projects from config into the database - Detects orphan projects (in DB but removed from config) - Interactive mode: prompts to delete orphans (default: No) - Robot mode: returns JSON with orphan info, no prompts Usage: lore init --refresh # Interactive lore --robot init --refresh # JSON output Improved UX: When running `lore init` with an existing config and no flags, the error message now suggests using `--refresh` to register new projects or `--force` to overwrite the config file. Implementation: - Added RefreshOptions and RefreshResult types to init module - Added run_init_refresh() for core refresh logic - Added delete_orphan_projects() helper for orphan cleanup - Added handle_init_refresh() in main.rs for CLI handling - Added JSON output types for robot mode - Registered --refresh in autocorrect.rs command flags registry - --refresh conflicts with --force (mutually exclusive)
3.6 KiB
3.6 KiB
Plan: lore init --refresh
Created: 2026-03-02 Status: Complete
Problem
When new repos are added to the config file, lore sync doesn't pick them up because project discovery only happens during lore init. Currently, users must use --force to overwrite their config, which is awkward.
Solution
Add --refresh flag to lore init that reads the existing config and updates the database to match, without overwriting the config file.
Implementation Plan
1. CLI Changes (src/cli/mod.rs)
Add to init subcommand:
--refreshflag (conflicts with--force)- Ensure
--robot/-Jpropagates to init
2. Update InitOptions struct
pub struct InitOptions {
pub config_path: Option<String>,
pub force: bool,
pub non_interactive: bool,
pub refresh: bool, // NEW
pub robot_mode: bool, // NEW
}
3. New RefreshResult struct
pub struct RefreshResult {
pub user: UserInfo,
pub projects_registered: Vec<ProjectInfo>,
pub projects_failed: Vec<ProjectFailure>, // path + error message
pub orphans_found: Vec<String>, // paths in DB but not config
pub orphans_deleted: Vec<String>, // if user said yes
}
pub struct ProjectFailure {
pub path: String,
pub error: String,
}
4. Main logic: run_init_refresh() (new function)
1. Load config via Config::load()
2. Resolve token, call get_current_user() → validate auth
3. For each project in config.projects:
- Call client.get_project(path)
- On success: collect for DB upsert
- On failure: collect in projects_failed
4. Query DB for all existing projects
5. Compute orphans = DB projects - config projects
6. If orphans exist:
- Robot mode: include in output, no prompt, no delete
- Interactive: prompt "Delete N orphan projects? [y/N]"
- Default N → skip deletion
- Y → delete from DB
7. Upsert validated projects into DB
8. Return RefreshResult
5. Improve existing init error message
In run_init(), when config exists and neither --refresh nor --force:
Current:
Config file exists at ~/.config/lore/config.json. Use --force to overwrite.
New:
Config already exists at ~/.config/lore/config.json.
- Use
--refreshto register new projects from config- Use
--forceto overwrite the config file
6. Robot mode output
{
"ok": true,
"data": {
"mode": "refresh",
"user": { "username": "...", "name": "..." },
"projects_registered": [...],
"projects_failed": [...],
"orphans_found": ["old/project"],
"orphans_deleted": []
},
"meta": { "elapsed_ms": 123 }
}
7. Human output
✓ Authenticated as @username (Full Name)
Projects
✓ group/project-a registered
✓ group/project-b registered
✗ group/nonexistent not found
Orphans
• old/removed-project
Delete 1 orphan project from database? [y/N]: n
Registered 2 projects (1 failed, 1 orphan kept)
Files to Touch
src/cli/mod.rs— add--refreshand--robotto init subcommand argssrc/cli/commands/init.rs— addRefreshResult,run_init_refresh(), update error messagesrc/main.rs(or CLI dispatch) — route--refreshto new function
Acceptance Criteria
lore init --refreshreads existing config and registers projects- Validates GitLab auth before processing
- Orphan projects prompt with default N (interactive mode)
- Robot mode outputs JSON, no prompts, includes orphans in output
- Existing
lore init(no flags) suggests--refreshwhen config exists --refreshand--forceare mutually exclusive