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.
From popkit-corenpx claudepluginhub jrc1883/popkit-ai --plugin popkit-coreThis skill uses the workspace's default tool permissions.
checklists/embed-coverage.jsonscripts/scan_project.pyworkflows/project-embed-workflow.jsonGuides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Migrates code, prompts, and API calls from Claude Sonnet 4.0/4.5 or Opus 4.1 to Opus 4.5, updating model strings on Anthropic, AWS, GCP, Azure platforms.
Guides Payload CMS config (payload.config.ts), collections, fields, hooks, access control, APIs. Debugs validation errors, security, relationships, queries, transactions, hook behavior.
Compute 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