SuperAPI AI Directory

feature-manager

Coding & development

View repository

Updated 10-15 10:30

About this skill

Feature manager

A feature is a tracking issue plus the PRs that implement it, often a stack of branches based on one another. The user registers a feature once; after that, "work on suggestion mode" means the same thing to Claude every time. This skill keeps the registry and runs the recurring chores over the whole feature at once.

Scripts live in this skill's scripts/ directory (~/.claude/skills/feature-manager/scripts/ once installed). They depend on gh and jq only and never touch the registry; Claude reads and edits registry files directly.

The registry

One YAML file per feature at ~/.claude/features/<slug>.yaml. Hand-editable; the user may change it without saying so, so read it fresh at the start of every task.

name: suggestion-mode
aliases: [suggest mode, suggestion mode, suggestions]
repo: WordPress/gutenberg
tracking_issues: [73411]
worktree: ~/repositories/worktrees/73411-suggest-mode
stack:                      # bottom to top; each base is the branch before it
  - { pr: 80427, branch: suggest/intent, base: trunk }
  - { pr: 80428, branch: suggest/data,   base: suggest/intent }
side_prs: [81997]           # related PRs outside the chain
bundle: { pr: 78994, branch: try/suggest-mode-combined }   # optional Playground bundle
last_checked: 2026-09-11T22:00:00Z
notes: |
  Waiting on design feedback for the sidebar summary wording.

Resolving a name. Match what the user said against name and aliases across every file in the directory, case-insensitively and ignoring the word "feature". One match: use it. None: offer to register, or list what exists. Several: ask which.

The PR list for any chore is the stack in order, then side PRs, then the bundle. Merged or closed PRs stay in the file until the user removes them; skip them for git work.

Chores

The user says Do
"register X from #NNN" / "add this feature" Register
"status of X", "check on X", "how is X doing" Status
"update X", "bring X up to date", "rebase X on trunk" Update (merge, never rebase; say so if they said rebase)
"fix CI on X", "get X green" CI
"any feedback on X", "anything new on X", "what needs a reply" Feedback
"work on X", "open X", "switch to X" Work on
"update the tracking issue", "sync the issue" Sync issue
"watch X", "keep an eye on X" Watch
"what features am I working on", "forget X" List / Forget

Register

bash ~/.claude/skills/feature-manager/scripts/discover-feature.sh WordPress/gutenberg 73411

The output lists every PR the issue body references plus the user's open PRs whose base is a branch already in the set, each with depth (0 = based on trunk) and a bundle_candidate flag. Build the proposed file from it: open PRs sorted by depth form stack; open PRs at depth 0 that are not the chain bottom, or that sit beside another PR at the same depth, go to side_prs; a bundle candidate goes to bundle. Leave merged and closed PRs out. Pick a slug and two or three aliases from the issue title. Set last_checked to now.

Show the user the whole proposed file and ask before writing it. Discovery is a guess about structure; they know which branch is the bundle and which PR is a side quest.

Status

bash ~/.claude/skills/feature-manager/scripts/feature-status.sh WordPress/gutenberg 80427 80428 ... 78994

Print one table, stack order, then side PRs, then the bundle:

PR Title CI Merge Behind Threads Last activity
#80427 1/9 editor intent Passing Conflicting 38 1 ciampo, review, 2h ago

Merge is mergeable unless it is MERGEABLE, then show mergeState (Clean, Blocked, Behind). Behind is commits on the PR's own base it lacks, so for a stack it says who needs the cascade. Mark drafts. Link every PR.

Then Needs you, at most five lines, in this order: conflicts, failing CI, changes requested, unresolved threads with someone else's last word, PRs behind their base. If nothing qualifies, say "all green" and stop. Do not recommend merging; the user decides.

Update

Always dry-run first and show the result:

bash ~/.claude/skills/feature-manager/scripts/cascade-update.sh <worktree> trunk suggest/intent suggest/data ... suggest/e2e --bundle try/suggest-mode-combined --dry-run

UP-TO-DATE in a dry run is relative to the parent as it is now; once trunk lands in the bottom layer every layer above will need its turn, which is what the real run does. If the worktree is dirty the script refuses; report that rather than committing or stashing for them.

