33Status: ** implemented** — the unified, manifest-driven system described below is
44in place. Plugins self-describe with a ` manifest ` (` kind: web | command | tool ` ),
55are auto-discovered (plus explicit ` pluginPaths ` ), are wired in only when
6- explicitly enabled, and are managed through the ` /plugins ` UI. The sections
6+ explicitly enabled (with one exception: a repo-origin plugin whose manifest
7+ sets ` defaultEnabled: true ` auto-enables when the settings key is missing),
8+ and are managed through the ` /plugins ` UI. The sections
79below double as the reference for the system and the record of why it is shaped
810this way. (The "Current state (the problem)" section is retained as the
911historical motivation.)
@@ -17,7 +19,7 @@ registered in global settings (`pluginPaths`), so consent is global once granted
1719
1820| Origin | Path | Auto-trusted? | Trust store |
1921| ---| ---| ---| ---|
20- | ` repo ` | Product-shipped ` plugins/ ` next to the Corbits Code binary | Yes | — |
22+ | ` repo ` | Product-shipped ` plugins/ ` next to the source root, ` dist/plugins ` , or ` dirname(execPath)/plugins ` — never session cwd | Yes | — |
2123| ` user ` | ` ~/.corbits/plugins/ ` | Yes (user home) | — |
2224| ` user ` (Claude) | Absolute ` installPath ` under ` ~/.claude/plugins/ ` from ` installed_plugins.json ` when ` settings.discoverClaudePlugins ` is true | Yes (user home; still disabled until enable; data-only load only) | — |
2325| ` project ` | ` <cwd>/.corbits/plugins/ ` | ** No** — per working directory | ` ~/.corbits/trust/<cwd-hash>.json ` |
@@ -152,7 +154,7 @@ A module with no valid manifest is ignored (not silently half-loaded).
152154
153155```
154156discoverPlugins(cwd) =
155- repo plugins/ (built-in)
157+ repo plugins/ (built-in: source root / dist/plugins / dirname(execPath)/plugins — never session cwd )
156158 + <cwd>/.corbits/plugins/
157159 + ~/.corbits/plugins/
158160 + settings.pluginPaths (explicit file/dir paths, added via /plugins)
@@ -223,8 +225,11 @@ shape.
223225### Command plugins and enable gating
224226
225227- ` command ` plugins (` commandPlugin ` export) register their slash commands only
226- when ` settings.plugins[id].enabled ` is true , via ` registerCommandPlugins `
228+ when the plugin is enabled , via ` registerCommandPlugins `
227229 (` src/plugins/register.ts ` ); enabling one in ` /plugins ` wires it in live.
230+ Enablement is ` settings.plugins[id].enabled === true ` , except the Decision 3
231+ repo-origin ` defaultEnabled ` case below (the first-party ` corbits-skills `
232+ catalog auto-enables when the settings key is missing).
228233- Commands may also be authored as data-only markdown (see below).
229234- Legacy ` settings.workflowPlugins ` / ` agentPlugins ` specifier arrays and their
230235 loaders are removed; everything flows through discovery + ` pluginPaths ` .
@@ -297,17 +302,29 @@ shape.
297302 exist. So a marketplace plugin (e.g. ` agents/plugins/gaas ` ) loads as-is via
298303 ` /plugins ` add-by-path: its ` agents/*.md ` wire as profiles and its
299304 ` skills/*/SKILL.md ` resolve through ` use_skill ` with no porting.
300- - ** Skill-commands.** Every skill in an enabled plugin is also surfaced as a
305+ - ** Skill-commands.** Skills in an enabled plugin are also surfaced as a
301306 ` /<skill-name> [args] ` slash command that sends the skill body (plus args) to
302- the agent. ` loadSkillCommands ` (` src/plugins/skill-commands.ts ` ) synthesizes
303- them; they merge into the same ` commandPlugin ` as ` commands/*.md ` . Frontmatter
307+ the agent, unless frontmatter sets ` user-invocable: false ` . ` loadSkillCommands `
308+ (` src/plugins/skill-commands.ts ` ) synthesizes them and skips that tag; they
309+ merge into the same ` commandPlugin ` as ` commands/*.md ` . Untagged skills still
310+ become slashes (marketplace backward compatibility). Frontmatter
304311 ` argument-hint ` is preserved so the TUI can show greyed arg guidance (e.g.
305- ` /linear- create ` → ` [description] [--from-doc] ` ). This is an additional
312+ ` /create-issue ` → ` [description] [--from-doc] ` ). This is an additional
306313 surface: ` discoverSkills ` is unchanged, so the model can still auto-invoke any
307- skill via ` use_skill ` — the slash command is a direct user entry point on top.
308- (An earlier revision gated this on the ` disable-model-invocation ` /
309- ` user-invocable ` frontmatter tags; that gate was dropped so untagged skills
310- like ` linear-create ` are reachable too.)
314+ skill via ` use_skill ` — including first-party recipes that are not operator
315+ slashes (` dispatch ` , ` git-rebase ` , ` linear-issue-workflow ` , ` style ` ,
316+ ` philosophy ` , ` typescript ` , ` opsh ` ). The slash command is a direct user entry
317+ point on top.
318+ - ** First-party catalog.** ` plugins/corbits-skills/ ` (id ` corbits-skills ` ,
319+ kind ` command ` , ` defaultEnabled: true ` ) is the bundled skill catalog. Origin
320+ ` repo ` is auto-trusted. Auto-enable applies only when ` origin === "repo" ` AND
321+ ` manifest.defaultEnabled ` AND the settings key is missing; an explicit
322+ ` enabled: false ` still disables. Marketplace ` defaultEnabled ` is ignored.
323+ The id is not ` gaas ` , so a later marketplace plugin named gaas cannot replace
324+ the module. Slash-command registration is first-wins (built-ins, then plugins
325+ in discovery order: repo before user/project/path), so ` /implement ` stays
326+ first-party when both the catalog and a marketplace plugin are enabled.
327+ ` discoverSkills ` is already first-wins (plugin dirs before project).
311328- ** Mixed plugins wire both sides.** A plugin contributing agents AND commands
312329 (the common marketplace shape) infers ` kind: "agent" ` so profiles wire, and
313330 ` isEnabledCommandPlugin ` (` src/plugins/register.ts ` ) also wires commands for
@@ -352,10 +369,13 @@ loaded via `pluginPaths`.
352369 ` settings.pluginPaths ` .
3533702 . ** ` settings.web ` stays** as the only kind-selector for now; generalize to
354371 ` settings.active[kind] ` only if another kind needs "exactly one active."
355- 3 . ** Always explicit enable.** Every discovered plugin (built-in or user-added)
356- starts disabled. Nothing is wired in until ` settings.plugins[id].enabled ` is
357- true — set in ` /plugins ` . (Note: this changes today's behavior where repo
358- command plugins auto-load; they must now be enabled.)
372+ 3 . ** Explicit enable, with one repo-origin exception.** Every discovered plugin
373+ starts disabled unless all of the following hold: ` origin === "repo" ` ,
374+ ` manifest.defaultEnabled ` is true, and ` settings.plugins[id] ` is missing.
375+ Then it auto-enables. An explicit ` enabled: false ` still disables. Marketplace
376+ (user / project / path / claude) ` defaultEnabled ` is ignored — those plugins
377+ stay opt-in via ` /plugins ` . The first-party catalog ` plugins/corbits-skills/ `
378+ (id ` corbits-skills ` ) is the plugin this exception exists for.
3593794 . ** Tool plugins require explicit consent.** Enabling a ` kind: "tool" ` plugin
360380 prompts a one-time confirmation in ` /plugins ` before its tools are wired in
361381 (they run in-process — the highest-trust surface). Consent is recorded in
0 commit comments