fix(config): anchor agent/command name matching at the relative path - #1136
Conversation
configEntryNameFromPath matched a prefix (agent/, agents/, command/,
commands/, mode/, modes/) anywhere in the absolute file path. A user or
parent directory whose name coincidentally contained one of those segments
(e.g. a home dir /Users/agent/) won the substring match before the real
entry directory, leaking the intervening path into the key — an agent at
/Users/agent/proj/agent/build.md keyed as "proj/agent/build" instead of
"build".
Anchor the match at the start of the path and have the call sites pass the
path relative to the directory they scanned (path.relative(dir, item)), so
the relative path is always rooted at the prefix. Glob already scans
{agent,agents}/**, {command,commands}/**, and {mode,modes}/* with cwd=dir,
so the .opencode/ prefix variants are subsumed and the prefix list
simplifies to the bare directory names. Case-insensitive matching and
nested-subdirectory keys are preserved.
Add test/config/entry-name.test.ts covering prefix stripping, nested keys,
backslash normalization, case-insensitive matching, basename fallback, and
the #28359 regression (a misleading parent /agent/ segment is no longer
stripped). The existing "tolerate unnormalized roots" assertion still holds.
Reimplemented for PawWork from upstream anomalyco/opencode e94d46af86
(PR #28359, regression #25713, thanks Kit Langton); the fork has no common
ancestor so this is an adapted port that keeps PawWork's case-insensitive
normalization, not a cherry-pick.
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Code Review
This pull request refactors the config entry name resolution to prevent incorrect key mapping when parent directory segments coincidentally match config prefixes (such as '/agent/'). It introduces path.relative at the call sites in agent.ts and command.ts to anchor prefix matching at the start of the relative path, and updates configEntryNameFromPath to use startsWith instead of indexOf. Comprehensive unit tests have also been added to verify this behavior and prevent regressions. There are no review comments, and I have no additional feedback to provide.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Restructure the right-side Status panel from 2 sections (Progress + Sources) into 4 (Progress -> Workspace/Git -> Changed files/Artifact -> Sources), fold the standalone Files tab into the panel as a compact changed-files list, and move the titlebar worktree badge into the Git section. Change boundary (packages/app, packages/ui): - Status panel: new Git section (diff stats -> Review, branch row, worktree indicator with tooltip + open-directory) and Artifact section (changed files with hover/focus-visible open + reveal); Git section hidden outside a git repo. Data from sync.data.vcs (branch), sessionInfo().executionContext.activeWorktree (worktree), aggregateFiles(turn_change_aggregate) (diff stats). - Files tab removed from RightPanelStaticTab / RIGHT_PANEL_TAB_META / command palette / keybind; legacy persisted "files" coerced to "status" via coerceLegacySidePanelTab + migrateLegacyRightPanelTab. - Titlebar PawworkWorktreeBadge removed (worktree info now lives in the panel Git section). - New `changes` icon registered (packages/ui). Verification: - typecheck clean; full app unit suite 1753 pass / 0 fail. - Visual: status-summary-panel snap (4 sections + rest->hover open/reveal) plus a dev:desktop walk in the real Electron host (dark theme, zh locale, live sidecar) - Git section populated from real VCS (+N/-N, branch main), Artifact section listing a real session file (sample-test.md, +76). - Codex adversarial review P1 findings fixed; 5 review threads resolved. Brought current with dev: one conflict in context/layout.tsx - dev had extracted the inline layout helpers into context/layout-state.ts / layout-projects.ts (#1056 slice work). Took dev's refactored layout.tsx and ported this branch's defaultSidePanelTab `| "files"` widening into layout-state.ts. Final state 0 behind dev; also merged #1135/#1136/#1137/#1139 cleanly (no file overlap). Deferred: dev:desktop worktree-indicator tooltip + non-git-hide are state-conditional and were not exercised live (hover open/reveal covered by the snap). session-side-panel.test.tsx isolation failure is the pre-existing mock.module warmup flake (its @/context/command mock omits matchKeybind/parseKeybind that terminal.tsx imports transitively); green in the full suite, tracked under the #1084 mock.module cleanup. Relates #1056.
Summary
configEntryNameFromPathmatched a known prefix (agent/,agents/,command/,commands/,mode/,modes/) anywhere in the absolute file path. A user or parent directory whose name coincidentally contained one of those segments won the substring match before the real entry directory, leaking the intervening path into the key — an agent at/Users/agent/proj/agent/build.mdkeyed asproj/agent/buildinstead ofbuild.This anchors the match at the start of the path and has the three call sites pass the path relative to the directory they scanned (
path.relative(dir, item)), so the relative path is always rooted at the prefix.Why
Glob.scanalready scans{agent,agents}/**,{command,commands}/**, and{mode,modes}/*withcwd=dir, sopath.relative(dir, item)is alwaysagent/…,command/…, etc. With the relative path, anchoring at the start fixes the mis-keying and the.opencode/prefix variants become unnecessary (.opencodelives indir, not in the relative path), so the prefix list simplifies to the bare directory names. PawWork's case-insensitive matching and nested-subdirectory keys (agents/team/build.md→team/build) are preserved.Related Issue
No PawWork issue. Reimplemented for PawWork from upstream
anomalyco/opencodee94d46af86(PR #28359, original regression #25713, thanks Kit Langton). The fork has no common ancestor with upstream, so this is an adapted port that keeps PawWork's case-insensitive normalization (upstream's variant is case-sensitive), not a cherry-pick.Human Review Status
Pending
Review Focus
Medium risk:
configEntryNameFromPathfeeds agent/command/mode keys across three call sites. Confirm (1) the contract change from absolute path →path.relative(dir, item)is correct for all three (the glob guarantees items are underdir), (2) case-insensitive matching is preserved, and (3) nested-subdirectory keys are preserved. The existingconfig.test.ts"tolerate unnormalized roots" assertion still passes unchanged.Risk Notes
Medium. The helper's contract changed (now expects a relative path); all three in-repo call sites were updated in the same change and there are no other callers. Behavior for the normal case is unchanged; only the mis-keyed parent-segment case changes (now correct). No platform/packaging/UI surface touched.
How To Verify
Screenshots or Recordings
N/A — no visible UI change.
Checklist
bug,enhancement,task,documentation. Type labels are author-added; the labeler bot does NOT assign them. Add the label in the GitHub UI, then tick this.app,ui,platform,harness,ci. The labeler bot assigns these on PR open based on changed paths. Confirm the bot's choice (or override if wrong), then tick this.P0,P1,P2,P3. The priority-triage bot suggests one on PR open. Confirm or override, then tick this.Pending,Approved by @<reviewer>, orNot required: <reason>(default isPending; "not required" is restricted to bot-authored low-risk PRs).dev, and my PR title and commit messages use Conventional Commits in English.