Skip to content

fix(plugin): register kami via marketplace manifest#16

Merged
tw93 merged 1 commit into
tw93:mainfrom
qishaoyumu:fix/plugin-install-path-escape
May 4, 2026
Merged

fix(plugin): register kami via marketplace manifest#16
tw93 merged 1 commit into
tw93:mainfrom
qishaoyumu:fix/plugin-install-path-escape

Conversation

@qishaoyumu
Copy link
Copy Markdown
Contributor

fix(plugin): register kami via marketplace manifest

Background

The Claude Code plugin manifest in this repo was added in #14, originally declared as "commands": ["./SKILL.md"]. That form installs and works, but the skill's invocation name comes from the filename and ends up as /kami:SKILL.

A follow-up commit before the squash merge changed the field to "skills": ["./"], the form documented in Path behavior rules. The intent was to let the name: frontmatter in SKILL.md drive the invocation name, producing /kami:kami. But the current Claude Code client rejects "./" when parsing plugin.json, and plugin install on main fails. This PR fixes that.

After looking into it, I found that moving the same manifest fields (including skills: ["./"]) from plugin.json into the marketplace.json plugin entry with "strict": false bypasses the path validator (which only fires on the plugin.json parse path) while preserving the intended /kami:kami invocation name. That is the approach this PR takes.

Symptoms

After /plugin marketplace add tw93/Kami and /plugin install kami@kami, /reload-plugins reports:

kami (user)
  skills path escapes plugin directory: ./
  Paths in plugin.json must not use ".." to reference files outside the plugin directory
1 error during load. Run /doctor for details.

The plugin entry installs without error, but no skill registers: /kami:* matches nothing in /help, the skill count is unchanged before and after install/reload, and the skill cannot be invoked.

Root cause

.claude-plugin/plugin.json declares "skills": ["./"]. This is the form documented in Path behavior rules for cases where SKILL.md sits directly in the plugin root:

When a skill path points to a directory that contains a SKILL.md directly, for example "skills": ["./"] pointing to the plugin root, the frontmatter name field in SKILL.md determines the skill's invocation name.

But the current Claude Code path validator treats "./" as escaping the plugin root and refuses to load. The documented behavior and the client implementation diverge. The same issue is tracked upstream as anthropics/claude-code#51888 (open, with the same Path escapes plugin directory: ./ symptom on darwin).

Fix

Delete plugin.json and move the manifest fields (including "skills": ["./"]) into the marketplace.json plugin entry, marked "strict": false. From strict mode docs:

strict: false: the marketplace entry is the entire definition. […] Since this is set to false, the plugin doesn't need its own plugin.json. The marketplace entry defines everything.

A marketplace.json plugin entry can carry any field from the plugin manifest schema, including skills. This bypasses the plugin.json path validator while preserving the documented skills: ["./"] form.

Final entry shape (description unchanged):

{
  "name": "kami",
  "description": "<existing description unchanged>",
  "category": "documents",
  "source": "./",
  "homepage": "https://github.com/tw93/Kami",
  "skills": ["./"],
  "strict": false
}

Beyond fixing the bug, two minor benefits

  1. Invocation name becomes /kami:kami. When skills: ["./"] is honored, the name: frontmatter in SKILL.md becomes the skill name (per Path behavior rules). Without this fix, even falling back to commands: ["./SKILL.md"] only yields /kami:SKILL (filename-derived).

  2. Metadata drift risk decreases. For fields like version, setting it in both places leads to divergence. The docs call this out:

    Avoid setting version in both plugin.json and the marketplace entry. The plugin.json value always wins silently, so a stale manifest version can mask a version you set in marketplace.json.

Why kami needs an explicit path entry

kami is a single-skill flat repo: SKILL.md sits at the repo root alongside references/, assets/templates/, and scripts/, with no skills/<name>/ subdirectory.

Per File locations reference, Claude Code's auto-discovery scans only skills/<name>/SKILL.md and commands/*.md by default. Without an explicit path entry, the plugin installs but registers zero skills, with no error. (This is also why dropping plugin.json Waza-style is not enough for kami on its own: Waza has a real skills/<name>/ tree to be discovered, kami doesn't, so kami needs skills: ["./"] to make the root SKILL.md visible.)

