Files
gitlore/plans/init-refresh-flag.md
teernisse 571c304031 feat(init): add --refresh flag for project re-registration
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)
2026-03-02 15:23:41 -05:00

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:

  • --refresh flag (conflicts with --force)
  • Ensure --robot / -J propagates 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 --refresh to register new projects from config
  • Use --force to 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

  1. src/cli/mod.rs — add --refresh and --robot to init subcommand args
  2. src/cli/commands/init.rs — add RefreshResult, run_init_refresh(), update error message
  3. src/main.rs (or CLI dispatch) — route --refresh to new function

Acceptance Criteria

  • lore init --refresh reads 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 --refresh when config exists
  • --refresh and --force are mutually exclusive