Skip to content

feat(cmd): add repo-scoped commands — raid <repo> <command>#62

Merged
8bitAlex merged 2 commits intomainfrom
claude/repo-scoped-commands
Apr 30, 2026
Merged

feat(cmd): add repo-scoped commands — raid <repo> <command>#62
8bitAlex merged 2 commits intomainfrom
claude/repo-scoped-commands

Conversation

@8bitAlex
Copy link
Copy Markdown
Owner

Summary

Adds the ability to explicitly run a command defined in a specific repository's raid.yaml, even when a profile-level command has the same name.

raid backend test     # run the "test" command from the backend repo
raid frontend build   # run the "build" command from the frontend repo
raid backend --help   # list available commands for the backend repo

Each repository that defines commands now appears as a subcommand in raid --help. The existing flat raid <command> behavior is fully preserved — this is purely additive.

Closes #21

Changes

Core (src/internal/lib/command.go)

  • GetRepos() — returns the repositories in the active profile (parallel to GetCommands())
  • ExecuteRepoCommand(repoName, cmdName, args) — looks up a command in a specific repo and runs it (same session/args/recording flow as ExecuteCommand)

Facade (src/raid/raid.go)

  • GetRepos() and ExecuteRepoCommand() wrappers

CLI (src/cmd/raid.go)

  • registerRepoCommands(root, repos) — registers each repo as a Cobra subcommand with its commands as sub-subcommands
  • Wired into executeRoot() after registerUserCommands()
  • Conflict handling: repos whose name matches a built-in or user command are skipped with a warning
  • RunE uses WithMutationLock (matching the existing user command pattern)

Docs

  • README.md — new raid <repo> <command> section
  • site/docs/usage/custom.mdx — "Repo-scoped commands" section
  • site/docs/features/repo-config.mdx — updated Commands section
  • site/docs/references/commands.mdx — added repo-scoped syntax
  • site/docs/examples/custom-commands.mdx — added raid api migrate example

Test plan

  • TestGetRepos_nilContext, TestGetRepos_withRepos
  • TestExecuteRepoCommand_success, _repoNotFound, _cmdNotFound, _taskFailure, _setsArgs, _nilContext
  • TestRegisterRepoCommands_appearsInHelp, _repoSubcommands, _reservedNameSkipped, _conflictWithUserCommand, _noCommandsSkipped, _multipleRepos, _emptyRepos, _runE
  • go test ./... — all passing
  • go vet ./... — clean
  • npm run build in site/ — docsite builds with no broken links
  • Version bumped to 0.7.4-beta

Generated by Claude Code

Each repository that defines commands in its raid.yaml is now registered
as a Cobra subcommand of root. Users can run `raid backend test` to
explicitly target the backend repo's "test" command, even when a
profile-level command has the same name.

- lib: add GetRepos() and ExecuteRepoCommand(repo, cmd, args)
- raid: expose GetRepos() and ExecuteRepoCommand() in the facade
- cmd: add registerRepoCommands() wired into executeRoot(); repos with
  names that conflict with built-in or user commands are skipped with a
  warning
- docs: README, docsite (custom commands, repo-config, command reference,
  examples)
- version: bump to 0.7.4-beta

Closes #21
Copilot AI review requested due to automatic review settings April 29, 2026 23:38
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 29, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.68%. Comparing base (4eda89b) to head (dff8298).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #62      +/-   ##
==========================================
+ Coverage   92.49%   92.68%   +0.19%     
==========================================
  Files          32       32              
  Lines        2438     2503      +65     
