Skip to content

Support custom skill roots and update React import in tests#925

Merged
esengine merged 2 commits into
esengine:mainfrom
kabaka9527:main
May 15, 2026
Merged

Support custom skill roots and update React import in tests#925
esengine merged 2 commits into
esengine:mainfrom
kabaka9527:main

Conversation

@kabaka9527

Copy link
Copy Markdown
Contributor

What

Adds configurable custom skill roots for Reasonix. Users can add, list, and remove custom skill paths from the CLI, configure the same paths from the Web UI settings page, and have those paths participate in skill discovery alongside project, global, and built-in skills. The implementation keeps the user-entered path text as the saved/displayed value while resolving paths internally for discovery, status checks, and deduplication.

Why

Fixes the workflow requested in issue #870: users need to reuse skills stored outside the built-in/project/global skill directories and manage those locations consistently across CLI and Web UI. This also fixes follow-up path handling issues so CLI-saved paths appear in Web UI settings, ~/... is resolved correctly for runtime use, and relative paths are not rewritten in the saved configuration.

How to verify

Run npm run verify.
In the CLI, run /skill paths add ~/.agents/skills/find-skills, then /skill paths and confirm the configured value remains ~/.agents/skills/find-skills while the resolved/status information points at the home directory.
Open the Web UI settings page and confirm the same skill path appears in the skills paths field.
Save comma-separated paths from the Web UI, then confirm /skill paths shows the same configured values in the CLI.
Confirm custom skills from those paths appear in /skill list, the Web UI skills panel, and are usable through the skill runner.

Checklist

  • [ ✅] npm run verify passes locally (lint + typecheck + tests + comment-policy gate)
  • [ ✅] No Co-Authored-By: Claude trailer in commits
  • [ ✅] Comments follow CONTRIBUTING.md (no module-essay headers, no incident history)
  • [ ✅] No edits to CHANGELOG.md — release notes are maintainer-written at release time

@esengine

Copy link
Copy Markdown
Owner

Thanks for the work — but I think this PR is solving a different problem than #870 actually asks for.

The issue requests auto-loading from two known paths (~/.agents/skills, ./.agents/skills) and explicitly rejects custom-path config as the alternative: "Custom env var – adds friction, no migration benefit." The minimum that closes #870 is ~4 lines inside SkillStore.roots() — append join(this.projectRoot, ".agents", SKILLS_DIRNAME) and join(this.homeDir, ".agents", SKILLS_DIRNAME) to the existing list. Skills sitting in .agents/skills would then "just work" with no user action.

What's here is ~880 lines across CLI subcommands + Web UI text field + dashboard + new scope + tests — exactly the friction the issue author wanted to avoid. It also doesn't actually solve the stated problem: existing .agents/skills directories still aren't picked up unless the user discovers the new setting and configures them. And per the project's current direction we've been trimming Web-UI / settings-page surface, not adding to it.

Two cleaner paths from here:

  1. Reduce this PR to the minimal change — two extra entries in roots(). Closes Support the .agents/skills directory #870, ships clean.
  2. Split the configurable-paths system into its own issue first so we can talk through scope before building it (is /skill paths add worth the surface vs editing ~/.reasonix/config.yaml? does the Web UI field stay?).

The React-import lint fix in tests/plan-confirm.test.tsx:3 is unrelated but welcome — happy to take that as its own one-line PR if you want to peel it off.

@kabaka9527

Copy link
Copy Markdown
Contributor Author

Thanks for the work — but I think this PR is solving a different problem than #870 actually asks for.

The issue requests auto-loading from two known paths (~/.agents/skills, ./.agents/skills) and explicitly rejects custom-path config as the alternative: "Custom env var – adds friction, no migration benefit." The minimum that closes #870 is ~4 lines inside SkillStore.roots() — append join(this.projectRoot, ".agents", SKILLS_DIRNAME) and join(this.homeDir, ".agents", SKILLS_DIRNAME) to the existing list. Skills sitting in .agents/skills would then "just work" with no user action.

What's here is ~880 lines across CLI subcommands + Web UI text field + dashboard + new scope + tests — exactly the friction the issue author wanted to avoid. It also doesn't actually solve the stated problem: existing .agents/skills directories still aren't picked up unless the user discovers the new setting and configures them. And per the project's current direction we've been trimming Web-UI / settings-page surface, not adding to it.

Two cleaner paths from here:

  1. Reduce this PR to the minimal change — two extra entries in roots(). Closes Support the .agents/skills directory #870, ships clean.
  2. Split the configurable-paths system into its own issue first so we can talk through scope before building it (is /skill paths add worth the surface vs editing ~/.reasonix/config.yaml? does the Web UI field stay?).

The React-import lint fix in tests/plan-confirm.test.tsx:3 is unrelated but welcome — happy to take that as its own one-line PR if you want to peel it off.

I don't think we should directly index ~/.agents/skills, as I found that when using skills.sh, there isn't a ~/.agents/skills option. It's more common to have a skills directory unique to the CLI tool. I believe when users work with multiple CLIs, they might assign corresponding skills based on the performance of each CLI, and these skills are mostly located in the proprietary directories of the CLI tools.

@kabaka9527

