feat: cherry-pick skills/commands/agents/MCPs on install (#119)#123
feat: cherry-pick skills/commands/agents/MCPs on install (#119)#123SecKatie wants to merge 9 commits into
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughThis pull request implements cherry-pick functionality for module item installation and updates. Users can now selectively install specific skills, commands, agents, and MCPs via CLI flags or an interactive multi-select prompt, rather than always installing complete modules. Installations are tracked with a ChangesCherry-Pick Module Item Installation and Update
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/lola/cli/install.py`:
- Around line 392-403: The _resolve_update_items function is incorrectly
comparing upstream module_items to installed artifact names (inst_items), which
fails for cherry-picked/renamed installs (e.g., inst.skills, inst.commands,
inst.agents) and causes renamed items to be orphaned; modify the logic so that
when ctx.inst.full_install is False you compare module_items against the
persisted source IDs (not the installed names) — either add/use a
source→installed mapping on the instance (e.g., inst.source_map or
inst._source_ids) that maps upstream names to installed names and check
membership against that mapping’s keys, or store a source_name field per
installed artifact and use that for the set lookup instead of inst_items; update
any code that populates inst_items (installation/registration flow) to persist
the source mapping so _resolve_update_items can reference it.
- Around line 1528-1538: The full_install branch indiscriminately replaces
inst.agents and inst.mcps with ctx.current_agents/current_mcps even when
_update_agents()/_update_mcps() returned early; change the assignments so you
only adopt upstream (current_*) values when the corresponding
ctx.installed_agents or ctx.installed_mcps indicate an actual update (i.e., are
truthy or non-empty); otherwise leave inst.agents and inst.mcps as they were in
the registry. Keep inst.commands using ctx.current_commands as before, but for
agents and mcps check ctx.installed_agents and ctx.installed_mcps before
assigning to inst.agents and inst.mcps.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 5ca31da7-f808-4db4-881f-13c8be6e3fc8
📒 Files selected for processing (6)
src/lola/cli/install.pysrc/lola/models.pysrc/lola/prompts.pysrc/lola/targets/install.pytests/test_cli_install.pytests/test_cli_install_cherry_pick.py
Add Vercel-style item selection to `lola install`. Users can now opt out of skills, commands, agents, or MCPs they don't want without forking the module. - New CLI flags: --skill / --command / --agent / --mcp (each repeatable and comma-separated) plus -y/--yes to skip the picker. - Interactive picker in TTY mode: a single checkbox listing every item with type prefixes and "All" pre-selected at the top. - Installation.full_install flag locks cherry-picked installs to the original selection on `lola update` — newly-upstream items are not silently picked up. Full installs continue to track upstream. - Legacy installed.yml entries load as full_install=True; the field is only emitted to YAML when False. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace the checkbox+sentinel "All" item with a fuzzy-searchable multi-select. Pressing Enter with nothing toggled installs everything, which removes the UI inconsistency where the "All" pseudo-item could not be auto-deselected when picking specific items. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
28ba5ae to
e016526
Compare
InquirerPy's fuzzy multiselect returns the currently-highlighted item on Enter when nothing is tab-toggled, so the picker's "Enter with no selection = all" path was unreachable and pressing Enter installed only one item. Drop the dead branch and advertise the inherited Alt-A toggle-all-true keybinding in long_instruction. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds cherry-pick support to lola install (via new CLI filters and an interactive picker) and updates lola update behavior to either keep tracking upstream (full installs) or lock to the originally selected subset (cherry-picked installs), persisting the needed state in installed.yml.
Changes:
- Add
--skill/--command/--agent/--mcp(repeatable + CSV) and-y/--yesto control non-interactive vs. interactive install selection. - Track cherry-picked vs full installs with
Installation.full_installplus per-item source mapping fields to preserve rename/conflict resolutions. - Update install/update pipelines to filter installs by selection and prevent cherry-picked updates from silently expanding to newly upstream items.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_cli_install.py | Updates existing interactive install tests to bypass the new module-item picker via -y. |
| tests/test_cli_install_cherry_pick.py | Adds coverage for CSV expansion, picker parsing, cherry-pick filtering, and update locking behavior. |
| src/lola/targets/install.py | Adds selection filtering + source maps during install; plumbs selection into install pipeline and records full_install. |
| src/lola/prompts.py | Introduces the fuzzy multi-select prompt for choosing module items to install. |
| src/lola/models.py | Extends Installation persistence with full_install and per-category *_sources mappings. |
| src/lola/cli/install.py | Adds CLI flags, selection resolution, and update logic intended to respect cherry-picked installs and renames. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Just gave this a shot and ended up not being able to navigate back up the tree once I started exploring. I had hacked together something at https://github.com/trevor-vaughan/lobstertrap-lola/tree/feat/cherry-pick that does (roughly) what I want but I like the multi-level menu experience. Happy to open a PR (or you can steal whatever you like). |
Replace the single cherry-pick picker with an "all vs choose items" prompt so full installs don't require visiting the picker, and fix update to keep identity-mapped picks and renamed registry entries when reloading from disk. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@trevor-vaughan I'll take a look! |
Adds `instructions: AGENTS.md` as a togglable entry in the interactive picker, and a `--instructions/--no-instructions` CLI flag. When any cherry-pick flag is passed, instructions are skipped unless `--instructions` is also supplied — making opt-in explicit and aligning the summary line with what was actually installed. Full install (`lola install <mod>` with no flags and no picker) is unchanged. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Fresh installs now start with every picker entry unchecked instead of checked, so confirming without explicit picks doesn't sweep in everything. Alt-A (and Ctrl-A) rebind from "select all" to "toggle all" so a single keystroke flips every visible item — useful both for selecting everything in one go on a fresh install and for clearing the pre-selected set on re-install. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…mapped picker items
Two bugs surfaced in manual testing of the cherry-pick install flow:
1. Cherry-picked installs that opted out of instructions silently picked
them up on `lola update` whenever upstream gained an AGENTS.md.
`_update_instructions` now respects `full_install=False` +
`has_instructions=False` and removes any stray instructions instead of
regenerating them.
2. `_current_for_picker` dropped identity-mapped items when the source map
only contained renames (compacted form). Switched to
`{source_map.get(name, name) for name in installed}` so the picker
pre-selects every previously-installed item.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@trevor-vaughan I love the ideas! I made changes to this PR and fixed some bugs. Wanna try it again? |
|
That seems better. I would suggest adding the hint about ^A/^R to select all and none at the top. Also, when I tried a new install, the current state wasn't reflected by what is currently installed. The selector stack was definitely a bit fiddly. |
Redesign installed.yml around v2 installation and module_cache records so assistant outputs and local cache copies have distinct lifecycles. Route install, update, uninstall, and mod rm through registry cache ownership decisions, including safe cache cleanup only after the last referencing installation is removed. Reuse recorded user-scope cache paths during update and preserve existing installed names/source mappings so cherry-picked items refresh without spurious conflict prompts.
|
Hello, thank you for this feature. I'm really missing this option in current lola and would be great to get it in. |
Summary
Adds an interactive item selector to
lola installso users can opt out of skills, commands, agents, MCPs, orAGENTS.mdinstructions they don't want without forking the module. Closes #119.--skill/--command/--agent/--mcp(each repeatable and comma-separated),--instructions / --no-instructions, plus-y/--yesto skip the picker.lola installfirst asks "install everything?"; choosing no opens a fuzzy-searchable multi-select picker. Entries are type-prefixed (skill: …,cmd: /…,agent: @…,mcp: …,instructions: AGENTS.md). All entries start deselected; Tab toggles a single item and Alt-A inverts the current selection (toggle-all). Submitting with nothing checked is treated as a cancel.(installed)) and marks newly-upstream items(new)so users can see the delta at a glance.Installation.full_installflag locks cherry-picked installs to the original selection onlola update— newly-upstream items (skills, commands, agents, MCPs, or AGENTS.md) are not silently picked up. Full installs keep tracking upstream. Renamed registry entries are reapplied so picks survive reloads. Legacyinstalled.ymlentries load asfull_install=True; the field is only emitted to YAML whenFalse.Related Issues
Closes #119
Test Plan
pytest— 962 tests passing (new tests intests/test_cli_install_cherry_pick.py)ruff check src tests— cleanbandit -r src— clean (false-positiveB105on the__all__sentinel suppressed with# nosec)lola install <module>asks "install everything?"; declining opens the fuzzy picker with everything deselected; Alt-A toggles all on; subsetting writes only chosen files andfull_install: falsetoinstalled.ymllola install <module> --skill foo --command barinstalls justfoo+bar; omitted categories install nothing;AGENTS.mdinstructions are only written when--instructionsis passedlola updatedoes not pick up the new skill; same flow with a full install doesAGENTS.mdupstream +lola updatedoes not install instructionsCLI shape
AI Disclosure
AI-assisted with Claude Code.
🤖 Generated with Claude Code