Configuration¶
sminer runs with no configuration at all. When you do want to change something, every setting can come from a flag, an environment variable or the config file.
Precedence¶
The first layer that sets a value wins:
- Command-line flags, such as
--since 30d - Environment variables:
SMINER_plus the key in upper case, with dots as underscores.classifier.modelisSMINER_CLASSIFIER_MODEL. - The config file: the file named by
--config, or else the first of these that exists:$XDG_CONFIG_HOME/sminer/config.yaml(by default~/.config/sminer/config.yaml),~/.sminer.yaml,./.sminer.yaml - Built-in defaults
sminer config show prints every effective value and which layer set it:
KEY VALUE SOURCE
window 30d env SMINER_WINDOW
offline true flag --offline
classifier.model claude-haiku-5-5 file /home/me/.config/sminer/config.yaml
min_count 3 default
The config file¶
Every key is optional. config.example.yaml in the repository is a commented starting point:
roots: [~/.claude/projects]
window: 90d
min_count: 3
offline: false
exclude_repos: ["~/personal/*"]
classifier:
model: claude-haiku-5-5
max_calls_per_run: 500
concurrency: 4
embeddings:
provider: auto
model: nomic-embed-text
url: http://localhost:11434
cluster:
threshold: 0
redact:
patterns: ["(?i)aws_secret", "ghp_[A-Za-z0-9]+"]
remedies:
hooks_dir: ~/src/claude-hooks
global_claude_md: ~/.claude/CLAUDE.md
skills_dir: ~/.claude/skills
settings: ~/.claude/settings.json
Keys¶
| Key | Default | Meaning |
|---|---|---|
roots |
[~/.claude/projects] |
Directories searched for *.jsonl transcripts. Flag: --root |
window |
90d |
How far back to ingest and analyze: 90d, 2w, 12h. Flag: --since |
min_count |
3 |
Occurrences a finding needs to be reported. Flag: --min-count |
offline |
false |
Never call the network. Flag: --offline |
exclude_repos |
[] |
Globs of repos never ingested; a pattern also matches subdirectories |
classifier.model |
claude-haiku-5-5 |
Model for classification and proposal drafting |
classifier.max_calls_per_run |
500 |
Cap on API calls per run, across both uses |
classifier.concurrency |
4 |
Parallel classifier calls |
embeddings.provider |
auto |
auto (ollama if it answers, else built-in), ollama or hash |
embeddings.model |
nomic-embed-text |
ollama embedding model |
embeddings.url |
http://localhost:11434 |
ollama server |
cluster.threshold |
0 |
Cosine similarity to join a cluster; 0 uses the embedder's default (0.45 built-in, 0.78 ollama) |
redact.patterns |
[] |
Extra regexes to redact, on top of the built-ins |
remedies.hooks_dir |
~/src/claude-hooks |
Where hook proposals are written, and existing hooks are read |
remedies.global_claude_md |
~/.claude/CLAUDE.md |
The CLAUDE.md for rules that span repos |
remedies.skills_dir |
~/.claude/skills |
Where skill proposals go, and existing skills are read |
remedies.settings |
~/.claude/settings.json |
Claude Code settings, read for existing hooks |
db |
$XDG_DATA_HOME/sminer/sminer.db |
The database. Flag: --db |
patch_dir |
$XDG_DATA_HOME/sminer/patches |
Where accepted patches are written |
json |
false |
Print machine-readable JSON on stdout. Flag: --json |
quiet |
false |
Print nothing on stderr except errors. Flag: --quiet |
verbose |
false |
Print detail on stderr. Flag: --verbose |
no_color |
false |
Disable color. Flag: --no-color |
Paths may start with ~. Invalid values (a bad window, a min_count below 1, an unknown embeddings.provider, or quiet and verbose both set without either flag) are rejected up front with exit code 2.
Credentials¶
The classifier uses the Anthropic SDK's standard credential lookup: ANTHROPIC_API_KEY most commonly. sminer never takes a key as a command-line argument.
Locations¶
sminer follows the XDG base directory spec, on macOS too:
| What | Where |
|---|---|
| Config file | $XDG_CONFIG_HOME/sminer/config.yaml, default ~/.config/sminer/config.yaml; then ~/.sminer.yaml and ./.sminer.yaml |
| Database and patches | $XDG_DATA_HOME/sminer/, default ~/.local/share/sminer/ |
Better clustering with ollama¶
The built-in embedder hashes words, so it groups corrections that share wording but can miss paraphrases. A local embedding model groups by meaning, and nothing leaves your machine either way:
Changing the embedder recomputes all embeddings on the next run. Finding IDs are matched by similarity, so most survive the switch.