Skip to content

feat(opencode): add reload_skills tool and live skill management - #16

Merged
shoootyou merged 4 commits into
devfrom
feat/reload-skills-tool
Jun 14, 2026
Merged

feat(opencode): add reload_skills tool and live skill management#16
shoootyou merged 4 commits into
devfrom
feat/reload-skills-tool

Conversation

@shoootyou

Copy link
Copy Markdown
Owner

Adds an explicit reload_skills tool that rescans configured skill directories and makes newly created or modified skills available immediately — no restart required.

What changes

  • Skill.Service: state moves from a one-time init snapshot to a Ref<State> with an explicit refresh() method
  • reload_skills tool: rescans and returns the updated skill list
  • Command.Service: reads skills live on each list()/get() call so the slash command picker reflects changes immediately
  • Web UI: skill invocations show [skill] name for clear identification in the chat

Usage

1. Create a SKILL.md file on disk
2. Call `reload_skills` tool
3. Call `skill("name")` — available in the same turn

Security fixes included

  • Path traversal prevention in URL skill discovery
  • Prototype pollution guard (Object.create(null)) for skill name records
  • XML escaping in fmt() verbose output to prevent prompt injection

Closes anomalyco#27956, anomalyco#6719, anomalyco#23304

@shoootyou shoootyou self-assigned this Jun 14, 2026
shoootyou and others added 3 commits June 14, 2026 09:35
Replaces the one-time InstanceState snapshot with a Ref<State> that can
be updated atomically. Adds refresh() which rescans all configured skill
directories and updates the Ref without restarting the process.

Security fixes included:
- Prevent path traversal in URL-sourced skill discovery (skill.name and
  file paths validated against cache boundary before download)
- Use Object.create(null) for skills Record to prevent prototype pollution
  via __proto__ skill names
- XML-escape skill name and description in fmt() verbose output to prevent
  prompt injection in the LLM system context

Co-authored-by: yui-soul <yui-soul@users.noreply.github.com>
Adds a reload_skills tool that calls Skill.Service.refresh() and
returns the updated skill list immediately. Skills created or modified
during an active session are available without restart.

- Command.Service.list() and get() now read skills live from Skill.Service
  (Ref.get, no I/O) instead of a one-time init snapshot — new skills
  appear in the slash command picker immediately after reload_skills runs
- Publishes command.catalog.updated event after refresh; stream transport
  detects this and calls loadCatalog() to update the TUI picker

Closes anomalyco#27956, anomalyco#6719, anomalyco#23304, anomalyco#29266

Co-authored-by: yui-soul <yui-soul@users.noreply.github.com>
Skill invocations in the web UI now show `[skill]  name` instead of
just the skill name, making them clearly identifiable in the chat.

Co-authored-by: yui-soul <yui-soul@users.noreply.github.com>
@shoootyou
shoootyou force-pushed the feat/reload-skills-tool branch from 8cfe339 to 91c7ab4 Compare June 14, 2026 09:36
Registers /reload as a built-in slash command in Command.Service.
When invoked, the template instructs the LLM to call the reload_skills
tool — rescanning configured skill directories and refreshing the
available skill list without restarting the session.

Co-authored-by: yui-soul <yui-soul@users.noreply.github.com>
@shoootyou
shoootyou force-pushed the feat/reload-skills-tool branch from 815358a to cf832c7 Compare June 14, 2026 09:49
@shoootyou
shoootyou merged commit 84d07ee into dev Jun 14, 2026
@shoootyou
shoootyou deleted the feat/reload-skills-tool branch June 14, 2026 09:52
@shoootyou
shoootyou restored the feat/reload-skills-tool branch June 14, 2026 09:52
@shoootyou
shoootyou deleted the feat/reload-skills-tool branch July 5, 2026 07:57
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.

Feature Request: Support hot-reloading skills or add a /reload-skills command

1 participant