Skip to content

feat: interactive capability picker for bare add/remove - #58

Merged
PrzemekGalarowicz merged 2 commits into
mainfrom
feat/capability-picker
Jul 23, 2026
Merged

feat: interactive capability picker for bare add/remove#58
PrzemekGalarowicz merged 2 commits into
mainfrom
feat/capability-picker

Conversation

@PrzemekGalarowicz

@PrzemekGalarowiczPrzemekGalarowicz commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Bare pharn add / pharn remove in a TTY open a grouped multi-select (grillers / lenses) and run the existing per-name install/remove path for each pick
  • Non-TTY / CI keeps a usage error (never prompts); named-arg paths stay unchanged
  • Shared pure picker helpers in capability-picker.ts, plus docs/CHANGELOG/tests

Test plan

  • npm test (especially tests/capability-picker.test.ts, tests/add.test.ts, tests/remove.test.ts)
  • In a real terminal: pharn add → pick capabilities → installs each; empty selection is a no-op
  • In a real terminal: pharn remove → multi-select → confirm → deletes each; decline/cancel leaves config alone
  • Pipe/non-TTY: bare pharn add / pharn remove exit with usage error (no prompt)
  • Named pharn add a11y / pharn remove a11y behavior unchanged

Made with Cursor

Summary by CodeRabbit

  • New Features

    • Added interactive multi-select pickers for bare pharn add and pharn remove commands.
    • add lists uninstalled capabilities; remove lists installed capabilities and confirms deletions once.
    • Bare commands now provide clear usage errors instead of prompting in non-interactive environments.
  • Documentation

    • Updated command help, README, command guides, and changelog with the new behavior.
  • Bug Fixes

    • Improved handling for empty selections, cancellations, and already-installed or unavailable capabilities.

Let terminal users multi-select grillers/lenses with no arg, while non-TTY keeps a usage error and named-arg paths stay unchanged.
Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitaiBot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@PrzemekGalarowicz, you've reached your PR review limit, so we couldn't start this review.

Next review available in:36 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a41d5d1f-f991-4b2a-9a0b-372acb0dc2bc

📥 Commits

Reviewing files that changed from the base of the PR and between 7f98902 and a945190.

📒 Files selected for processing (9)
  • .dev/features/capability-picker/REGRESSION.md
  • .dev/features/capability-picker/REVIEW.md
  • .dev/features/capability-picker/SHIP.md
  • .dev/features/capability-picker/VERIFY.md
  • .dev/features/capability-picker/regression-report.json
  • .dev/features/capability-picker/verify-report.json
  • .pharn/pharn-dev-regress/base-results.json
  • .pharn/pharn-dev-regress/head-results.json
  • .pharn/writes-scope.json
📝 Walkthrough

Walkthrough

Bare pharn add and pharn remove now provide TTY-only grouped multi-select pickers. Add installs selected available capabilities; remove confirms and deletes selected installed capabilities. Picker models, command tests, help text, documentation, changelog entries, and advisory records were updated.

Changes

Capability picker contracts and models

Layer / File(s)Summary
Picker contracts and selection models
.dev/features/capability-picker/PLAN.md, src/lib/capability-picker.ts, tests/capability-picker.test.ts, .pharn/writes-scope.json
Defines deterministic grouped selection models, available-versus-installed computation, remove selection grouping, and the requirement that both standard streams be TTYs.
Feature validation and advisory records
.dev/features/capability-picker/GRILL.md
Records advisory findings and a non-blocking verdict for the capability-picker plan and implementation.

Interactive add flow

Layer / File(s)Summary
Interactive add flow
src/commands/add.ts, tests/add.test.ts, src/index.ts, docs/commands/add.md, README.md, CHANGELOG.md
Bare add invocations now gate on TTY status, present grouped selections, install each pick through the existing path, persist accumulated capabilities, and document the updated behavior.

Interactive remove flow

