Plugin version and skill attribution - #280
Draft
Fluzko wants to merge 14 commits into
Draft
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
depends on #277
What does this PR do?
Until now, Symposium only ever handed an agent individual skill files. It copied each
SKILL.mdit found into.claude/skills/,.agents/skills/, and so on. The agent saw a pileof skills with no idea which project or crate they came from, and no version attached to any
of them.
Most agents have since grown a real unit for this: a plugin, which is one folder holding a small
manifest (name, version, description) plus the skills that belong to it. Claude Code, Codex
CLI, Copilot CLI, and Gemini CLI all understand that folder. This PR makes Symposium speak
that language.
After each
cargo agents sync, Symposium now:the skills that actually passed their conditions. The agent never sees a rule or a
condition, only the finished content.
entry, a config file, a copy into its own directory, or nothing at all for Gemini, which
just reads the folder).
(Kiro, OpenCode, Goose), and for project-specific plugins on agents that cannot scope a
plugin to one project.
are removed. Anything you created by hand is never touched.
Practical effect: your agent now shows skills grouped and named by where they came from
(
pdf-tools:extract-tablesinstead of a bareextract-tables), with a version, and adescription.
Three other things it brings
You can now use externally authored plugin packages. A folder containing a
plugin.json(the agent-plugins.org format) is now a validSymposium plugin, the same as one with a
SYMPOSIUM.toml. So a plugin written for Claude Codeor Codex by someone who has never heard of Symposium can be dropped in and used, and it will
reach every agent you have configured, not just the one it was written for.
Symposium works outside a Rust project. Previously
cargo agents syncneeded a Cargoworkspace. Now, if there is no workspace, it still installs the plugins you enabled globally
instead of refusing to run. Useful if you keep a set of personal skills and want them
everywhere.
Plugins carry identity. Version and description now flow from a plugin's manifest through
to
search,status, and the agent-facing manifest, and each installed skill records whichplugin contributed it.
statusandsearchalso tell you which kind of manifest defined aplugin, and mark a plugin as
dormantwhen it is installed but waiting to be enabled.Also fixes a data-loss bug found while building this: if a plugin registry could not be read
(an unmounted drive, a network share that was down), Symposium used to read the empty result
as "these plugins were deleted" and uninstall them from every agent. It now leaves everything
in place when a source is unreadable.
How to use it
Nothing, for the common case
Run a sync and the new behaviour is already in effect:
To see what happened:
You will see lines like
compiled pdf-tools (project, 3 skills)followed bydelivered pdf-tools (project) to claude.Built folders live in
.symposium/plugins/inside your project (git-ignored), and in~/.symposium/installed/for the ones enabled everywhere. Both are managed by Symposium; youdo not edit them.
Install an externally authored plugin package
Put the package in your personal plugin directory, one folder per plugin:
mkdir -p ~/.symposium/plugins/portable-toolsThat folder needs a
plugin.jsonplus askills/subfolder holding one folder per skill(the format fixes that location, so the manifest does not point at it):
{ "name": "portable-tools", "version": "2.1.0", "description": "Tools I want in every project" }Because the package format has no way to say when a plugin should be active, Symposium reads
that from an optional section of its own:
{ "name": "portable-tools", "version": "2.1.0", "extensions": { "dev.symposium": { "depends-on": ["serde"] } } }That makes the plugin apply only in projects depending on
serde. Leave the section out andthe plugin stays dormant until you enable it by name:
Add
--globalto enable it in every project rather than just this one:The same
plugin.jsonworks in two other places: in a workspace member's directory (activewhenever that member is part of the project), and inside a crate you depend on (offered to
you for consent, like any other dependency-provided plugin).
Check what is going on
Lists every plugin, its version, the kind of manifest that defined it, and whether it is
active, dormant, awaiting your consent, or declined.
Search now shows each hit's version, description, and manifest kind, and flags dormant ones.
Validates a plugin folder, and now labels
plugin.jsonpackages asagent pluginso you cantell at a glance which format was read.
Use skills outside a Rust project
Enable what you want globally, then sync from anywhere:
Notes for reviewers
about it can vary per project. Otherwise two projects would keep undoing each other's work,
since a global install is visible everywhere while cleanup removes whatever the current sync
did not write.
because it only counts a plugin as installed once its own machine-managed config records it.
That call is disabled in tests.
md/design/agents.md,module-structure.md,important-flows.md) are updatedalongside the code.
Disclosure questions
AI disclosure.
Questions for reviewers.