Skip to content

fix: allow global commands to resolve when a project is active#3

Open
Krashnicov wants to merge 2 commits into3clyp50:mainfrom
Krashnicov:fix/global-commands-outside-project-scope
Open

fix: allow global commands to resolve when a project is active#3
Krashnicov wants to merge 2 commits into3clyp50:mainfrom
Krashnicov:fix/global-commands-outside-project-scope

Conversation

@Krashnicov
Copy link
Copy Markdown

@Krashnicov Krashnicov commented Apr 11, 2026

Problem

When a project context is active, using any Global command fails with:

Command path is outside the selected scope

This affects both the slash picker invocation and the editor resolve path.

Root Cause

Two places in helpers/commands.py validated file paths exclusively against the project scope directory:

  1. _validate_command_path - raises ValueError if the command file is not inside the project commands dir.
  2. _load_yaml_command_file - returns None (silent failure) if the content file is not inside the project scope root.

Global commands live in the global scope directory, not the project directory, so they always fail these checks when any project is active.

Fix

_validate_command_path

Instead of checking against only the project scope root, check against all effective scope roots using the same _iter_precedence_scopes list already used by list_effective_commands:

# Before
scope_root = get_scope_directory(project_name, "")
if not files.is_in_dir(command_path, scope_root):
    raise ValueError("Command path is outside the selected scope")

# After
valid_roots = [get_scope_directory(scope, "") for scope in _iter_precedence_scopes(project_name)]
if not any(files.is_in_dir(command_path, scope_root) for scope_root in valid_roots):
    raise ValueError("Command path is outside the selected scope")

_load_yaml_command_file

Content files are always co-located with their config file. Validate against the config file's own parent directory (directory_path) rather than the project scope root:

# Before
scope_root = get_scope_directory(project_name, "")
if not files.is_in_dir(content_abs_path, scope_root):
    return None

# After
# Content file must live in the same directory as its config file.
if not files.is_in_dir(content_abs_path, directory_path):
    return None

Reproduction

  1. Create a Global command (no project active)
  2. Activate any project
  3. Open the slash picker - Global command appears
  4. Invoke the Global command - previously raised ValueError: Command path is outside the selected scope

Checklist

  • Only helpers/commands.py modified
  • No new dependencies
  • Existing behaviour for project-scoped commands unchanged
  • Syntax verified (ast.parse clean)

Summary by CodeRabbit

  • Bug Fixes
    • Command file loading and path validation now correctly accept both project-scoped and global command configurations, ensuring content files are resolved relative to their configuration scope.
  • Documentation
    • Added user-facing docstrings and descriptions to many public command helpers to improve clarity and discoverability of command-related operations.

When a project context is active, _validate_command_path and
_load_yaml_command_file were only checking paths against the project
scope directory. Global commands live in the global scope directory
and were always rejected with 'Command path is outside the selected
scope'.

Fixes:
- _validate_command_path: check all effective scope roots
  (_iter_precedence_scopes) instead of only the project scope root.
  This mirrors the same precedence list already used by
  list_effective_commands.
- _load_yaml_command_file: validate content file against its own
  parent directory (directory_path) rather than the project scope
  root. Content files are always co-located with their config files.

Reproduction: create a global command, activate any project, then
try to invoke or resolve the global command — previously raised
ValueError, now resolves correctly.
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 11, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8bb50b9e-3151-4a80-8a32-07ab7613a543

📥 Commits

Reviewing files that changed from the base of the PR and between e2f2389 and 7015e68.

📒 Files selected for processing (1)
  • helpers/commands.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • helpers/commands.py

📝 Walkthrough

Walkthrough

Updated command file and path validation in helpers/commands.py: content-file containment is checked against the config file's parent directory, and scope validation now checks against all effective precedence scopes. Docstrings were added to many public helper functions without signature changes.

Changes

Cohort / File(s) Summary
Command validation & docs
helpers/commands.py
Changed _load_yaml_command_file to validate command content files relative to the config file's parent directory; updated _validate_command_path to validate against all effective scope roots from _iter_precedence_scopes(project_name) instead of a single project root. Added docstrings to multiple public helpers (no signature/behavior changes).

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 I nudge the scopes and hop along,

Configs and globals singing one song.
Paths now check where their files reside,
Multiple roots walk side by side.
A tiny rabbit's tidy stride ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main fix: allowing global commands to resolve when a project context is active, which aligns perfectly with the changeset's core objective.
Docstring Coverage ✅ Passed Docstring coverage is 91.67% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

Adds Google-style docstrings to all 22 public functions to satisfy
the 80% docstring coverage CI threshold.

Functions documented:
- sanitize_command_name, normalize_command_type
- command_file_name, command_content_file_name
- parse_slash_invocation, parse_arguments
- render_command_body, render_text_template
- get_scope_key, get_scope_label, get_scope_directory
- ensure_scope_directory, get_scope_payload, get_context_scope
- list_scope_commands, list_effective_commands
- get_command, save_command, delete_command
- duplicate_command, resolve_command_invocation
- strip_private_scope
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.

1 participant