Skip to content

fix(commands): resolve active plugin root in /instinct-status (#2037)#2059

Open
fxdv wants to merge 1 commit into
affaan-m:mainfrom
fxdv:fix/instinct-status-resolve-plugin-root-2037
Open

fix(commands): resolve active plugin root in /instinct-status (#2037)#2059
fxdv wants to merge 1 commit into
affaan-m:mainfrom
fxdv:fix/instinct-status-resolve-plugin-root-2037

Conversation

@fxdv
Copy link
Copy Markdown

@fxdv fxdv commented May 25, 2026

Summary

Fixes #2037.

The /instinct-status slash command template expanded ${CLAUDE_PLUGIN_ROOT} directly and documented a python3 ~/.claude/skills/continuous-learning-v2/scripts/instinct-cli.py fallback for manual installs. When users had both an active plugin install (under ~/.claude/plugins/cache/<slug>/<org>/<version>/) AND a legacy ~/.claude/skills/continuous-learning-v2/ directory left over from a previous manual install, an empty CLAUDE_PLUGIN_ROOT (which Claude Code does not always populate in slash-command shell contexts, per the issue repro) silently made the command read the stale legacy install while the active plugin hooks and observer wrote to the new XDG path.

End result, as the reporter described: a fully functional, actively learning system that appeared completely broken to the user — "No instincts found" while observations were accumulating elsewhere.

Fix

Replace the brittle two-block template with the same inline-resolver pattern that hooks/hooks.json and the other slash commands (/sessions, /skill-health) already use:

ECC_ROOT="${CLAUDE_PLUGIN_ROOT:-$(node -e "var r=(()=>{...resolver...})();console.log(r)")}"
python3 "$ECC_ROOT/skills/continuous-learning-v2/scripts/instinct-cli.py" status

The resolver chain is: env var → standard install → known plugin roots → plugin cache walk → fallback. It's the canonical INLINE_RESOLVE constant exported from scripts/lib/resolve-ecc-root.jsno new code is introduced, just consistent adoption of the existing pattern across all slash commands.

Files changed

  • commands/instinct-status.md — canonical
  • .opencode/commands/instinct-status.md
  • docs/zh-CN/commands/instinct-status.md
  • docs/ja-JP/commands/instinct-status.md
  • docs/tr/commands/instinct-status.md
  • tests/lib/command-plugin-root.test.js — extends the existing pattern (which already covers sessions.md and skill-health.md) with an instinct-status.md assertion, plus a regression guard that the legacy ~/.claude/skills/... fallback string is no longer present.

Test plan

  • node tests/lib/command-plugin-root.test.js — 4/4 pass (3 prior + 1 new)
  • node tests/lib/resolve-ecc-root.test.js — 23/23 pass (resolver itself is unchanged; existing tests already cover the env-unset → plugin-cache-walk path that fixes this bug)
  • node tests/hooks/hooks.test.js — 237/237 pass (sanity)
  • Smoke-tested the new bash block locally with unset CLAUDE_PLUGIN_ROOT; the resolver returns the correct active install path (falls through to ~/.claude cleanly when no install is present, which matches the documented final-fallback behavior).

Notes for reviewer

  • All five copies are kept in sync in this PR (canonical + opencode + 3 translations). Surrounding prose in each translation is preserved; only the Implementation section's two code blocks → one code block change.
  • The inline resolver blob is the verbatim string from INLINE_RESOLVE in scripts/lib/resolve-ecc-root.js, so any future tightening of the resolver only needs to update that one constant + the inlined copies in hooks.json, sessions.md, skill-health.md, and now instinct-status.md (the existing tests/lib/command-plugin-root.test.js already pins this consistency).
  • Did not consolidate the inline blob into a shared script file because the current architecture deliberately keeps the resolver inlinable into bash (Node has to find the wrapper before it can require() anything from the plugin tree — chicken-and-egg). The pre-minified INLINE_RESOLVE export is the maintainer's solution to that constraint and is reused here as-is.

Summary by cubic

Fixes stale path resolution in /instinct-status that could read a legacy install when CLAUDE_PLUGIN_ROOT was unset, causing “No instincts found.” The command now uses the shared inline resolver to always target the active plugin install (#2037).

  • Bug Fixes
    • Replaced the two-block template with the canonical inline resolver (env var → standard install → known plugin roots → plugin cache → fallback) from scripts/lib/resolve-ecc-root.js.
    • Updated all copies of the command (canonical, .opencode, JA/TR/ZH) to use the resolver; polished zh-CN phrasing.
    • Extended tests to assert the resolver is present and the legacy ~/.claude/skills/... fallback is not used.

Written for commit 6c99b78. Summary will update on new commits. Review in cubic

Summary by CodeRabbit

  • Documentation

    • Updated instinct-status command docs (EN/JA/TR/ZH) to show a prioritized plugin-root resolution and run the status example using the resolved root for more reliable command examples.
  • Tests

    • Added tests to validate the resolver is invoked correctly and to prevent regressions that reintroduce legacy hardcoded fallback paths.

Review Change Stack

@fxdv fxdv requested a review from affaan-m as a code owner May 25, 2026 19:27
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 25, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b76ed240-940b-463a-8a54-e01c086b4a98

📥 Commits

Reviewing files that changed from the base of the PR and between 25fdac5 and 6c99b78.

📒 Files selected for processing (6)
  • .opencode/commands/instinct-status.md
  • commands/instinct-status.md
  • docs/ja-JP/commands/instinct-status.md
  • docs/tr/commands/instinct-status.md
  • docs/zh-CN/commands/instinct-status.md
  • tests/lib/command-plugin-root.test.js

📝 Walkthrough

Walkthrough

The PR updates instinct-status command documentation and tests across English and localized versions to resolve the active ECC plugin root via a Node-based resolver before invoking the instinct CLI, eliminating path divergence when CLAUDE_PLUGIN_ROOT is unset but a legacy ~/.claude install directory remains.

Changes

instinct-status ECC_ROOT resolution

Layer / File(s) Summary
Core command documentation and validation
.opencode/commands/instinct-status.md, commands/instinct-status.md, tests/lib/command-plugin-root.test.js
The primary command documentation and tests are updated to compute ECC_ROOT through a Node-based resolver that checks CLAUDE_PLUGIN_ROOT, standard install locations, known plugin roots, and plugin cache directories in order, then invokes the status script from the resolved path. Tests verify the resolver is called exactly once per marketplace plugin root and that no hardcoded legacy ~/.claude fallback is present.
Localized documentation translations
docs/ja-JP/commands/instinct-status.md, docs/tr/commands/instinct-status.md, docs/zh-CN/commands/instinct-status.md
Japanese, Turkish, and Chinese translations of the instinct-status command documentation are updated in parallel to document the same ECC_ROOT resolution pattern and updated example invocation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

  • #2037: This PR implements the ECC_ROOT resolver and replaces brittle ${CLAUDE_PLUGIN_ROOT}/~/.claude fallbacks, addressing the path divergence described in issue #2037.

Suggested reviewers

  • affaan-m

Poem

🐰 I sniffed the roots both near and far,
Traced ECC_ROOT by moon and star,
No more stale paths left on the trail,
The status runs true without fail,
A rabbit hops, content—no more derail.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'fix(commands): resolve active plugin root in /instinct-status (#2037)' directly and clearly describes the main change: fixing the /instinct-status command to properly resolve the active plugin root, addressing issue #2037.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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.

@ecc-tools
Copy link
Copy Markdown
Contributor

ecc-tools Bot commented May 25, 2026

ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/zh-CN/commands/instinct-status.md`:
- Line 14: The sentence "相同的解析器运行本能 CLI——环境变量 → 标准安装 → 已知插件根 → 插件缓存 → 回退。" has
awkward phrasing; change "相同的解析器运行本能 CLI" to a more natural form such as
"以相同的解析器运行本能 CLI" or "用相同解析器运行本能 CLI" to improve readability while keeping the
rest of the line intact.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 51f7718a-8c1a-4e42-851c-6646d5780124

📥 Commits

Reviewing files that changed from the base of the PR and between 928076c and 25fdac5.

📒 Files selected for processing (6)
  • .opencode/commands/instinct-status.md
  • commands/instinct-status.md
  • docs/ja-JP/commands/instinct-status.md
  • docs/tr/commands/instinct-status.md
  • docs/zh-CN/commands/instinct-status.md
  • tests/lib/command-plugin-root.test.js

Comment thread docs/zh-CN/commands/instinct-status.md
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

No issues found across 6 files

Re-trigger cubic

…-m#2037)

The `/instinct-status` slash command template expanded
`${CLAUDE_PLUGIN_ROOT}` directly and documented a manual-install
fallback to `~/.claude/skills/continuous-learning-v2/scripts/instinct-cli.py`.
When users had both an active plugin install (under
`~/.claude/plugins/cache/<slug>/<org>/<version>/`) and a legacy
`~/.claude/skills/continuous-learning-v2/` directory left over from a
previous manual install, an empty `CLAUDE_PLUGIN_ROOT` (which Claude
Code does not always populate in slash-command shell contexts) silently
made the command read the stale legacy install while the active plugin
hooks and observer wrote to the new XDG path. The user saw "No
instincts found" while the system was actively learning — exactly the
divergence the bug reporter spent hours diagnosing.

Replace the brittle two-block template with the same inline resolver
pattern that `hooks/hooks.json` and `/sessions` / `/skill-health`
already use: env var → standard install → known plugin roots → plugin
cache walk → fallback. The resolver is the canonical `INLINE_RESOLVE`
constant from `scripts/lib/resolve-ecc-root.js`, so no new code is
introduced — just consistent adoption of the existing pattern.

Apply the same fix to all five copies of the command:
  - commands/instinct-status.md (canonical)
  - .opencode/commands/instinct-status.md
  - docs/zh-CN/commands/instinct-status.md
  - docs/ja-JP/commands/instinct-status.md
  - docs/tr/commands/instinct-status.md

Extend tests/lib/command-plugin-root.test.js with an assertion that the
canonical instinct-status.md uses the inline resolver and no longer
hard-codes the legacy `~/.claude/skills/...` fallback (regression
guard).

zh-CN copy: polish the Chinese phrasing per LanguageTool feedback
(`使用与 ... 相同的解析器` → `以与 ... 相同的解析器`) so the verb is
introduced by an explicit preposition instead of reading as an awkward
verb-object construction.
@fxdv fxdv force-pushed the fix/instinct-status-resolve-plugin-root-2037 branch from 25fdac5 to 6c99b78 Compare May 25, 2026 22:05
@fxdv
Copy link
Copy Markdown
Author

fxdv commented May 25, 2026

Applied in 6c99b786 — changed 使用与 ... 相同的解析器 to 以与 ... 相同的解析器 so the means/method is introduced by an explicit preposition () instead of reading as a bare verb-object construction. Thanks for the LanguageTool catch.

@ecc-tools
Copy link
Copy Markdown
Contributor

ecc-tools Bot commented May 25, 2026

ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR.

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.

/instinct-status falls back to manual install when CLAUDE_PLUGIN_ROOT is unset, masking the plugin's actual state

1 participant