Configuration: config.yaml & ignore files
The .repowise/ directory, the config.yaml file repowise generates on first init, and how to control which files get indexed with .gitignore, nested .gitignore, .repowiseIgnore, and --exclude.
Everything repowise knows about a repository lives in a .repowise/
directory at the repo root, created on the first
repowise init. The main configuration file is
.repowise/config.yaml. repowise writes it for you during init, and
you can edit it by hand afterwards.
The .repowise/ directory
.repowise/
├── wiki.db # SQLite: pages, symbols, graph, git metadata, decisions
├── lancedb/ # Vector search index
├── omissions/ # Distill omission store + savings ledger (omissions.db)
├── config.yaml # Provider, model, embedder, exclude patterns
├── health-rules.json # Per-file code-health marker overrides
├── state.json # Last sync commit, page counts, token usage
├── mcp.json # MCP server configuration
└── .env # API keys (gitignored automatically)repowise adds .repowise/ to your .gitignore automatically. It's a
local cache, not a source of truth, so don't commit it.
config.yaml
Generated after the first init and updated when you pass flags like
--commit-limit or --follow-renames. You can also edit it directly;
changes take effect on the next init, update, serve, or mcp run.
config.yaml has no schema validation. It's loaded as a plain YAML
dict, so an unknown or misspelled key is silently ignored; it won't
error and won't take effect. The only part that's validated is the
distill: block, and only when you run repowise doctor. If a setting
doesn't seem to take effect, check spelling and indentation first.
provider: anthropic # LLM provider
model: claude-sonnet-4-6 # Model identifier
embedder: gemini # Embedding provider for semantic search
embedding_model: text-embedding-3-small # Embedding model (provider default if omitted)
reasoning: auto # auto | off | none | minimal | low | medium | high | xhigh | max
max_tokens: 16384 # Max output tokens for each generated documentation page
wiki_style: comprehensive # comprehensive | caveman | reference | tutorial | custom
language: en # Output language for generated pages (en, zh, ru, hi, ...)
max_file_pages: 2000 # Cap file pages (omit = size policy, 0 = one page per file)
generation_context: # Optional source evidence for synthesis pages
token_budget: 8000
files:
repo_overview:
- docs/ARCHITECTURE.md
exclude_patterns: # Gitignore-style patterns
- vendor/
- "*.generated.*"
- proto/
commit_limit: 500 # Max commits per file for git analysis
follow_renames: false # Track file renames in git history
enable_onboarding: true # Show first-run onboarding prompts| Parameter | Type | Default | Description |
|---|---|---|---|
provider | string | auto-detected | LLM provider: anthropic, openai, gemini, openrouter, deepseek, kimi, ollama, litellm, opencode |
model | string | — | Model identifier override for the provider |
embedder | string | mock | Embedding provider: openai, gemini, ollama, openrouter, mock (mock when no key is detected) |
embedding_model | string | — | Embedding model identifier, provider default if omitted |
reasoning | string | auto | Reasoning mode for capable models: auto | off | none | minimal | low | medium | high | xhigh | max |
max_tokens | number | 16384 | Max output tokens requested for each model-written documentation page. Must be a positive integer when documentation is generated |
wiki_style | string | comprehensive | Voice and density of generated wiki pages: comprehensive | caveman | reference | tutorial | custom. Editing this key and running update does not retranslate existing pages, use repowise restyle |
language | string | en | Output language for generated wiki prose (code, paths, and symbol names stay untranslated). Changing it later doesn't retranslate existing pages, use init --force --language <code> |
max_file_pages | number | — | Most file pages a run emits, highest importance first. Unset lets a size policy decide, 0 means one page per eligible file, a positive value is a hard cap |
generation_context | object | — | Repository-source evidence appended to model-written overview and onboarding prompts (see below) |
exclude_patterns | string[] | — | Extra gitignore-style patterns to skip (persisted from --exclude) |
commit_limit | number | 500 | Max commits analyzed per file for git history |
follow_renames | boolean | false | Track file renames across git history (slower) |
enable_onboarding | boolean | true | Show first-run onboarding prompts (CLI and web) |
generation_context.files supplies explicit evidence for model-written
synthesis pages when the page's assembled structural context doesn't
normally include a fact you want it to have. Keys name the target page:
repo_overview or onboarding/<slot> for getting_started,
key_concepts, how_it_works, and active_landscape. Each value is an
ordered list of repository-relative paths; a file is only eligible if it
was included in the indexed source map and contains non-empty UTF-8 text.
token_budget (default 8000) is a per-page cap shared across configured
files, estimated with repowise's normal four-characters-per-token
heuristic. Existing pages aren't regenerated just by editing
config.yaml, run repowise generate --all or request the affected page.
Provider keys and a few runtime knobs are set via environment
variables, not config.yaml. See
Environment variables. Code-health rules
are configured separately in .repowise/health-rules.json.
The distill: block
Controls output distillation for this repo.
Everything defaults sensibly when the block is absent; repowise doctor
validates it.
distill:
enabled: true # master switch for this repo
commands:
enabled: true # the command path (CLI + hook rewrites)
permission: allow # ask | allow | off: rewrite-hook posture
families: # per-filter overrides
test_output: allow # auto-allow rewrites for test runs
git_diff: deny # never rewrite git diff here
disabled_filters: [] # filters to skip entirely, e.g. [logs]
omission_store:
ttl_days: 7 # prune stored omissions after this many days
max_mb: 50 # size cap; oldest entries pruned firstpermission: allow is the default: it auto-approves rewrites uniformly
across the main agent and every subagent. This is not a permission
escalation, a rewrite is always repowise distill <one recognized command> from a closed family set, never an arbitrary command smuggled
behind the wrapper. Set ask to have each rewritten command shown for
approval instead, or off to disable rewrites in this repo.
families keys are filter names (test_output, build_output,
lint_output, git_status, git_log, git_diff, search_results,
file_listing, logs) and accept ask | allow | off | deny. Declining
the repowise init opt-in prompt writes commands.enabled: false, so a
rewrite hook installed globally from another repo stays inert here.
Under Codex, only families set to allow are rewritten; its hook
protocol has no ask-with-mutation (see Distill).
The hooks: block
Opt-in behaviour for the agent hooks. Absent means every key below is off.
hooks:
read_skeleton: false # serve large indexed files as skeletons
read_reread: false # serve unchanged re-reads as a pointer
search_digest: false # serve multi-file grep floods as a digestread_skeletonlets the PostToolUse Read hook return the skeleton of a large indexed file instead of the full file, once per file per session. Signatures stay; bodies become... N lines (a-b)markers, and any elided span can be pulled back with a ranged Read. Reading the file a second time returns it whole.read_rereadlets the PostToolUse Read hook answer a repeat Read of the same range with a short notice instead of the content, when nothing changed the bytes since the last time this session served them. A file whose content differs on disk is always served in full.search_digestserves multi-file grep floods as a digest instead of raw matches.- Both
read_skeletonandread_rereadrequire Claude Code 2.1.218+; older clients are left untouched. - Saying yes to the rewrite-hook question in
repowise initturns these on too;--no-editor-setupand--no-distill-hookturn them off with everything else. To change your mind for one repo without re-runninginit, userepowise hook read-skeleton install | uninstall | status.
The mcp: block
Controls which tools the MCP server advertises. The default surface is
curated, not every tool: 11 tools in single-repo mode, plus 2
workspace-only tools (get_blast_radius,
get_architecture) added
automatically in workspace mode. This block lets you opt extra tools in
or trim the set down; the repowise mcp --tools / --all flags override
it for a single launch.
mcp:
tools: ["+get_execution_flows", "-get_dead_code"] # adjust the default set
# tools: ["get_answer", "get_context"] # or an explicit allowlist
# tools: all # or everything available
# tools: lean # or the agent-lean profile+name/-nameentries add to or remove from the default set; an unprefixed list is treated as an explicit allowlist.leanselects the agent-lean profile:get_answer,get_context,get_symbol,search_codebase,get_risk,get_why(pluslist_reposin workspace mode), small enough that Claude Code can keep every schema always loaded.- Opt-in tools, off by default everywhere, are
get_dependency_path,get_execution_flows,generate_refactoring_code, andget_conformance(the last only usable in workspace mode).
The decisions: block
Controls decision extraction. Each key under sources: names an
index-time capture source; set it to false to skip that source on the
next init / update. Unknown keys are ignored, and sources you don't
mention stay enabled.
decisions:
session_mining: true # mine agent-session transcripts (see below)
sources:
comment: false # LLM comment archaeology (top central files)
# inline_marker: false # WHY:/DECISION: markers
# git_archaeology: false
# adr: false
# changelog: false
# pr: falsesession_mining (default on) lets repowise update mine coding-agent
session transcripts (Claude Code's ~/.claude/projects/) for durable
decisions: user corrections, explicit choices with a stated reason, and
failed approaches replaced by working ones. Candidates pass deterministic
gates first, then one batched LLM structuring call per update, and every
produced field must quote the transcript verbatim or it is dropped.
Everything stays local: transcripts are read from your machine, staging
lives in .repowise/sessions/sessions.db, and only the distilled
decision text about the codebase is stored. Set session_mining: false
to turn the whole pipeline off.
The refactoring: block
Controls the refactoring-intelligence layer: the structured Extract
Class / Extract Helper / Move Method / Break Cycle / Split File plans
surfaced by repowise health --refactoring-targets,
get_health(include=["refactoring"]), and the web Refactoring tab.
refactoring:
enabled: true # the deterministic plans (zero LLM, in the health pass)
detectors:
disabled: [] # e.g. [move_method] to silence one detector
min_confidence: null # low | medium | high (confidence floor; null = no floor)
llm:
enabled: true # code generation, on by default; set false to disableThe deterministic layer is zero-LLM and runs in the init / update
health pass. Code generation is the only part that calls a provider.
It's on by default but never runs during indexing, only on an explicit
request (set llm.enabled: false to disable it). enabled: false
skips the whole deterministic detector pass; detectors.disabled
silences named detectors while the rest keep running.
The health-rules.json file
A separate JSON file (not part of config.yaml) that tunes code-health
biomarkers: which ones run, their severity, and per-path overrides.
Malformed JSON never raises, repowise warns and falls back to an empty
config.
{
"profile": null,
"disabled_biomarkers": [],
"severity_overrides": {
"high_churn": "low"
},
"rules": [
{
"path": "legacy/**",
"disabled_biomarkers": ["long_function"],
"severity_overrides": {
"duplication": "critical"
}
}
]
}| Parameter | Type | Default | Description |
|---|---|---|---|
profile | string | null | Named calibration profile; only "small-team" is defined today |
disabled_biomarkers | string[] | [] | Biomarker names to skip repo-wide |
severity_overrides | object | {} | Maps a biomarker name to a severity label: low | medium | high | critical |
rules | object[] | [] | Per-path overrides, evaluated in order. Each entry takes path (glob, aliases path_glob / glob also accepted), disabled_biomarkers, and severity_overrides |
Only the severity label is overridable this way, never the underlying numeric weights or caps that produce the health score.
skip_tests, skip_infra, and include_submodules are CLI-flag-only
(--skip-tests, --skip-infra, --include-submodules) and they don't
persist to config.yaml, so pass them again on each init/update
run if you want the same exclusions.
Controlling what gets indexed
repowise decides which files to document using, in order:
.gitignore: respected automatically, using the samegitwildmatchformat git uses. repowise reads the repo-root.gitignoreand nested.gitignorefiles in subdirectories, just like git: a.gitignorein any directory applies to that directory's contents..repowiseIgnore: same syntax as.gitignore, for repowise-only exclusions you don't want in git. Honoured at the repo root and in any subdirectory.exclude_patterns/--exclude: extra patterns from the CLI, persisted toconfig.yamland reapplied on everyupdate.- Built-in exclusions (always applied):
.git/,.repowise/,node_modules/,.venv/,dist/,build/,__pycache__/, binary files, lockfiles, and minified assets (*.min.js,*.min.css).
Monorepos & yarn/npm workspaces: because nested .gitignore files
are honoured, a workspace package that keeps its own .gitignore
(excluding that package's build output, generated bundles, coverage,
etc.) is respected without any extra configuration. You don't need to
duplicate those patterns at the repo root.
Add extra patterns on the command line; they're saved to config.yaml
and reused by later update runs:
repowise init -x vendor/ -x "*.generated.ts" -x proto/ -x "**/*.pb.go"Or drop a .repowiseIgnore file at the repo root or in any subdirectory
for granular control without touching .gitignore:
# packages/web/.repowiseIgnore
generated/
*.stories.tsxYou can also skip categories of files with flags: --skip-tests
excludes test files, and --skip-infra excludes Dockerfiles, Makefiles,
and shell scripts.
Submodules
Git submodule directories are excluded by default (repowise reads
.gitmodules to detect them). Include them with:
repowise init --include-submodules