Expand description
ski / skill-inject — local semantic auto-injection of agent skills.
Milestones 1–3 surface: skill discovery, embedding index, ranking
(ski index / ski why), the hook hot-path with session dedup (ski hook),
model-load observation (ski observe), session lifecycle
(ski session-start), and host setup (ski init).
Modules§
- confidence
- Map a stage score onto one
[0,1]confidence axis plus a coarse band, shared by the injection phrasing (how forcefully to recommend) and session dedup (whether a re-recommendation clears the HIGH bar). - config
- Runtime configuration. Compiled defaults (
Config::base), overlaid by an optional user file (~/.config/ski/config.toml, seeFileConfig) loaded throughConfig::load. The file is the escape hatch: silence a noisy skill withdeny, pinrerank_min, widenmax_skills, etc. without a rebuild. - context
- Conversational-context query enrichment (the query side of retrieval).
- doctor
ski doctor— one-command health check for the whole install.- embed
- Embedding backends behind a single trait.
- history
ski history— read the opt-in telemetry log. Two views over the same JSONL: the default aggregate calibration readout (recommendations vs. actual use), and a--tail Nper-event listing that shows each recommendation’s prompt, stage, every candidate’s confidence, which ids were injected, and whether each injected skill was then used in that session — the view you want when iterating on matcher quality.ski clearwipes per-session dedup state (and optionally the log). All read-only and tolerant of malformed lines (skips them) so a partially-written log still reports.- hook
ski hook— the hot path. Reads a hook event on stdin, decides which skills to inject, writes the host’s injection contract on stdout.- index
- The skill index: skill metadata plus the description embedding, persisted to disk and reused incrementally (re-embed only entries whose content hash or the embedding model changed).
- init
ski init— one-shot setup of ski’s hooks for a host into the user’s config.- inject
- Turn ranked hits into the text injected into the model’s context.
- lexical
- Stage-1.5 lexical channel: BM25 over full skill descriptions.
- observe
ski observe— thePostToolUsepath. Records skills the model pulled in on its own (by reading aSKILL.md, or invoking theSkilltool) so the hook’s dedup never re-injects them.- paths
- Canonical on-disk locations, shared by every subcommand.
- pipeline
- The shared decision pipeline: stage selection + gating, single-sourced so the
hook (hot path),
ski why(tuning aid), andexamples/evalrun identical math. - rank
- Hybrid ranking: cosine(query, skill-description) + context blend + file boost
- rerank
- Stage-2 cross-encoder reranking, gated on stage-1 ambiguity.
- session
- Per-conversation state: which skills are already in context, and at what confidence we last recommended them, so dedup can be score-aware rather than “seen once, suppressed forever”.
- session_
start ski session-start— theSessionStartpath. Two jobs, both best-effort:- skill
- Skill discovery and
SKILL.mdfrontmatter parsing. - status
ski status— a plain-language readout of what ski actually did in your recent conversations. ski’s hot path is deliberately silent (it never prints into your session), so without this the only “is it helping me?” answers areski doctor(“is it wired?”) andski history(“what did telemetry log?” — empty unless you opted in). This fills the gap in between: it reads the per-session dedup ledgers (crate::session) that ski writes on every prompt regardless of telemetry, and turns them into three counts a user cares about —- suggest
ski suggest— turn the telemetry log into concrete, copy-pasteable tuning actions.ski historyshows the recall misses and false positives; this closes the loop by saying what to do about them:- telemetry
- Opt-in JSONL event log for debugging and calibration. Disabled by default
— every entry point short-circuits unless telemetry is enabled, via either
telemetry = truein~/.config/ski/config.tomlor a truthySKI_TELEMETRYenv var (1|true|yes|on, e.g. in theenvblock of~/.claude/settings.json). Each entry point callsinitright afterConfig::loadto reflect the config flag into the process;enabledis then config-OR-env. - text
- Tiny text utilities shared by the embedder, ranker, and skill parser. Deterministic by design — embeddings persisted in the index must reproduce byte-for-byte across runs and builds, so we use a fixed FNV hash, not the std hasher (whose seed/impl is not a stability guarantee).
- trace
- Opt-in stderr diagnostics for the fail-open hot paths.