@skillsmith/core
Core library for Skillsmith — database operations, search, caching, security, analytics, and multi-language codebase analysis for agent skill management.
Part of Skillsmith: a registry for sharing, scanning, and tracking agent skills across teams.
Contents
What's New in v0.12.2
- New
resolveSessionTier client (sync/license-status-client.ts): authenticates a stored skillsmith login session against /license-status so the MCP server can resolve a real subscription tier without a separately-configured SKILLSMITH_API_KEY, instead of silently falling back to community.
- Scanner: bundled-file scan expanded to operational code (Gap 8 of the ClawHavoc remediation): the indexer now reads
scripts/, src/, and bin/ alongside SKILL.md, closing a blind spot where a backdoor buried mid-function in working operational code was structurally invisible.
- Scanner fix: the markdown indented-code-block heuristic was silently downgrading real non-markdown source findings from
high to medium — analyzeMarkdownContext/SecurityScanner.scan() now take an explicit isMarkdown parameter instead of assuming every scanned file is documentation.
- Five new scanner detectors (SMI-6033 Waves 3–4):
gatekeeper_bypass (macOS quarantine-attribute stripping), archive_evasion (password-protected archives correlated with a fetch), a paste/snippet-host reputation detector, an encoded-payload decode-and-recursively-rescan detector, and decoy_misdirection (a fetch domain that doesn't match a nearby vendor-authority claim) — plus a stronger multi-signal co-signal escalation model so several individually sub-threshold findings can now jointly escalate a weak code_execution finding to critical.
See CHANGELOG.md for previous releases.
Installation
npm install @skillsmith/core
@huggingface/transformers is an optionalDependency — when it cannot be installed (no prebuilt ONNX binary, --no-optional flag, restricted hosts) @skillsmith/core falls back to mock embeddings per ADR-009. To force the mock fallback explicitly, set SKILLSMITH_USE_MOCK_EMBEDDINGS=true. The @skillsmith/mcp-server boot logs a structured stderr warning when the fallback is engaged (SMI-5009).
Quick Start
import {
openDatabase,
SkillRepository,
SearchService,
TieredCache,
} from '@skillsmith/core'
const db = openDatabase('~/.skillsmith/skills.db')
const skillRepo = new SkillRepository(db)
const cache = new TieredCache()
const searchService = new SearchService(skillRepo, cache)
const results = await searchService.search({
query: 'testing',
limit: 10,
})
Live API
As of v0.2.0, Skillsmith uses a live API at api.skillsmith.app to serve skills.
Configuration
export SKILLSMITH_API_URL=https://your-api.example.com
export SKILLSMITH_OFFLINE_MODE=true
Telemetry
Skillsmith collects anonymous usage data to improve the product.
To opt out:
export SKILLSMITH_TELEMETRY=false
See PRIVACY.md for details on what data is collected.
Features
Database Operations
SQLite-based storage with migrations and type-safe queries.
import { openDatabase, createDatabase, runMigrations } from '@skillsmith/core'
const db = openDatabase('./skills.db')
await runMigrations(db)
Repositories
- SkillRepository - CRUD operations for skills
- CacheRepository - Persistent cache storage
- IndexerRepository - Batch indexing operations
- SkillDependencyRepository - Skill dependency graph queries
import { SkillRepository } from '@skillsmith/core'
const repo = new SkillRepository(db)
const skill = await repo.findById('author/skill-name')
const skills = await repo.search({ query: 'testing', limit: 10 })
Search Services
Hybrid search combining full-text and semantic search.
import { HybridSearch, SearchService } from '@skillsmith/core'
const search = new HybridSearch(db)
const results = await search.search({
query: 'git commit helper',
filters: { trustTier: 'verified' },
})
Caching
Multi-tier caching with L1 (memory) and L2 (SQLite) layers.
import { TieredCache, L1Cache, L2Cache } from '@skillsmith/core'
const cache = new TieredCache({
l1: new L1Cache({ maxSize: 1000, ttlMs: 60000 }),
l2: new L2Cache(db),
})
await cache.set('key', { data: 'value' })
const cached = await cache.get('key')
Security
Rate limiting, path validation, security scanning, and audit logging.
import {
RateLimiter,
SecurityScanner,
AuditLogger,
validateDbPath,
} from '@skillsmith/core'
const limiter = new RateLimiter({ maxRequests: 100, windowMs: 60000 })
const allowed = await limiter.checkLimit('user-123')
const result = validateDbPath('/path/to/db.sqlite')
if (!result.valid) throw new Error(result.error)
const scanner = new SecurityScanner()
const report = await scanner.scan(skillContent)
const logger = new AuditLogger(db)
await logger.log({
eventType: 'skill.install',
actor: { type: 'user', id: 'user-123' },
resource: { type: 'skill', id: 'author/skill' },
})
Indexing
Index skills from GitHub repositories.
import { GitHubIndexer, SkillParser } from '@skillsmith/core'
const indexer = new GitHubIndexer({
token: process.env.GITHUB_TOKEN,
})
const result = await indexer.indexRepository('owner/repo')
Quality Scoring
Score skills based on documentation, security, and community signals.
import { QualityScorer, quickScore } from '@skillsmith/core'
const scorer = new QualityScorer()
const score = await scorer.score(skill)
const quick = quickScore(skillMetadata)
Dependency Intelligence
Infer and manage skill dependencies from SKILL.md content.
import {
extractMcpReferences,
mergeDependencies,
SkillDependencyRepository,
} from '@skillsmith/core'
const refs = extractMcpReferences(skillMdContent)
const merged = mergeDependencies(declaredDeps, refs)
const depRepo = new SkillDependencyRepository(db)
await depRepo.upsert('author/skill', merged)
const deps = depRepo.findBySkillId('author/skill')
Analytics
Track skill usage and generate insights.
import { UsageTracker, UsageAnalyticsService } from '@skillsmith/core'
const tracker = new UsageTracker(db)
await tracker.trackUsage({
skillId: 'author/skill',
eventType: 'install',
})
const analytics = new UsageAnalyticsService(db)
const summary = await analytics.getSummary({ days: 30 })
Telemetry
OpenTelemetry-based tracing and metrics.
import {
initializeTelemetry,
getTracer,
getMetrics,
traced,
} from '@skillsmith/core'
await initializeTelemetry({ serviceName: 'skillsmith' })
const tracer = getTracer()
const span = tracer.startSpan('operation')
span.end()
class MyService {
@traced('search')
async search(query: string) {
}
}
Multi-Language Codebase Analysis (v2.0.0)
Analyze codebases in TypeScript, JavaScript, Python, Go, Rust, and Java.
import { CodebaseAnalyzer } from '@skillsmith/core'
const analyzer = new CodebaseAnalyzer()
const context = await analyzer.analyze('/path/to/project')
console.log(context.metadata.languages)
console.log(context.stats.filesByLanguage)
console.log(context.frameworks)
analyzer.dispose()
Language Router
Route files to appropriate language adapters:
import {
LanguageRouter,
TypeScriptAdapter,
PythonAdapter,
GoAdapter,
RustAdapter,
JavaAdapter,
} from '@skillsmith/core'
const router = new LanguageRouter()
router.registerAdapter(new TypeScriptAdapter())
router.registerAdapter(new PythonAdapter())
router.registerAdapter(new GoAdapter())
router.registerAdapter(new RustAdapter())
router.registerAdapter(new JavaAdapter())
router.canHandle('main.py')
router.getLanguage('main.go')
const result = router.parseFile(content, 'main.py')
console.log(result.imports, result.exports, result.functions)
router.dispose()
Parse Caching
Cache parse results for improved performance:
import { ParseCache } from '@skillsmith/core'
const cache = new ParseCache({ maxMemoryMB: 100 })
const cached = cache.get('src/main.ts', content)
if (cached) {
return cached
}
const result = adapter.parseFile(content, 'src/main.ts')
cache.set('src/main.ts', content, result)
console.log(cache.getStats())
Incremental Parsing
Efficiently parse changes:
import { IncrementalParser, TypeScriptAdapter } from '@skillsmith/core'
const parser = new IncrementalParser({ maxTrees: 50 })
const adapter = new TypeScriptAdapter()
const result1 = parser.parse('src/main.ts', content1, adapter)
console.log(result1.wasIncremental)
const result2 = parser.parse('src/main.ts', content2, adapter)
console.log(result2.wasIncremental)
parser.dispose()
Parallel Parsing
Parse large codebases in parallel:
import { ParserWorkerPool } from '@skillsmith/core'
const pool = new ParserWorkerPool({ poolSize: 4 })
const tasks = files.map(f => ({
filePath: f.path,
content: f.content,
language: 'typescript'
}))
const results = await pool.parseFiles(tasks)
console.log(`Parsed ${results.length} files`)
pool.dispose()
Dependency Parsers
Parse language-specific dependency files:
import {
parseGoMod,
parseCargoToml,
parsePomXml,
parseBuildGradle,
} from '@skillsmith/core'
const goMod = parseGoMod(goModContent)
console.log(goMod.module)
console.log(goMod.require)
const cargo = parseCargoToml(cargoTomlContent)
const maven = parsePomXml(pomXmlContent)
const gradle = parseBuildGradle(buildGradleContent)
Supported Languages & Frameworks
| TypeScript/JS | .ts, .tsx, .js, .jsx, .mjs, .cjs | React, Vue, Angular, Next.js, Express, Nest.js, Jest, Vitest |
| Python | .py, .pyi, .pyw | Django, FastAPI, Flask, pytest, pandas, numpy |
| Go | .go | Gin, Echo, Fiber, GORM, Cobra, gRPC, testify |
| Rust | .rs | Actix, Rocket, Axum, Tokio, Serde, Diesel, SQLx |
| Java | .java | Spring Boot, Quarkus, Micronaut, JUnit, Hibernate, Lombok |
Performance
| 10k file analysis | <5 seconds |
| Incremental parse | <100ms |
| Cache hit rate | >80% |
| Memory efficiency | LRU eviction |
Exports
The package provides multiple entry points:
import { SkillRepository, SearchService } from '@skillsmith/core'
import { SkillsmithError, ValidationError } from '@skillsmith/core/errors'
import { EmbeddingService } from '@skillsmith/core/embeddings'
import {
CodebaseAnalyzer,
LanguageRouter,
ParseCache,
TreeCache,
IncrementalParser,
ParserWorkerPool,
MemoryMonitor,
TypeScriptAdapter,
PythonAdapter,
GoAdapter,
RustAdapter,
JavaAdapter,
parseGoMod,
parseCargoToml,
parsePomXml,
parseBuildGradle,
type SupportedLanguage,
type ParseResult,
type ImportInfo,
type ExportInfo,
type FunctionInfo,
type CodebaseContext,
} from '@skillsmith/core'
import {
extractMcpReferences,
mergeDependencies,
SkillDependencyRepository,
type DependencyDeclaration,
type SkillDependencyRow,
type DepType,
type DepSource,
type McpReference,
type McpExtractionResult,
type MergedDependency,
} from '@skillsmith/core'
Billing module — relocated in 0.7.0 (BREAKING)
SMI-5006 moved Stripe billing (StripeClient, BillingService, StripeWebhookHandler,
GDPRComplianceService, StripeReconciliationJob) to
@smith-horn/enterprise. Update imports:
import { StripeWebhookHandler } from '@skillsmith/core/billing'
import { StripeWebhookHandler } from '@smith-horn/enterprise/billing'
No back-compat shim is shipped — the ./billing subpath export was removed.
Requirements
- Node.js >= 22.0.0
- SQLite (via better-sqlite3)
License
Elastic License 2.0
Links