Skip to content

fix: skill upload 200-file cap + packaging hygiene (3.0.1)#242

Merged
mvanhorn merged 8 commits intomainfrom
fix/skill-upload-200-file-limit
Apr 14, 2026
Merged

fix: skill upload 200-file cap + packaging hygiene (3.0.1)#242
mvanhorn merged 8 commits intomainfrom
fix/skill-upload-200-file-limit

Conversation

@mvanhorn
Copy link
Copy Markdown
Owner

Summary

claude.ai's "Upload skill" UI rejects zips with more than 200 files. Zipping this repo produced 406 files, so direct upload failed. This PR fixes that plus related packaging hygiene.

  • Removes unused root vendor/ (215 files from accidental PR feat: add Xiaohongshu source + Reddit public fallback (and probe reliability fix) #48 commit; real vendored X client stays at scripts/lib/vendor/bird-search/)
  • Removes legacy top-level plans/ (superseded by docs/plans/)
  • Adds .gitattributes with export-ignore entries that mirror Anthropic's canonical skill-packager exclusions plus repo-specific dev/docs/media/internal-skill excludes
  • Adds scripts/build-skill.sh - one-command builder that produces dist/last30days.skill with a single top-level last30days/ directory, enforces =200 files and exactly one SKILL.md, and refuses dirty-tree builds
  • Trims SKILL.md description from 228 to 167 chars (Anthropic caps at 200)
  • Bumps version to 3.0.1 across SKILL.md, skills/last30days/SKILL.md, plugin.json, gemini-extension.json

Verification

  • bash scripts/build-skill.sh - 90 files, 264K, exactly one SKILL.md, no symlinks in archive
  • python3 -m pytest tests/test_bird_x.py - 9 passed (proves bird-search runtime intact)
  • python3 -m pytest tests/test_version_consistency.py - 2 passed (version alignment)
  • Runtime import audit: all non-stdlib imports resolve to lib.*, store, or scripts.* - zero reach into excluded paths
  • Pre-existing test_store.py / test_watchlist_commands.py failures confirmed present on main before these changes (not introduced here)

Plan

Full plan at docs/plans/2026-04-14-001-fix-skill-upload-200-file-limit-plan.md.

Out of scope (separate PRs)

Test plan

  • Build-skill script produces valid .skill file
  • Archive contains exactly one SKILL.md at last30days/SKILL.md
  • No symlinks or nested skills/ directories in archive
  • bird_x tests pass after vendor/ delete
  • Version consistency tests pass after bump
  • Manual: upload dist/last30days.skill to claude.ai via the "Upload skill" UI and confirm acceptance (the final rejection-risk gate)

Post-Deploy Monitoring & Validation

No runtime behavior changes ship in this PR - it is pure packaging hygiene and metadata updates. Skill consumers (Claude Code plugin via GitHub URL, ClawHub publish path, Gemini extension) see the same runtime.

Validation:

  • Watch the next 48 hours of GitHub issues for anyone reporting install/load failures on 3.0.1 vs 3.0.0
  • If the manual claude.ai upload test passes, the primary goal is met
  • Rollback trigger: any report that the plugin install via Claude Code or gemini extensions install starts failing on 3.0.1. Mitigation: revert the version bump and republish 3.0.0 with the packaging fixes.

Owner: @mvanhorn. Window: 48 hours post-merge.

Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com

Root vendor/package/ was an accidentally committed extracted npm tarball
(steipete-bird-0.8.0). Zero importers: the real vendored X client lives
at scripts/lib/vendor/bird-search/, referenced by scripts/lib/bird_x.py
and tests/test_bird_x.py.

Removes 215 files + 1 .tgz, dropping repo from 406 to 191 files and
clearing the claude.ai skill-upload 200-file cap.

Adds /vendor/ to .gitignore (leading slash so scripts/lib/vendor/ is unaffected).
Both plans describe work that was already shipped:
- feat-add-websearch-source.md - websearch is in the v3 pipeline (scripts/lib/perplexity.py etc)
- fix-strict-date-filtering.md - date filtering is enforced in scripts/lib/dates.py

New planning goes in docs/plans/ following the ce:plan convention.
…kill

Wraps git archive with --prefix=last30days/ so the zip contains a single
top-level skill folder matching SKILL.md's name: frontmatter. Enforces:

- refuses to build with a dirty working tree (prevents shipping untracked changes)
- fails if zip exceeds 200 files (claude.ai's empirical upload cap)
- fails if zip contains more than one SKILL.md (avoids name: confusion)

Output at dist/last30days.skill (gitignored).
Atomic bump across all four manifests:
- SKILL.md (root)
- skills/last30days/SKILL.md (internal spec)
- .claude-plugin/plugin.json
- gemini-extension.json

CHANGELOG entry documents the skill-upload packaging fix, vendor/ removal,
legacy plans/ removal, and the new scripts/build-skill.sh builder.
@mvanhorn mvanhorn merged commit 9f3be8b into main Apr 14, 2026
@mvanhorn mvanhorn deleted the fix/skill-upload-200-file-limit branch April 14, 2026 16:24
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.

1 participant