Layer / File(s)Summary
Interactive remove flow
src/commands/remove.ts, tests/remove.test.ts, docs/commands/remove.md, CHANGELOG.md
Bare remove invocations now select multiple installed capabilities, confirm once, delete selected directories, update configuration once, and handle cancellation, empty selections, declined confirmation, and non-TTY execution.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

Interactive add

sequenceDiagram
participant CLI
participant Picker
participant Installer
participant Config
CLI->>Picker: Build and present available grouped capabilities
Picker-->>CLI: Return selected capabilities
CLI->>Installer: Install each selected capability
Installer->>Config: Persist accumulated capabilities
Loading

Interactive remove

sequenceDiagram
participant CLI
participant Picker
participant Confirmation
participant Filesystem
CLI->>Picker: Build and present installed grouped capabilities
Picker-->>CLI: Return selected capabilities
CLI->>Confirmation: Request one confirmation
Confirmation-->>CLI: Confirm deletion
CLI->>Filesystem: Delete selected capability directories
Loading

Possibly related PRs

  • pharn-dev/pharn-cli#23: Both changes update pharn add and pharn remove around capability parsing and per-capability installation or deletion.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 70.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly summarizes the main change: an interactive capability picker for bare add/remove commands.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/capability-picker

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 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 @.dev/features/capability-picker/GRILL.md:
- Line 60: Update the advisory verdict text in GRILL.md to use the canonical
/pharn-grill command name instead of /pharn-dev-grill, unless the repository
explicitly exposes both commands; keep the surrounding floor-gate guidance
unchanged.
- Around line 20-21: Update the review wording to refer specifically to the bare
interactive “pharn add” picker test rather than a named add test. Preserve the
requirement that the test verifies the final persisted capabilities contain all
selected picks, order-independent, not only that installCapabilityDirs or
writePharnConfig were called.
In `@docs/commands/remove.md`:
- Around line 19-24: Update the later --yes option description in the remove
command documentation to state that --yes remains a no-op and does not bypass
the interactive picker confirmation. Keep the description consistent with the
picker and confirmation behavior documented in the no-argument removal flow.
In `@README.md`:
- Line 98: Update the README command table’s `pharn remove` row to document the
optional capability argument and no-argument interactive multi-select behavior.
Align its wording with the `remove [capability]` usage in `src/index.ts` and
describe that multiple capabilities can be removed.
🪄 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 Plus

Run ID: 0bca5fd0-ebd5-449a-905c-7482010b80d5

📥 Commits

Reviewing files that changed from the base of the PR and between a8131a2 and 7f98902.

📒 Files selected for processing (14)
  • .dev/features/capability-picker/GRILL.md
  • .dev/features/capability-picker/PLAN.md
  • .pharn/writes-scope.json
  • CHANGELOG.md
  • README.md
  • docs/commands/add.md
  • docs/commands/remove.md
  • src/commands/add.ts
  • src/commands/remove.ts
  • src/index.ts
  • src/lib/capability-picker.ts
  • tests/add.test.ts
  • tests/capability-picker.test.ts
  • tests/remove.test.ts

Comment on lines +20 to +21
problem: "The whole feature's correctness hinges on add's picker threading the growing config through resolveArchetypeAdd, which persists pharn.config.json EACH iteration off the config passed in; a threading bug silently clobbers every pick but the last. The named add test must assert the FINAL persisted capabilities equals ALL picks (order-independent), not merely that installCapabilityDirs/writePharnConfig were called."
evidence: "PLAN.md:40 'installs each pick via the existing path & threads config so the final capabilities holds all picks'; PLAN.md:19 'loop the existing resolveArchetypeAdd per pick (config threaded in-memory)'."

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Refer to the bare interactive add test, not a named add test.

These findings concern the picker path for bare pharn add; “named add test” could send reviewers to the wrong regression case.

Proposed wording
- problem: "The ... named add test must assert ...+ problem: "The ... bare interactive add test must assert ...- problem: "No named test pins add's partial-progress-on-error ...+ problem: "No add-picker test pins the partial-progress-on-error ...

Also applies to: 47-49

