This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
FastSkill is a Rust-based package manager and operational toolkit for Claude Code-compatible skills. It provides registry services, semantic search, version management, and deployment tooling for AI agent skills at scale.
# Build the project
cargo build
# Run fastskill locally with arguments
cargo run --bin fastskill -- <command>
# Run in release mode (optimized)
cargo build --release# Run all tests with nextest (recommended - faster than cargo test)
cargo nextest run
# Run specific test by name
cargo nextest run -E 'test(test_name)'
# Run tests with all features enabled
cargo nextest run --all-features
# Run tests with specific features
cargo nextest run --features hot-reloadFastSkill uses insta for snapshot testing CLI output:
# Review snapshot changes when tests fail
cargo insta review
# Accept all snapshot changes
cargo insta accept
# Run tests and accept snapshots in one command
cargo insta test --accept --test-runner nextest# Format code
cargo fmt --all
# Run clippy linter
cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
# Check for typos
typos
# Check for unused dependencies
cargo shear# Enable trace-level logging for fastskill
RUST_LOG=fastskill=trace cargo run --bin fastskill -- <command>
# Enable debug logging for specific modules
RUST_LOG=fastskill::core=info,fastskill::http=debug cargo run --bin fastskill -- <command>FastSkill follows a layered architecture with clear separation of concerns:
CLI Layer (src/cli/)
↓
Service Layer (FastSkillService)
↓
Core/Business Layer (src/core/)
↓
Storage Layer (src/storage/)
HTTP Layer (src/http/) - independent of CLI, uses same service layer
-
src/cli/- Command-line interface and argument parsing (14 files)cli.rs- Main CLI entry point and command dispatchcommands/- Individual command implementations (add, search, serve, registry, etc.)config.rs- Configuration file handlingutils/- CLI utilities (API client, messages, install/manifest helpers)
-
src/core/- Core business logic (27 files)skill_manager.rs- Skill lifecycle management (register, update, enable/disable)metadata.rs- Skill metadata extraction and discoveryvector_index.rs- Semantic search using OpenAI embeddings + SQLiteregistry/- Registry client, configuration, and authenticationrepository.rs- Unified repository system (git, HTTP, local, ZIP)manifest.rs- Project manifest (skills.toml) and lockfile handlingservice.rs-FastSkillServiceorchestrator that initializes all sub-services
-
src/http/- HTTP API server (13 files)server.rs- Axum server setup and router configurationhandlers/- API endpoint handlers (skills, search, registry, manifest, etc.)models.rs- Request/response types (ApiResponse<T>, error handling)
-
src/storage/- Storage backends (5 files)filesystem.rs- File-based skill storage with metadata cachinggit_storage.rs- Git operations for skill sourceszip_handler.rs- ZIP package extraction and creationvector_index_storage.rs- SQLite persistence for embeddings
-
src/validation/- Skill validation (3 files)skill_validator.rs- Validates skill structure and metadatastandard_validator.rs- Standard SKILL.md format validationzip_validator.rs- ZIP package integrity validation
-
src/events/- Event bus for skill lifecycle tracking (2 files) -
src/execution.rs- Script execution sandboxing and security policies
The core data structure representing a skill. Located in src/core/skill_definition.rs.
Key fields:
id: SkillId- Validated skill identifierskill_file: PathBuf- Path to SKILL.mdsource_url/source_type/source_branch- Tracks skill origineditable: bool- For local development (like Poetry's-eflag)enabled: bool- Runtime enable/disable without uninstalling- Execution config:
execution_environment,dependencies,timeout
The main service orchestrator in src/core/service.rs. Initializes and coordinates all sub-services:
SkillManagementService(skill lifecycle)MetadataService(metadata extraction)VectorIndexService(semantic search)StorageBackend(file operations)RepositoryManager(multi-source skill discovery)
Used by both CLI commands and HTTP handlers.
Multi-source skill repository support in src/core/repository.rs:
Repository Types:
GitMarketplace- Git repos with marketplace.json for skill discoveryHttpRegistry- HTTP-based registries with flat indexZipUrl- ZIP file downloads from base URLLocal- Local filesystem paths
Configured in .claude/repositories.toml with priority-based conflict resolution.
Commands are divided into two categories:
-
Service-dependent commands (add, search, serve, show, update, etc.)
- Initialize
FastSkillServicefirst - Use shared service layer for operations
- Initialize
-
Standalone commands (init, install, publish, auth, registry)
- Execute without full service initialization
- Avoid circular dependencies and overhead
- Registry command has its own modular structure in
src/cli/commands/registry/
Located in src/core/vector_index.rs:
- Skills are embedded using OpenAI's
text-embedding-3-smallmodel - Embeddings stored in SQLite database (
.claude/.fastskill/index.db) - Search uses cosine similarity to rank results
- Files are content-addressed (SHA256 hashing) to detect changes
Key trait: VectorIndexService with methods: add_or_update_skill(), search_similar(), remove_skill()
Note: The remove and reindex commands automatically keep the vector index in sync by removing entries for deleted skills or skills no longer on disk.
Event-driven architecture in src/events/event_bus.rs:
Event types: SkillRegistered, SkillUpdated, SkillUnregistered, SkillReloaded, SkillEnabled, SkillDisabled
Enables decoupled components to react to skill lifecycle changes (e.g., hot-reload, cache invalidation).
FastSkill resolves configuration in priority order:
- CLI arguments
- Environment variables (e.g.,
OPENAI_API_KEY,RUST_LOG) skill-project.toml[tool.fastskill]section (walks up directory tree)- Walk up directory tree to find existing
.claude/skills/ - Default to
./.claude/skills/
skill-project.toml[tool.fastskill]- Project configuration (embedding settings, skills directory).claude/repositories.toml- Multi-repository configuration.claude/skills.toml- Project manifest (like package.json or Cargo.toml).claude/skills.lock- Lockfile for reproducible installations.claude/.fastskill/index.db- SQLite vector index
Defined in Cargo.toml:
filesystem-storage(default) - Local filesystem storage for skillsregistry-publish(default) - Publishing to registries with AWS S3hot-reload(optional) - File watching for automatic skill reloading
Tests requiring optional features are skipped if features not enabled.
FastSkill uses structured error handling:
thiserrorfor domain-specific error types (e.g.,SkillError,RegistryError)anyhowfor error propagation with context- Use
.with_context(|| format!("..."))for adding context to errors - Use
?operator for propagation
- Unit tests - Test individual functions and modules
- Integration tests - Test CLI commands and HTTP endpoints
- Snapshot tests - Validate CLI output using insta (in
tests/cli/) - Helper utilities - Use
tests/cli/snapshot_helpers.rsfor consistent snapshot testing
When adding tests that modify CLI output, run cargo insta review to accept snapshot changes.
FastSkill is async-first using Tokio:
- All I/O operations are async
- Service traits use
#[async_trait] - Use
Arc<dyn Trait>for shared service references across async tasks - Main service orchestrator (
FastSkillService) usesArc<RwLock<_>>for thread-safe state
- Rust nightly required (MSRV defined in
rust-toolchain.toml) - Pure Rust dependencies - No C compiler needed
- SQLite bundled - Uses
rusqlitewithbundledfeature - System git - Git operations use system
gitbinary (not libgit2)
- Add command variant to
Commandsenum insrc/cli/commands/mod.rs - Create handler module in
src/cli/commands/ - Implement
execute_*()async function - Add dispatch logic in
src/cli/cli.rs - Wire through
FastSkillServicemethods if service-dependent
- Create handler module in
src/http/handlers/ - Define request/response types in
src/http/models.rs - Add route to Axum router in
src/http/server.rs - Keep handlers consistent with local
fastskill serveunauthenticated API behavior
- Add new repository type to
RepositoryTypeenum insrc/core/repository.rs - Implement
RepositoryClienttrait for new type - Add CLI subcommand in
src/cli/commands/registry/ - Update formatters in
src/cli/commands/registry/formatters.rsif needed
Refer to STYLE.md for detailed style guidelines. Key points:
- Use "fastskill" (lowercase) in code and commands, not "FastSkill"
- CLI messages use "headline style" (terse, no trailing periods for single sentences)
- Use structured logging with
tracingcrate (debug!,info!,warn!,error!) - User-facing messages go to stdout/stderr directly, not through tracing
- Follow error template:
error: <summary>with optional hints - Avoid
.unwrap()and.expect()in production code (enabled as Clippy warnings)
When handling untrusted input or archives, agents MUST follow these rules:
-
Path traversal
Code that writes files from archive entry names or other untrusted path-like strings MUST validate that the resolved output path stays under the intended base directory. The resolved path MUST be normalized (e.g. without..or redundant segments) and MUST have the base directory as a prefix before any filesystem write; otherwise the entry MUST be rejected. -
Archive extraction
Any ZIP (or similar) extraction MUST use the same rule: never join entry names to a base path and write without checking that the result is under the extraction root. This applies to CLI add-from-zip, registry validation worker extraction, and any future extraction code. -
Tests
For code that extracts archives or resolves untrusted paths, tests MUST include at least one case that uses malicious path components (e.g.../,..\\, or segments that escape the base). The test MUST assert that no file is created outside the intended directory (or that the operation fails). Shared safe-extraction helpers SHOULD have dedicated tests so reuse does not regress.
Per RFC 2119, the following rules apply:
- MUST use conventional commit-style messages: a type (e.g.
feat,fix,docs,chore,refactor,test), optional scope in parentheses, and a short description (e.g.feat(cli): add --dry-run to install). - MUST NOT add co-author trailers (e.g.
Co-authored-by: Cursor,Co-authored-by: Claude) or any AI/agent attribution in commit messages or footers. - MUST NOT include author-style lines or footers in commit messages; commits MUST NOT contain
Author:or similar trailers that attribute the change to an AI or tool. - Commit messages MUST refer only to the change itself and MUST NOT state or imply that the commit was co-authored by Cursor, Claude, or any other agent.
- Automatic releases on pushes to
main(patch version bump) - Skip with
[skip release],[no release], or[skip ci]in commit message - Manual releases via version tags (
v1.2.3) or workflow dispatch - Builds 3 binary variants:
x86_64-unknown-linux-musl(static),x86_64-unknown-linux-gnu(glibc),x86_64-pc-windows-msvc
- CONTRIBUTING.md - Full contributor guidelines
- STYLE.md - Comprehensive style guide for CLI output and documentation
- README.md - User-facing documentation and installation instructions
- SECURITY.md - Security policy and vulnerability reporting