Claude Code Plugins
TumbleTrove Desktop has first-class Claude Code integration: packages can ship Claude Code plugins (skills, commands, agents, hooks, MCP servers), and the launcher aggregates them into a per-project Claude Code marketplace on every project prepare. When you work on that project in Claude Code, the packages' tooling is right there.
Why
Claude Code discovers plugins via marketplaces — JSON manifests registered under ~/.claude/plugins/known_marketplaces.json. Managing those registrations by hand, per-project, per-package, gets painful fast.
The TumbleTrove launcher does it for you: when you prepare a project, it scans every installed package for Claude plugins and emits one marketplace per project. Claude Code picks them up on next run.
Declaring plugins in a package
A package declares plugin directories via the TT_CLAUDE_PLUGINS environment variable in its hpm.toml:
[package]
name = "studio-workflow"
version = "1.2.0"
[env]
TT_CLAUDE_PLUGINS = "{package_dir}/claude/rigging:{package_dir}/claude/rendering"The value is a path-separated list of absolute directory paths (: on macOS/Linux, ; on Windows). HPM expands {package_dir} to the package's install location at prepare time.
Each listed directory must be a valid Claude Code plugin — i.e., contain a .claude-plugin/plugin.json at its root, plus any of the usual plugin assets:
claude/rigging/
├── .claude-plugin/plugin.json
├── skills/
├── commands/
├── agents/
├── hooks/
└── .mcp.jsonYou can author these plugins with any tooling you like; TumbleTrove just shuttles the paths to Claude Code. See the Claude Code plugins reference for the plugin format.
What happens on prepare
When you run Prepare on a project:
The launcher reads
TT_CLAUDE_PLUGINSfrom every installed package's env vars.Entries are split on the platform path separator, canonicalized, and deduplicated.
Non-absolute paths and paths that don't resolve are skipped (logged as warnings).
A marketplace is built under an app-owned directory,
~/.tumbletrove/claude-projects/tumbletrove-<scope>-<project>/. Each plugin's directory is copied into that marketplace root and referenced by a./relativesource:json{ "name": "tumbletrove-personal-my-project", "owner": { "name": "TumbleTrove" }, "plugins": [ { "name": "rigging", "source": "./rigging", "description": "Claude Code plugin shipped with studio-workflow" } ] }Claude Code only installs a local plugin whose
sourceis a relative path inside the marketplace root — absolute paths and out-of-root symlinks are rejected — so the plugin content is copied in rather than referenced in place. The marketplace lives in an app-owned directory (not your project folder) to keep your project tree clean.If the Enable Claude Code plugin discovery setting is on (Settings → General), the marketplace root is appended to
~/.claude/plugins/known_marketplaces.json. If the setting is off, the marketplace is still built — you can register it manually withclaude plugin marketplace add ~/.tumbletrove/claude-projects/tumbletrove-<scope>-<project>.
The marketplace name is always qualified as tumbletrove-<scope>-<project> to avoid collisions between same-named projects in different scopes (personal vs. team vs. org).
If no packages in the project declare any plugins, the project's app-owned marketplace dir is removed and its registration dropped.
Turning discovery on or off
Settings → General → Enable Claude Code plugin discovery.
- On — every
Prepareregisters (or re-registers) the project's marketplace with Claude Code automatically. - Off — the marketplace is still built (under
~/.tumbletrove/claude-projects/) for manual registration. Existing registrations are not auto-removed.
This toggle is per-user, not per-project. Flip it off if you want to control Claude's marketplace list by hand.
Using the plugins
After a prepare with discovery on, the project's marketplace is registered with Claude Code user-wide. Because it lives in an app-owned directory, it isn't tied to your project folder or your shell's working directory — you can use it from any Claude Code session:
- In Claude Code, run
/plugin— the project's marketplace appears astumbletrove-<scope>-<project>. - Install a plugin from it:
/plugin install <name>@tumbletrove-<scope>-<project>. Claude Code copies the plugin into its own cache. (First time only; it stays installed afterward.) - Once installed, skills surface on relevant prompts; commands appear in the slash-command list; hooks fire on the events they're bound to. Each plugin's docs (its own
README.md) govern exact usage.
Example: a studio workflow package
A fictional studio-workflow package might ship:
skills/rigging-review— a Claude skill that reviews.hdafiles against studio rigging standards.commands/publish-shot—/publish-shotto bundle and upload a shot to the review system.hooks/on-file-write— a hook that lints.pyfiles on save..mcp.json— registers the studio asset MCP server.
Add studio-workflow to a project, prepare, then install its plugin from the project's marketplace in Claude Code (/plugin install …) — all of the above are live.
Troubleshooting
Plugins not showing up in Claude Code? Check:
Settings → General → Enable Claude Code plugin discoveryis on.- The project has been prepared since you added the package.
~/.tumbletrove/claude-projects/tumbletrove-<scope>-<project>/.claude-plugin/marketplace.jsonexists and looks right.~/.claude/plugins/known_marketplaces.jsonlists that project's marketplace path.- You've installed the plugin in Claude Code (
/plugin install <name>@tumbletrove-<scope>-<project>) — registration only makes it available to install; it isn't active until installed.
Restart Claude Code after a fresh registration — it reads the marketplaces list on startup.
Warning in logs about non-absolute paths? Your package's TT_CLAUDE_PLUGINS contains a relative path. Use {package_dir}/... so HPM expands it to an absolute path at prepare time.
Paths with special characters? Directory names are slugified (lowercase, non-alphanumeric → hyphens) when used as the plugin name in the marketplace manifest. The actual source path is preserved as-is. If two packages ship plugins with directory names that slugify to the same string, Claude Code may complain; rename one of the directories.
Related
- Projects — preparing projects is what triggers marketplace generation
- Scripts — another pattern for package-shipped automation
- Claude Code plugins reference — plugin format and capabilities