fix: correct skill-only .skill packaging structure in Step 6

This commit is contained in:
2026-05-05 11:34:54 -05:00
parent be67cd4b8e
commit 011763ca97
@@ -174,10 +174,11 @@ Both destinations are required. Confirm both are written before proceeding.
---
## Step 6 — Package the .plugin File (skip for skill-only with no MCP server)
## Step 6 — Package the .skill / .plugin File
If the plugin has an MCP server component (has `.mcp.json` and a `server/` directory),
build a fresh `.plugin` package from the downloaded repo archive:
### For plugins with an MCP server (has `.mcp.json` and `server/` directory)
Build a `.plugin` package from the repo. No structural constraints on top-level folders:
```bash
cd /tmp/plugin-repo/[repo-folder-name]
@@ -189,24 +190,53 @@ zip -r /tmp/[plugin-name]-v[version].plugin \
# Add any additional skills/ subdirectories if multiple skills exist
```
For skill-only plugins (no `server/` directory, no `.mcp.json`), package only the skill files:
### For skill-only packages (no `server/` directory, no `.mcp.json`)
**Critical structure requirement:** The zip must contain **exactly one top-level folder**
with `SKILL.md` directly inside it. Do NOT zip `.claude-plugin/` and `skills/` as separate
top-level entries — the upload validator will reject it with "Zip must contain exactly one
top-level folder" and "SKILL.md must be in the top-level folder, not nested deeper."
```bash
cd /tmp/plugin-repo/[repo-folder-name]
zip -r /tmp/[plugin-name]-v[version].plugin \
.claude-plugin/plugin.json \
# Stage into a clean directory with one top-level folder named after the skill
mkdir -p /tmp/[skill-name]-pkg/[skill-name]/
cp skills/[skill-name]/SKILL.md /tmp/[skill-name]-pkg/[skill-name]/SKILL.md
# Copy any subdirectories (references/, assets/, etc.) if present
cp -r skills/[skill-name]/references/ /tmp/[skill-name]-pkg/[skill-name]/references/
# Zip from the staging dir — SKILL.md ends up at root of the single top-level folder
cd /tmp/[skill-name]-pkg
zip -r /tmp/[skill-name]-v[version].skill [skill-name]/
```
**Verify before uploading** — contents must look like this:
```
[skill-name]/
SKILL.md ← directly here, NOT nested
references/ ← optional
*.md
```
NOT like this (will be rejected by the upload validator):
```
.claude-plugin/
plugin.json
skills/
# Include all files under skills/ recursively
[skill-name]/
SKILL.md
```
**Upload to Drive:**
Use `create_drive_file` with:
- `file_name`: `[plugin-name]-v[version].plugin`
- `file_name`: `[skill-name]-v[version].skill`
- `folder_id`: the CW-XXX folder ID from Step 4
- `mime_type`: `application/zip`
- `fileUrl`: `file:///[outputs-path]/[plugin-name]-v[version].plugin`
- `fileUrl`: `file:///[outputs-path]/[skill-name]-v[version].skill`
If an older `.plugin` file exists in the folder, trash it first:
Note: The Drive API server runs on the host, not the sandbox. Copy the file from `/tmp`
to the outputs directory first, then reference it via the host path (not the VM `/tmp` path).
If an older `.skill` or `.plugin` file exists in the folder, trash it first:
- Use `search_drive_files` to find it by name pattern in the folder
- Use `update_drive_file` with `trashed: true`
@@ -277,7 +307,7 @@ Before writing the registry row, confirm:
- [ ] README.md is in the Drive folder (check via `search_drive_files` or confirm upload ID)
- [ ] Wiki doc is in the Drive folder (confirm parent folder ID matches)
- [ ] .plugin file is in the Drive folder (or note "skill-only, no .plugin" explicitly)
- [ ] .skill/.plugin file is in the Drive folder (or note "skill-only, no .skill" explicitly)
If any artifact failed to land in the folder, resolve it before proceeding.
@@ -303,7 +333,7 @@ Adjust if the user specifies otherwise.
Report every artifact with its link:
- README location: Drive link + Git link (if pushed)
- .plugin file: Drive link and version (or "skill-only, not applicable")
- .skill/.plugin file: Drive link and version (or "skill-only, not applicable")
- Wiki Doc: Google Doc link
- Registry: link to sheet