# Multi-Project Ergonomics - **Confidence:** 90% - **Tier:** 1 - **Status:** proposed - **Effort:** medium (multiple small improvements that compound) ## The Problem Every command that touches project-scoped data requires `-p group/subgroup/project` to disambiguate. For users with 5+ projects synced, this is: - Repetitive: typing `-p infra/platform/auth-service` on every query - Error-prone: mistyping long paths - Discoverable only by failure: you don't know you need `-p` until you hit an ambiguous error The fuzzy matching in `resolve_project` is already good (suffix, substring, case-insensitive) but it only kicks in on the `-p` value itself. There's no way to set a default, group projects, or scope a whole session. ## Proposed Improvements ### 1. Project Aliases in Config Let users define short aliases for long project paths. ```json { "projects": [ { "path": "infra/platform/auth-service", "alias": "auth" }, { "path": "infra/platform/billing-service", "alias": "billing" }, { "path": "frontend/customer-portal", "alias": "portal" }, { "path": "frontend/admin-dashboard", "alias": "admin" } ] } ``` Then: `lore issues -p auth` resolves via alias before falling through to fuzzy match. **Implementation:** Add optional `alias` field to `ProjectConfig`. In `resolve_project`, check aliases before the existing exact/suffix/substring cascade. ```rust #[derive(Debug, Clone, Deserialize)] pub struct ProjectConfig { pub path: String, #[serde(default)] pub alias: Option, } ``` Resolution order becomes: 1. Exact alias match (new) 2. Exact path match 3. Case-insensitive path match 4. Suffix match 5. Substring match ### 2. Default Project (`LORE_PROJECT` env var) Set a default project for your shell session so you don't need `-p` at all. ```bash export LORE_PROJECT=auth lore issues # scoped to auth-service lore mrs --state opened # scoped to auth-service lore search "timeout bug" # scoped to auth-service lore issues -p billing # explicit -p overrides the env var ``` **Implementation:** In every command that accepts `-p`, fall back to `std::env::var("LORE_PROJECT")` when the flag is absent. The `-p` flag always wins. Could also support a config-level default: ```json { "defaultProject": "auth" } ``` Precedence: CLI flag > env var > config default > (no filter). ### 3. `lore use ` — Session Context Switcher A command that sets `LORE_PROJECT` for the current shell by writing to a dotfile. ```bash lore use auth # writes ~/.local/state/lore/current-project containing "auth" lore issues # reads current-project file, scopes to auth lore use --clear # removes the file, back to all-project mode lore use # shows current project context ``` This is similar to `kubectl config use-context`, `nvm use`, or `tfenv use`. **Implementation:** Write a one-line file at a known state path. Each command reads it as the lowest-priority default (below env var and CLI flag). Precedence: CLI flag > env var > `lore use` state file > config default > (no filter). ### 4. `lore projects` — Project Listing and Discovery A dedicated command to see what's synced, with aliases and activity stats. ```bash $ lore projects Alias Path Issues MRs Last Sync auth infra/platform/auth-service 142 87 2h ago billing infra/platform/billing-service 56 34 2h ago portal frontend/customer-portal 203 112 2h ago admin frontend/admin-dashboard 28 15 3d ago - data/ml-pipeline 89 45 2h ago ``` Robot mode returns the same as JSON with alias, path, counts, and last sync time. **Implementation:** Query `projects` joined with `COUNT(issues)`, `COUNT(mrs)`, and `MAX(sync_runs.finished_at)`. Overlay aliases from config. ### 5. Project Groups in Config Let users define named groups of projects for batch scoping. ```json { "projectGroups": { "backend": ["auth", "billing", "data/ml-pipeline"], "frontend": ["portal", "admin"], "all-infra": ["auth", "billing"] } } ``` Then: `lore issues -p @backend` (or `--group backend`) queries across all projects in the group. **Implementation:** When `-p` value starts with `@`, look up the group and resolve each member project. Pass as a `Vec` of project IDs to the query layer. This is especially powerful for: - `lore search "auth bug" -p @backend` — search across related repos - `lore digest --since 7d -p @frontend` — team-scoped activity digest - `lore timeline "deployment" -p @all-infra` — cross-repo timeline ### 6. Git-Aware Project Detection When running `lore` from inside a git repo that matches a synced project, auto-scope to that project without any flags. ```bash cd ~/code/auth-service lore issues # auto-detects this is infra/platform/auth-service ``` **Implementation:** Read `.git/config` for the remote URL, extract the project path, check if it matches a synced project. Only activate when exactly one project matches. Detection logic: ``` 1. Check if cwd is inside a git repo (find .git) 2. Parse git remote origin URL 3. Extract path component (e.g., "infra/platform/auth-service.git" → "infra/platform/auth-service") 4. Match against synced projects 5. If exactly one match, use as implicit -p 6. If ambiguous or no match, do nothing (fall through to normal behavior) ``` Precedence: CLI flag > env var > `lore use` > config default > git detection > (no filter). This is similar to how `gh` (GitHub CLI) auto-detects the repo you're in. ### 7. Prompt Integration / Shell Function Provide a shell function that shows the current project context in the prompt. ```bash # In .bashrc / .zshrc eval "$(lore completions zsh)" PROMPT='$(lore-prompt)%~ %# ' ``` Output: `[lore:auth] ~/code/auth-service %` Shows which project `lore` commands will scope to, using the same precedence chain. Helps users understand what context they're in before running a query. ### 8. Short Project References in Output Once aliases exist, use them everywhere in output for brevity: **Before:** ``` infra/platform/auth-service#42 Login timeout bug infra/platform/auth-service!234 Refactor auth middleware ``` **After:** ``` auth#42 Login timeout bug auth!234 Refactor auth middleware ``` With `--full-paths` flag to get the verbose form when needed. ## Combined UX Flow With all improvements, a typical session looks like: ```bash # One-time config lore init # sets up aliases during interactive setup # Daily use lore use auth # set context lore issues --state opened # no -p needed lore search "timeout" # scoped to auth lore timeline "login flow" # scoped to auth lore issues -p @backend # cross-repo query via group lore mrs -p billing # quick alias switch lore use --clear # back to global ``` Or for the power user who never wants to type `lore use`: ```bash cd ~/code/auth-service lore issues # git-aware auto-detection ``` Or for the scripter: ```bash LORE_PROJECT=auth lore --robot issues -n 50 # env var for automation ``` ## Priority Order Implement in this order for maximum incremental value: 1. **Project aliases** — smallest change, biggest daily friction reduction 2. **`LORE_PROJECT` env var** — trivial to implement, enables scripting 3. **`lore projects` command** — discoverability, completes the alias story 4. **`lore use` context** — nice-to-have for heavy users 5. **Project groups** — high value for multi-repo teams 6. **Git-aware detection** — polish, "it just works" feel 7. **Short refs in output** — ties into timeline issue #001 8. **Prompt integration** — extra polish ## Relationship to Issue #001 The timeline entity-ref ambiguity (issue #001) is solved naturally by items 7 and 8 here. Once aliases exist, `format_entity_ref` can use the alias as the short project identifier in multi-project output: ``` auth#42 instead of infra/platform/auth-service#42 ``` And in single-project timelines (detected via `lore use` or git-aware), the project prefix is omitted entirely — matching the current behavior but now intentionally.