==========================================
+ Hits         2255     2320      +65     
  Misses        114      114              
  Partials       69       69              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds repo-scoped CLI command namespaces (raid <repo> <command>) so users can run a command from a specific repository’s raid.yaml even when a profile-level command has the same name (closes #21).

Changes:

  • Added GetRepos() and ExecuteRepoCommand() to the internal lib + facade layer.
  • Registered repo namespaces and their commands as Cobra subcommands (raid <repo> <command>), including conflict handling.
  • Updated docs and added tests covering repo discovery, command execution, and CLI registration behavior.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/resources/app.properties Bumps version to 0.7.4-beta.
src/raid/raid.go Adds facade wrappers for repo listing + repo-scoped command execution.
src/internal/lib/command.go Implements GetRepos() and ExecuteRepoCommand() in core command runner.
src/internal/lib/command_test.go Adds unit tests for repo listing and repo-scoped command execution.
src/cmd/raid.go Registers repo namespaces + repo commands into Cobra command tree.
src/cmd/raid_test.go Adds CLI registration tests for repo-scoped commands and conflict handling.
site/docs/usage/custom.mdx Documents repo-scoped command syntax and updates reserved-name constraints.
site/docs/references/commands.mdx Adds repo-scoped syntax and examples; updates reserved-name list.
site/docs/features/repo-config.mdx Updates repo command precedence explanation and reserved-name list.
site/docs/examples/custom-commands.mdx Adds explicit repo-scoped command examples.
README.md Documents raid <repo> <command> usage and examples.

Comment thread src/internal/lib/command.go Outdated
Comment on lines +115 to +117
startedAt := RecordRecentStart(found.Name)
err := runCommand(found)
RecordRecentEnd(found.Name, err, startedAt)
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

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

ExecuteRepoCommand records recent runs under found.Name only. If a repo-scoped command shares the same name as a profile-level command (the motivating case for this feature), the recent history / raid context output becomes ambiguous. Consider recording a namespaced identifier (e.g., " " or ":") for RecordRecentStart/End in the repo-scoped path so history clearly identifies which command actually ran.

Suggested change
startedAt := RecordRecentStart(found.Name)
err := runCommand(found)
RecordRecentEnd(found.Name, err, startedAt)
recentName := fmt.Sprintf("%s:%s", repoName, found.Name)
startedAt := RecordRecentStart(recentName)
err := runCommand(found)
RecordRecentEnd(recentName, err, startedAt)

Copilot uses AI. Check for mistakes.
Comment thread site/docs/usage/custom.mdx Outdated
## Constraints

Custom command names cannot shadow built-in names: `profile`, `install`, `env`, `doctor`.
Custom command names cannot shadow built-in names: `profile`, `install`, `env`, `doctor`, `context`.
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

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

The docs say built-in names are limited to profile, install, env, doctor, context, but the CLI also reserves help, version, and completion (see reservedNames in src/cmd/raid.go). Please update this list (or rephrase to avoid an exhaustive enumeration) so the documentation matches actual behavior.

Suggested change
Custom command names cannot shadow built-in names: `profile`, `install`, `env`, `doctor`, `context`.
Custom command names cannot shadow reserved built-in CLI names, such as `profile`, `install`, `env`, `doctor`, `context`, `help`, `version`, and `completion`.

Copilot uses AI. Check for mistakes.
Comment thread site/docs/references/commands.mdx Outdated
Custom commands are defined in `commands` sections of the profile or in individual repository `raid.yaml` files. Run `raid --help` to see all available commands.

Custom command names cannot shadow built-in names (`profile`, `install`, `env`, `doctor`).
Custom command names cannot shadow built-in names (`profile`, `install`, `env`, `doctor`, `context`).
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

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

This reserved-name list is incomplete: the CLI also prevents custom commands from using help, version, and completion (see reservedNames in src/cmd/raid.go). Update the list (or reword to indicate the list is non-exhaustive) so users don’t accidentally pick a disallowed name.

Suggested change
Custom command names cannot shadow built-in names (`profile`, `install`, `env`, `doctor`, `context`).
Custom command names cannot shadow built-in or reserved names (`profile`, `install`, `env`, `doctor`, `context`, `help`, `version`, `completion`).

Copilot uses AI. Check for mistakes.
Comment thread site/docs/features/repo-config.mdx Outdated
raid api api-dev # explicitly run the api repo's "api-dev" command
```

Command names cannot shadow built-in names: `profile`, `install`, `env`, `doctor`, `context`.
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

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

This built-in name list should match what the CLI actually reserves. reservedNames in src/cmd/raid.go also includes help, version, and completion, so custom commands using those names will be rejected even though they aren’t listed here. Please update or clarify the wording.

Suggested change
Command names cannot shadow built-in names: `profile`, `install`, `env`, `doctor`, `context`.
Command names cannot shadow built-in names: `profile`, `install`, `env`, `doctor`, `context`, `help`, `version`, `completion`.

Copilot uses AI. Check for mistakes.
- Record repo-scoped commands with namespaced identifier (repo:cmd) in
  recent history so `raid context` output is unambiguous when a repo
  command shares a name with a profile command
- Update reserved-name lists in 3 doc pages to include all 8 reserved
  names (was missing help, version, completion)
- Add facade tests for GetRepos() and ExecuteRepoCommand() to close the
  codecov patch gap
@8bitAlex 8bitAlex merged commit 2881258 into main Apr 30, 2026
13 checks passed
@8bitAlex 8bitAlex deleted the claude/repo-scoped-commands branch April 30, 2026 00:49
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.

Explicitly run repo specific commands

3 participants