feat(cc-config): list a plugin's skills, agents and commands by name
A plugin card showed "7 skills, 5 agents" and nothing more — the counts were the whole story, so finding out WHICH skills a plugin ships meant opening its install directory by hand. The contribution chips are now buttons: clicking one expands a list naming each artifact with its description, one surface open at a time. Commands render with their slash. Hooks stay a plain chip — a plugin's hooks are matcher/command pairs declared inline in plugin.json, not named artifacts. `contributes.items` carries the four surfaces server-side; the existing counts keep their type and are now derived from those lists, so a chip reading "3 commands" can never sit beside a list holding two. That also fixes a real blind spot. Each surface was read only from the conventional install subdirectory, but plugin.json may declare its own paths — this repo's own `ccam` lists three files under plugins/ccam/commands/ and keeps commands/ empty, so it reported zero commands. Both sources are now read and de-duplicated. A declared path resolving outside the plugin's install directory is dropped: a manifest is third-party data and must not turn the dashboard into an arbitrary file reader. Also pins the Refresh button's width: both labels share one grid cell so the button is always as wide as "Refreshing…" / "Đang làm mới…" and no longer resizes the toolbar when the state flips. Measuring the longest real string beats a min-width that would be wrong in the next language. Verified: npm run test:server (1370 tests, +6 for the new discovery), npm run test:client (457, +3 for the expand behaviour), tsc --noEmit, prettier and check-headers clean. Docs synced: docs/API.md, openapi.yaml (new CcConfigPluginItem schema), ARCHITECTURE.md, docs/PLUGINS.md.
This commit is contained in:
@@ -2288,6 +2288,18 @@ export interface CcMdItem {
|
||||
preview: string;
|
||||
}
|
||||
|
||||
/** One named artifact a plugin contributes — a skill, subagent, command or
|
||||
* output style. `name` is the frontmatter name Claude Code addresses it by
|
||||
* (`/ccam:ship-feature`, `subagent_type: qc-local`), falling back to the
|
||||
* filename when the file declares none. */
|
||||
export interface CcPluginItem {
|
||||
name: string;
|
||||
/** Frontmatter `description`; null when the file declares none. */
|
||||
description: string | null;
|
||||
/** Absolute path of the backing `.md` file. */
|
||||
file: string;
|
||||
}
|
||||
|
||||
/** Counts of what a plugin contributes to Claude Code, plus its manifest
|
||||
* metadata, embedded in {@link CcPlugin}. */
|
||||
export interface CcPluginContributions {
|
||||
@@ -2296,6 +2308,14 @@ export interface CcPluginContributions {
|
||||
commands: number;
|
||||
outputStyles: number;
|
||||
hooks: number;
|
||||
/** The same surfaces by name, so a card can list WHICH artifacts a plugin
|
||||
* ships rather than only how many. Counts above are these lists' lengths. */
|
||||
items: {
|
||||
skills: CcPluginItem[];
|
||||
agents: CcPluginItem[];
|
||||
commands: CcPluginItem[];
|
||||
outputStyles: CcPluginItem[];
|
||||
};
|
||||
/** Parsed `plugin.json` fields; null if the plugin has no manifest. */
|
||||
pluginJson: {
|
||||
name?: string;
|
||||
|
||||
Reference in New Issue
Block a user