Embed project-local skills, agents, and commands for semantic search. Use after creating items manually or to update embeddings.
Inherits all available tools
Additional assets for this skill
This skill inherits all available tools. When active, it can use any tool Claude has access to.
checklists/embed-coverage.jsonscripts/scan_project.pyworkflows/project-embed-workflow.jsonCompute vector embeddings for project-local items to enable semantic discovery and routing.
This is a Pro tier feature. Free tier users can use basic file search instead.
When a free tier user invokes this skill, provide basic search capabilities:
## Basic Search (Free Tier)
Project embeddings require PopKit Pro. However, you can still search your project!
### Available Search Methods
**Find skills:**
```bash
ls .claude/skills/*/SKILL.md 2>/dev/null
Find agents:
ls .claude/agents/*/AGENT.md 2>/dev/null
Find commands:
ls .claude/commands/*.md 2>/dev/null
Search by keyword:
grep -r "keyword" .claude/
With PopKit Pro, you'd get semantic embeddings including:
Run /popkit:upgrade to unlock project embeddings.
### Fallback Implementation
```python
import sys
sys.path.insert(0, "hooks/utils")
from premium_checker import check_entitlement
result = check_entitlement("pop-embed-project")
if not result.allowed:
# Provide basic search alternatives
print("## Basic Search (Free Tier)")
print("\nProject embeddings require PopKit Pro.")
print("Use basic file search: `grep -r 'keyword' .claude/`")
print("\nRun `/popkit:upgrade` to unlock project embeddings.")
return
Check for flags in the user's command:
--status: Show status only, don't embed--force or -f: Re-embed all items even if unchanged--type <type>: Filter to specific type (skill, agent, command)If --status flag:
# Use the embedding_project module
import sys
sys.path.insert(0, "hooks/utils")
from embedding_project import get_project_embedding_status
status = get_project_embedding_status()
# Display results
print(f"Project: {status['project_path']}")
print(f"API Available: {status['api_available']}")
print()
print(f"Items Found: {status['items_found']}")
print(f"Items Embedded: {status['items_embedded']}")
print(f"Items Stale: {status['items_stale']}")
print(f"Items Missing: {status['items_missing']}")
if status['by_type']:
print("\nBy Type:")
for stype, counts in status['by_type'].items():
print(f" {stype}: {counts['embedded']}/{counts['found']}")
If embedding (default):
import sys
sys.path.insert(0, "hooks/utils")
from embedding_project import embed_project_items, scan_project_items
# Map --type flag to source types
type_map = {
"skill": ["project-skill", "generated-skill"],
"agent": ["project-agent", "generated-agent"],
"command": ["project-command"],
}
source_types = None
if args.type:
source_types = type_map.get(args.type, [f"project-{args.type}"])
# First scan to show what we found
items = scan_project_items()
print(f"Found {len(items)} items")
# Embed items
result = embed_project_items(
force=args.force,
source_types=source_types,
verbose=True
)
# Report results
if result["status"] == "success":
print(f"\nEmbedding complete!")
print(f" Embedded: {result['embedded']}")
print(f" Skipped: {result['skipped']}")
if result['errors']:
print(f" Errors: {result['errors']}")
elif result["status"] == "no_items":
print("No embeddable items found in project.")
elif result["status"] == "error":
print(f"Error: {result.get('error', 'Unknown error')}")
The embedding module automatically handles rate limiting:
| Location | Source Type |
|---|---|
.claude/skills/*/SKILL.md | project-skill |
.claude/agents/*/AGENT.md | project-agent |
.claude/commands/*.md | project-command |
.generated/skills/*/SKILL.md | generated-skill |
.generated/agents/*/AGENT.md | generated-agent |
VOYAGE_API_KEY environment variable setdescription in YAML frontmatter# Check current status
/popkit:project embed --status
# Embed all items (skips unchanged)
/popkit:project embed
# Force re-embed everything
/popkit:project embed --force
# Embed only skills
/popkit:project embed --type skill
Scanning project: /path/to/project
Found 8 items
Embedding 5 new/changed items...
Waiting 21s for rate limit...
Embedding complete!
Embedded: 5
Skipped: 3 (unchanged)
Errors: 0
Project: /path/to/project
API Available: Yes
Items Found: 8
Items Embedded: 8
Items Stale: 0
Items Missing: 0
By Type:
project-skill: 3/3
project-agent: 2/2
project-command: 3/3
This skill integrates with:
hooks/utils/embedding_project.py - Core embedding logichooks/utils/embedding_store.py - Database storagehooks/utils/voyage_client.py - Voyage API clienthooks/utils/semantic_router.py - Routing using embeddings/popkit:project skills generate - Creates skills then auto-embeds/popkit:project mcp - Creates MCP server with semantic search