kabaka9527 commented May 15, 2026

Copy link
Copy Markdown
Contributor Author
image

Users should have their own path selection, rather than fixed ~/.agents/skills

@esengine

Copy link
Copy Markdown
Owner

Fair pushback — I'll grant that .agents/skills adoption is uneven across agent CLIs (Claude Code uses ~/.claude/skills, skills.sh varies, MCP-style tools have their own). Letting users point at whatever directory their existing toolchain already uses is legitimate.

That said, I still don't want this PR's full shape. The surface — /skill paths add/list/remove subcommand tree + Web-UI text field + dashboard plumbing + new custom scope enum — is too much for a config a user sets once and never touches again. We've been actively trimming Web-UI / settings surface (/harvest, /branch), not adding to it.

What I'd merge is a much smaller version:

  • Add a customSkillRoots: string[] field to ~/.reasonix/config.yaml and read it inside SkillStore.roots(). ~20 lines.
  • Also append the two .agents/skills defaults from Support the .agents/skills directory #870 so users following that convention get zero-friction. ~4 lines.
  • Drop the /skill paths subcommand tree, the Web-UI input, the dashboard panel changes, and the new custom scope — entries from customSkillRoots can just map to scope global.

That's roughly 30–50 lines total. Covers both #870's zero-friction case AND your "point me at my Claude skills" case, without the friction (or the UI surface) you and the issue author both flagged.

Want to slim this PR down to that shape, or open a separate issue first so we can settle the scope before more work?

The React-import fix in tests/plan-confirm.test.tsx:3 stays welcome regardless.

@esengine

Copy link
Copy Markdown
Owner

On reflection — let's just ship this. Your point about variance across agent CLIs is valid, tests are thorough, and the surface I was pushing back on is genuinely useful for the multi-CLI setup case. Thanks for pushing back, it was the right call.

Merging now. I'll follow up with a tiny PR appending .agents/skills to the default roots so users on that specific convention also get zero-friction discovery on top of your configurable system — that's what cleanly closes #870 (the title here claimed it, but as-is a user with existing ~/.agents/skills still has to configure the setting).

@esengine esengine merged commit 6c6c8cc into esengine:main May 15, 2026
3 checks passed
esengine added a commit that referenced this pull request May 15, 2026
…870) (#932)

* feat(skills): auto-discover .agents/skills as a default root

Closes #870. The configurable-paths system from #925 lets users point at
any directory, but a user with existing skills already sitting in
`~/.agents/skills` or `<project>/.agents/skills` still has to find that
setting and configure it — which is exactly the friction the original
issue asked us to avoid.

Append `.agents/skills` to the default discovery list in
`SkillStore.roots()` at both project and global scope, alongside the
existing `.reasonix/skills` entries. Anything sitting in the
skills.sh-style convention now just works on first launch.

* test(settings): make skillPaths absolute-path assertion platform-agnostic

The combined-POST test from #925 asserts `resolved: "/opt/skills"` for an
input of `/opt/skills`, which only holds on POSIX. On Windows `/opt/skills`
isn't an absolute path — `path.resolve` rebases it against the current
drive and returns `F:\opt\skills` (or whatever `CWD`'s drive is). Same
behavior as the production code, just the test forgot to mirror it.

Wrap the expected `resolved` in `resolve(absolute)` so both the
production resolver and the test compute the value through the same
function. Linux output unchanged.

(This would have been caught by the matrix CI from #926, but #925's PR
build ran a few minutes before that landed.)

---------

Co-authored-by: reasonix <reasonix@deepseek.com>
ChasLui pushed a commit to ChasLui/DeepSeek-Reasonix that referenced this pull request May 23, 2026
…#925)

* feat(skills): support custom skill roots

* chore(tests): use type-only react import
ChasLui pushed a commit to ChasLui/DeepSeek-Reasonix that referenced this pull request May 23, 2026
…sengine#870) (esengine#932)

* feat(skills): auto-discover .agents/skills as a default root

Closes esengine#870. The configurable-paths system from esengine#925 lets users point at
any directory, but a user with existing skills already sitting in
`~/.agents/skills` or `<project>/.agents/skills` still has to find that
setting and configure it — which is exactly the friction the original
issue asked us to avoid.

Append `.agents/skills` to the default discovery list in
`SkillStore.roots()` at both project and global scope, alongside the
existing `.reasonix/skills` entries. Anything sitting in the
skills.sh-style convention now just works on first launch.

* test(settings): make skillPaths absolute-path assertion platform-agnostic

The combined-POST test from esengine#925 asserts `resolved: "/opt/skills"` for an
input of `/opt/skills`, which only holds on POSIX. On Windows `/opt/skills`
isn't an absolute path — `path.resolve` rebases it against the current
drive and returns `F:\opt\skills` (or whatever `CWD`'s drive is). Same
behavior as the production code, just the test forgot to mirror it.

Wrap the expected `resolved` in `resolve(absolute)` so both the
production resolver and the test compute the value through the same
function. Linux output unchanged.

(This would have been caught by the matrix CI from esengine#926, but esengine#925's PR
build ran a few minutes before that landed.)

---------

Co-authored-by: reasonix <reasonix@deepseek.com>
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.

2 participants