AGENTS.md
This file provides guidance to AI coding agents working on the wittyhub CLI codebase.
Project Overview
wittyhub is the CLI for the open agent skills ecosystem.
Commands
| Command | Description |
|---|---|
wittyhub |
Show banner with available commands |
wittyhub add <pkg> |
Install skills from git repos, URLs, or local paths |
wittyhub use <pkg>@<skill> |
Use one skill without installing |
wittyhub experimental_install |
Restore skills from skills-lock.json |
wittyhub experimental_sync |
Sync skills from node_modules into agent dirs |
wittyhub list |
List installed skills (alias: ls) |
wittyhub update [skills...] |
Update skills to latest versions |
wittyhub init [name] |
Create a new SKILL.md template |
Aliases: wittyhub a works for add. wittyhub i, wittyhub install (no args) restore from skills-lock.json. wittyhub ls works for list. wittyhub experimental_install restores from skills-lock.json. wittyhub experimental_sync crawls node_modules for skills.
Architecture
src/
├── cli.ts # Main entry point, command routing, init/check/update
├── cli.test.ts # CLI tests
├── add.ts # Core add command logic
├── add-prompt.test.ts # Add prompt behavior tests
├── add.test.ts # Add command tests
├── constants.ts # Shared constants
├── find.ts # Find/search command
├── list.ts # List installed skills command
├── list.test.ts # List command tests
├── remove.ts # Remove command implementation
├── remove.test.ts # Remove command tests
├── agents.ts # Agent definitions and detection
├── installer.ts # Skill installation logic (symlink/copy) + listInstalledSkills
├── skills.ts # Skill discovery and parsing
├── skill-lock.ts # Global lock file management (~/.agents/.skill-lock.json)
├── local-lock.ts # Local lock file management (skills-lock.json, checked in)
├── sync.ts # Sync command - crawl node_modules for skills
├── source-parser.ts # Parse git URLs, GitHub shorthand, local paths
├── git.ts # Git clone operations
├── telemetry.ts # Anonymous usage tracking
├── types.ts # TypeScript types
├── mintlify.ts # Mintlify skill fetching (legacy)
├── plugin-manifest.ts # Plugin manifest discovery support
├── prompts/ # Interactive prompt helpers
│ └── search-multiselect.ts
├── providers/ # Remote skill providers (GitHub, HuggingFace, Mintlify)
│ ├── index.ts
│ ├── registry.ts
│ ├── types.ts
│ ├── huggingface.ts
│ ├── mintlify.ts
│ └── wellknown.ts
├── init.test.ts # Init command tests
├── use.ts # Use command - generate a skill prompt or launch an agent
├── use.test.ts # Use command tests
└── test-utils.ts # Test utilities
tests/
├── cross-platform-paths.test.ts # Path normalization across platforms
├── full-depth-discovery.test.ts # --full-depth skill discovery tests
├── openclaw-paths.test.ts # OpenClaw-specific path tests
├── plugin-manifest-discovery.test.ts # Plugin manifest skill discovery
├── sanitize-name.test.ts # Tests for sanitizeName (path traversal prevention)
├── skill-matching.test.ts # Tests for filterSkills (multi-word skill name matching)
├── source-parser.test.ts # Tests for URL/path parsing
├── installer-symlink.test.ts # Tests for symlink installation
├── list-installed.test.ts # Tests for listing installed skills
├── skill-path.test.ts # Tests for skill path handling
├── wellknown-provider.test.ts # Tests for well-known provider
├── xdg-config-paths.test.ts # XDG global path handling tests
└── dist.test.ts # Tests for built distribution
Update Checking System
How wittyhub check and wittyhub update Work
- Read
~/.agents/.skill-lock.jsonfor installed skills - Filter to GitHub-backed skills that have both
skillFolderHashandskillPath - For each skill, call
fetchSkillFolderHash(source, skillPath, token). Optional auth token is sourced fromGITHUB_TOKEN,GH_TOKEN, orgh auth tokento improve rate limits. fetchSkillFolderHashcalls GitHub Trees API directly (/git/trees/<branch>?recursive=1formain, thenmasterfallback)- Compare latest folder tree SHA with lock file
skillFolderHash; mismatch means update available wittyhub updatereinstalls changed skills by invoking the current CLI entrypoint directly (node <repo>/bin/cli.mjs add <source-tree-url> -g -y) to avoid nested npm exec/npx behavior
Lock File Compatibility
The lock file format is v3. Key field: skillFolderHash (GitHub tree SHA for the skill folder).
If reading an older lock file version, it's wiped. Users must reinstall skills to populate the new format.
Key Integration Points
| Feature | Implementation |
|---|---|
wittyhub add |
src/add.ts - full implementation |
wittyhub experimental_sync |
src/sync.ts - crawl node_modules |
wittyhub check |
src/cli.ts + fetchSkillFolderHash in src/skill-lock.ts |
wittyhub update |
src/cli.ts direct hash compare + reinstall via wittyhub add |
Development
# Install dependencies
pnpm install
# Build
pnpm build
# Test locally
pnpm dev add vercel-labs/agent-skills --list
pnpm dev experimental_sync
pnpm dev check
pnpm dev update
pnpm dev init my-skill
# Run all tests
pnpm test
# Run specific test file(s)
pnpm test tests/sanitize-name.test.ts
pnpm test tests/skill-matching.test.ts tests/source-parser.test.ts
# Type check
pnpm type-check
# Format code
pnpm format
# Check formatting
pnpm format:check
# Validate and sync agent metadata/docs
pnpm run -C scripts validate-agents.ts
pnpm run -C scripts sync-agents.ts
Code Style
This project uses Prettier for code formatting. Always run pnpm format before committing changes to ensure consistent formatting.
# Format all files
pnpm format
# Check formatting without fixing
pnpm format:check
CI will fail if code is not properly formatted.
Publishing
# 1. Bump version in package.json
# 2. Build
pnpm build
# 3. Publish
npm publish
Adding a New Agent
- Add the agent definition to
src/agents.ts - Run
pnpm run -C scripts validate-agents.tsto validate - Run
pnpm run -C scripts sync-agents.tsto update README.md and package keywords