Then run without --dry-run. Each layer merges its parent with a merge commit and pushes to origin. The bundle merges the top of the stack last, so bundle-only commits survive. On CONFLICT (exit 3) the merge is left in progress: report the branch and files, then stop. Resolving is the user's call. When they say to resolve, do it in that worktree, commit, push, and re-run the script starting from the next branch with the resolved branch as the base. Never git rebase, never --force, never reset --hard a shared branch.

The script only touches branches that live in origin. A PR from a contributor's fork cannot be cascaded from here - the script exits 2 saying origin/<branch> does not exist. Report those PRs with their Behind count from Status and leave the update to their author; the user decides whether to ask.

Afterwards run Status so the table reflects the pushes (CI will show Running).

CI

Run Status, take the PRs with ci: failing, and for each one use the ci-fixer skill in the feature worktree, bottom of the stack first. A fix low in the stack often clears the layers above once the cascade carries it up, so after fixing one layer run Update before touching the next. Report which PRs were red, what changed, and which are still running.

Feedback

bash ~/.claude/skills/feature-manager/scripts/feature-feedback.sh WordPress/gutenberg <last_checked> 73411 80427 80428 ...

Group by target, people first, bots (is_bot: true) in a separate short section with unresolved items only. For each item say who, where (linked), a one-line gist, and a classification: code change, reply, or nothing (already resolved, a thanks, a bot summary). For code changes and replies, propose the response in one or two lines.

Nothing gets changed or posted from this chore. When the user picks items, code changes happen in the worktree with atomic commits, and replies go through post-review-gate in adams-voice with claude-attribution. Advance last_checked in the registry only after the digest is in front of the user, never before, so a crashed run does not swallow comments.

Work on

Read the registry, cd to worktree. If it does not exist, create it from the repo's main checkout: git worktree add ~/repositories/worktrees/<issue>-<slug> <branch> (the worktrunk skill applies when wt is set up for that repo). Check out the branch the user named, or the top of the stack by default, fast-forward it from origin, and run nvm use when the repo has an .nvmrc. Say which branch is checked out and which PR it belongs to, then wait for the actual task.

Sync issue

Build a status block from the Status table and place it in the tracking issue body between <!-- feature-manager:status --> and <!-- /feature-manager:status -->, adding the markers at the end of the body if absent. Text outside the markers is never touched. The block opens with a claude-attribution header. This is a post under the user's name: draft the full new body to a file, run it through post-review-gate, then gh issue edit NNN --repo OWNER/REPO --body-file <file>, and log it as kind issue.

Watch

Use /loop with a thirty minute interval. Each tick: run Status with --snapshot <slug> and Feedback since last_checked. If changes is empty and there is no new feedback from a person, say nothing beyond a one-line "no change". Otherwise report only what moved (CI turned red, a conflict appeared, a review landed) and, for feedback, the digest. Never take git action or post from a watch tick.

List / Forget

List: one line per registry file with name, repo, open PR count, and last_checked. Forget: confirm, then delete the file and its snapshot under ~/.claude/features/.snapshots/.

Guardrails

  • Read the registry fresh, every task. The user edits it by hand.
  • Never merge a PR, never force-push, never rebase, never resolve a conflict unasked.
  • Nothing posts without post-review-gate. Replies, issue body edits, all of it.
  • Discovery proposes, the user confirms. Do not write a registry file they have not seen.
  • Scope is one feature. Cross-repo "what should I work on next" is pr-status-review's job; fixing a red check is ci-fixer's job. Delegate rather than reimplement.
  • One question at a time when a name or a branch is ambiguous. Guessing wrong pushes to the wrong branch.

Rationalizations that mean stop

Thought Reality
"The conflict is trivial, I'll just resolve it." The user asked for an update, not a resolution. Report and stop.
"Rebase would give cleaner history." The user chose merges so review threads stay anchored. Merge.
"The bot's suggestion is right, I'll apply it." Feedback proposes; the user picks. Put it in the digest.
"Discovery looks obviously right, I'll save it." The user knows which PR is the bundle and which is a side quest. Show it first.
"I'll bump last_checked now so I don't forget." Bump it after the digest is in chat, or a crash loses comments.