Considered but not taken: restructure to skills/kami/SKILL.md

Another option is to abandon the flat layout and use the default skill subdirectory layout:

skills/
└── kami/
    ├── SKILL.md
    ├── references/
    ├── assets/
    └── ...

That would also unblock install, and the manifest could omit skills/commands entirely. I chose not to take this route, because moving SKILL.md would touch three workflows that need separate verification:

  • npx skills add tw93/kami is the public install command documented in README.md, index*.html, and llms.txt. The skills CLI's behavior with SKILL.md not at the repo root needs separate verification.
  • The Claude Desktop ZIP is built by scripts/package-skill.sh from the repo root, and would need to be re-pointed at skills/kami/.
  • scripts/build.py and the relative references in SKILL.md to references/, assets/templates/, assets/diagrams/, and CHEATSHEET.md all assume cwd = repo root.

The restructure is reasonable and worth doing, but as a separate, deliberate decision rather than a side effect of unblocking install. Happy to follow up with a dedicated PR if you'd prefer that direction.

Verified

Two install paths covered

  • Local path: /plugin marketplace add /local/path/to/Kami
  • Remote fork @Branch: /plugin marketplace add qishaoyumu/Kami@fix/plugin-install-path-escape

Identical results on both paths. Each manifest variant was tested from a clean uninstall + marketplace remove state.

Check Before: plugin.json with skills: ["./"] After: marketplace-only with skills: ["./"], strict: false
Manifest shape plugin.json + marketplace.json entry marketplace.json entry only
/plugin marketplace add OK OK
/plugin install kami@kami command returns OK command returns OK
/reload-plugins 1 error during load (skills path escape) clean, no errors
Skill registration none registered (load failed during path validation) kami:kami registered
/help namespace no /kami:* entries /kami listed with description
Skill invocation No commands match "/kami:*" invokes SKILL.md content

Repro (each manifest variant tested from a clean uninstall + marketplace-remove state):

/plugin uninstall kami@kami
/plugin marketplace remove kami
/plugin marketplace add /path/to/Kami
/plugin install kami@kami
/reload-plugins
/kami:kami

Scope

Final diff against main:

.claude-plugin/marketplace.json: adds skills and strict
.claude-plugin/plugin.json:      deleted

Nothing in scripts/, assets/, references/, SKILL.md, README.md, index*.html, or llms.txt changes. Non-marketplace install paths (npx skills add, Claude Desktop ZIP) stay out of scope and continue to work because SKILL.md remains at the repo root.

Move the plugin manifest from .claude-plugin/plugin.json into the
marketplace.json plugin entry with strict: false. Carrying
skills: ["./"] in the marketplace entry bypasses the plugin.json
path validator that currently rejects "./" with "skills path escapes
plugin directory" (anthropics/claude-code#51888), and lets the
SKILL.md frontmatter name: drive the idiomatic /kami:kami invocation
name.
@vercel
Copy link
Copy Markdown

vercel Bot commented May 4, 2026

@qishaoyumu is attempting to deploy a commit to the Tw93 Team on Vercel.

A member of the Team first needs to authorize it.

@tw93 tw93 merged commit 361d279 into tw93:main May 4, 2026
1 check failed
@tw93
Copy link
Copy Markdown
Owner

tw93 commented May 4, 2026

@qishaoyumu Thank you for the detailed investigation and the clean fix. I merged this PR, and the marketplace manifest update is now on main.

I also refreshed the latest V1.4.0 release asset so users installing from the release ZIP get this fix directly.

@qishaoyumu qishaoyumu deleted the fix/plugin-install-path-escape branch May 5, 2026 06:29
tw93 added a commit that referenced this pull request May 13, 2026
- Section Header and Code Card components added to design.md + en.md
- Deck Recipe (R1-R2, R4-R10) added as design.md section 8
- --slide-pad: 80px spacing token added to styles.css
- demo-agent-slides.html updated to 7 slides with Code Card demo
- slides.py / slides-en.py: remove italic, fix page_num, clean up
- production.md: correct BRAND color (coral -> ink-blue), fix italic ref,
  add pitfall #16 slide letter-spacing halved
- writing.md, CHEATSHEET.md, SKILL.md, CLAUDE.md: prose polish,
  remove emoji contrast markers, nine-rule count sync
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.

2 participants