🤖 Prompt for 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.
In @.dev/features/capability-picker/GRILL.md around lines 20 - 21, Update the
review wording to refer specifically to the bare interactive “pharn add” picker
test rather than a named add test. Preserve the requirement that the test
verifies the final persisted capabilities contain all selected picks,
order-independent, not only that installCapabilityDirs or writePharnConfig were
called.


## Verdict

**ADVISORY VERDICT: 5 concerns raised (0 blocking, 1 important, 4 minor) — for the human to weigh before/at review; `/pharn-dev-grill` gates nothing.** This is not "grill passed" and not a judgment that the plan is sound — it surfaces what the plan omits or understates; the floor gates (`/pharn-dev-build` spec-hash + `validate.mjs`, `/pharn-dev-regress`, `/pharn-dev-verify`) remain the only proceed/stop authorities.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use the canonical advisory command name.

The supplied floor-check context refers to /pharn-grill; update /pharn-dev-grill here unless the repository intentionally exposes both commands.

🤖 Prompt for 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.
In @.dev/features/capability-picker/GRILL.md at line 60, Update the advisory
verdict text in GRILL.md to use the canonical /pharn-grill command name instead
of /pharn-dev-grill, unless the repository explicitly exposes both commands;
keep the surrounding floor-gate guidance unchanged.

Comment on lines +19 to +24
2. With no argument **in a terminal**, opens an interactive multi-select picker (grouped by role) over
the capabilities you have installed, then asks for one confirmation listing your picks. With an
argument, resolves it to one installed capability. In a non-interactive context (CI, a pipe),
no-argument `pharn remove` does **not** prompt — it exits with a usage error (unless nothing is
installed, which is reported plainly).
3. Deletes each selected capability's isolated directory and drops its entry from `capabilities`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Correct the stale --yes description.

This section documents the new picker confirmation, but the later --yes paragraph still says removal has no confirmation prompt. State that --yes remains a no-op and does not bypass the interactive picker confirmation. As per coding guidelines, “Keep user-facing documentation synchronized with implemented behavior.”

🤖 Prompt for 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.
In `@docs/commands/remove.md` around lines 19 - 24, Update the later --yes option
description in the remove command documentation to state that --yes remains a
no-op and does not bypass the interactive picker confirmation. Keep the
description consistent with the picker and confirmation behavior documented in
the no-argument removal flow.

Source: Coding guidelines

Comment threadREADME.md
| --------------------------- | ------------------------------------------------------------------------------- |
| `pharn init` | Detect archetypes and install the applicable capabilities (default) |
| `pharn add [capability]` | Add a capability, e.g. `a11y` or `lens:n-plus-one` (no arg: pick interactively) |
| `pharn remove <capability>` | Remove an installed capability (no arg: pick one interactively) |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Align the remove row with the new no-arg multi-select behavior.

Two inconsistencies vs. the implementation and src/index.ts USAGE (remove [capability]): the argument is now optional (interactive no-arg mode), and the picker is a groupMultiselect that removes multiple capabilities, not one.

📝 Proposed fix
-| `pharn remove <capability>` | Remove an installed capability (no arg: pick one interactively) |+| `pharn remove [capability]` | Remove an installed capability (no arg: pick interactively) |
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
|`pharn remove <capability>`| Remove an installed capability (no arg: pick one interactively) |
|`pharn remove [capability]`| Remove an installed capability (no arg: pick interactively)|
🤖 Prompt for 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.
In `@README.md` at line 98, Update the README command table’s `pharn remove` row
to document the optional capability argument and no-argument interactive
multi-select behavior. Align its wording with the `remove [capability]` usage in
`src/index.ts` and describe that multiple capabilities can be removed.

@PrzemekGalarowicz
PrzemekGalarowicz merged commit ffc1082 into mainJul 23, 2026
8 checks passed
@PrzemekGalarowicz
PrzemekGalarowicz deleted the feat/capability-picker branch July 23, 2026 22:36
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@PrzemekGalarowicz