Skip to content

fix(plugin-subcommands-advanced): sort registered subcommands by name - #257

Merged
kodiakhq[bot] merged 1 commit into
mainfrom
fix/plugin-subcommands-advanced-sort-order
Oct 17, 2026
Merged

kodiakhq[bot] merged 1 commit into
mainfrom
fix/plugin-subcommands-advanced-sort-order

Conversation

@RedStar071

Copy link
Copy Markdown
Member

🔗 Linked issue

Resolves #256

🧭 Context

Registered subcommands were added to their parent in the order the stores loaded the pieces. That order changes between starts, so the same build could deploy /reports as unblock, block, history once and history, block, unblock the next time. @wolfstar/http-framework 6.4.0 compares deployed and loaded commands by option position, so with register: 'on-start' every parent with modular subcommands was updated on each restart even when nothing had changed.

📚 Description

Registered subcommands, groups, and the subcommands inside each group are now iterated sorted by name, in wireParentSubcommands and in both RegisterSubcommandsHooks methods. Subcommands the parent declares itself are replayed from its snapshot first, so they still come before the registered ones. Names are compared by code unit instead of localeCompare, so the result does not depend on the machine's locale.

I followed the Pullfrog plan on the issue. Checked against the code: the three iteration sites and the lookupEntry loops (search by method name only, left alone) match what it describes.

The first start after upgrading may update those commands once; after that the order is stable. A position option for a custom order is not part of this change.

Key changes

  • sortedRegistryEntries helper (@internal) in src/lib/utils/functions.ts.
  • wireParentSubcommands and RegisterSubcommandsHooks.subcommands/groups use it.
  • Tests load the same children in opposite orders and assert identical, sorted options for direct subcommands, grouped subcommands, and the builder hooks, with the parent's native subcommand still first. They fail without the fix.
  • Patch changeset for @wolfstar/plugin-subcommands-advanced.

Verification: pnpm build, pnpm typecheck and pnpm test (125 files, 1845 tests) pass; oxlint reports nothing on the changed files. pnpm lint as a whole fails its oxfmt --check here only because this Windows checkout has CRLF line endings; the changed files were formatted with oxfmt --write.

Type of Change

  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation change
  • Workflow / CI change

Pre-flight Checklist

  • I have read the Contributing Guidelines (if applicable)
  • My code follows the code style of this project
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have updated the documentation accordingly
  • I added a changeset with pnpm changeset (or pnpm changeset add --empty if no release is needed). See .changeset/README.md.

🤖 AI disclosure: Claude Code was used on this PR. Code written with claude-sonnet-5-5; PR description written with claude-sonnet-5-5. AI policy.

Registered subcommands followed store load order, which changes between starts.
http-framework then updated the parent command on every restart.

Iterate them sorted by name when wiring and in the register hooks.
@coldtea-pr-lens

coldtea-pr-lens Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Architecture

Architecture diagram for wolfstar-project/plugins at 67cc65a

Play the walkthrough


Data flow

Data flow diagram for wolfstar-project/plugins at 67cc65a

Follow each request


Review

✨ Nothing flagged · reviewed 67cc65a


Tip

The diagrams are links. Click one to open it on the canvas, then press W or click play to walk through the change

🪧 More tips
  • Run npx skills add coldteadotai/pr-lens, then tell your coding agent: "Diagram the change you just made with PR Lens and attach it to the pull request."
  • Run npx @coldtea/pr-lens-cli analyze --base origin/main on a branch, then npx @coldtea/pr-lens-cli render .pr-lens/graph.json. Same lenses, your own model key, before the pull request exists
  • Click the link under each diagram to open it on a canvas you can zoom, pan and step through
  • Open a diagram on the canvas, then press W or click play to walk through the change one step at a time
  • The CLI's render reads .github/pr-lens.yml and applies your renames, exclusions and lane pins at draw time
  • Set github.comment.collapsed: true in .github/pr-lens.yml to fold the comment behind one View architecture and data flow row. Drawing still runs as before
  • Set github.draw: on-demand in .github/pr-lens.yml and PR Lens stops drawing pull requests on its own. Comment @pr-lens draw on a pull request when you want that one drawn
  • Add .github/workflows/pr-lens.yml with coldteadotai/pr-lens/packages/action@v0 and your model provider's key as its api-key to run PR Lens from your own CI. Any /chat/completions endpoint works
  • After a push, tick Redraw to draw the latest commit
  • Switch GitHub to dark mode and the diagrams follow. The moving dots are this pull request's data in motion

Thanks for using PR Lens! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out on X, Bluesky, Mastodon, Reddit or LinkedIn

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes

Reviewed the full single-commit diff for stable ordering of registered subcommands.

  • sortedRegistryEntries helper: a non-mutating, locale-independent (code unit) sort of a registry's entries. It uses toSorted, which the repo already uses and which fits the ES2023 lib and Node >=20.
  • wireParentSubcommands and RegisterSubcommandsHooks: direct subcommands, groups, and the subcommands inside each group are now iterated sorted. Subcommands the parent declares itself are replayed first, so they still come before the registered ones.
  • Tests: children loaded forward and backward must yield identical, sorted options for direct, grouped, and builder-hook paths, with the native subcommand still first.
  • Changeset: patch bump for @wolfstar/plugin-subcommands-advanced.

Pullfrog  | View workflow run | Using claude-sonnet-5-5 | 𝕏

@kodiakhq
kodiakhq Bot merged commit 481d536 into main Oct 17, 2026
17 checks passed
@kodiakhq
kodiakhq Bot deleted the fix/plugin-subcommands-advanced-sort-order branch October 17, 2026 19:27
Sign up for free to 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.

plugin-subcommands-advanced: the order of the subcommands changes from a start to the next

1 participant