Embed project-local skills, agents, and commands for semantic search. Use after creating items manually or to update embeddings. Works with both keyword and semantic search modes.
Compute vector embeddings for project-local skills, agents, and commands to enable semantic search and intelligent routing. Use after manually creating items or to update embeddings when content changes.
/plugin marketplace add jrc1883/popkit-claude/plugin install popkit-core@popkit-claudeThis 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 skill works in two modes:
All users can search projects using built-in file search:
## Keyword Search Mode
Project search works great with built-in tools!
### 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 an API key, you get semantic intelligence:
Get a free API key: /popkit:cloud signup
### Enhancement Detection
```python
import sys
# No longer needed - install popkit-shared instead
from enhancement_detector import check_enhancement
result = check_enhancement("project-embeddings")
if not result.has_api_key:
# Provide keyword search alternatives (fully functional)
print("## Keyword Search Mode")
print("\nProject search works great with built-in tools!")
print("Use file search: `grep -r 'keyword' .claude/`")
print("\nFor semantic enhancements: `/popkit:cloud signup` (free)")
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
# No longer needed - install popkit-shared instead
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
# No longer needed - install popkit-shared instead
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