Configuration
Settings
devcoach has seven settings, all stored in the settings table of the database:
| Setting | Default | Range / values | Set via |
|---|---|---|---|
max_per_day | 2 | 1–20 | CLI · MCP tool · web UI |
min_gap_minutes | 240 | 0–1440 | CLI · MCP tool · web UI |
nudge_every | 10 | 0–1000 | CLI · MCP tool · web UI |
nudge_scope | session | session | global | CLI · MCP tool · web UI |
share_name | (empty) | ≤ 80 chars; empty → git user.name | CLI · MCP tool · web UI |
ui_theme | system | system | light | dark | web UI only |
ui_home | auto | auto | lessons | knowledge | web UI only |
devcoach set <key> <value> and the update_settings MCP tool accept the first five. The two ui_*
settings belong to the dashboard and are changed from its Settings page: ui_theme is the colour
scheme, ui_home is where / lands (auto = Lessons once a lesson exists, the knowledge map before).
Rate limits
Two of the settings rate-limit lesson delivery to prevent overload:
| Setting | Default | Range | Description |
|---|---|---|---|
max_per_day | 2 | 1–20 | Maximum lessons in a rolling 24-hour window |
min_gap_minutes | 240 | 0–1440 | Minimum minutes between consecutive lessons |
Both count your own lessons only: a lesson someone
shared with you (imported = 1) never uses up the daily
budget, never starts the gap, and never resets the pacing counter.
Examples:
# Aggressive learning: up to 5 lessons/day, no minimum gap
devcoach set max_per_day 5
devcoach set min_gap_minutes 0
# Conservative: 1 lesson/day, must be at least 8 hours apart
devcoach set max_per_day 1
devcoach set min_gap_minutes 480
# Disable rate limiting entirely (not recommended)
devcoach set max_per_day 20
devcoach set min_gap_minutes 0
Via MCP tool:
{ "key": "max_per_day", "value": "3" }
{ "key": "min_gap_minutes", "value": "120" }
Via web UI: devcoach ui → Settings page. The dashboard binds to 127.0.0.1 only (never reachable
from other machines) and takes a single option, --port <n> (default 7860).
Lesson pacing (nudge)
Beyond the rate limits, devcoach paces the coaching cue itself — the hook signal that asks the agent to deliver a lesson. This keeps coaching deliberately quiet: short sessions may produce no lesson at all, by design.
| Setting | Default | Values | Description |
|---|---|---|---|
nudge_every | 10 | 0–1000 | Interactions (agent stops) between lesson cues. 0 = cue on every eligible stop |
nudge_scope | session | session | global | Count interactions per chat session, or across all sessions |
How the counter behaves:
- Plan-mode turns don't count — planning isn't coachable work.
- Rate-limited stops keep accumulating, so the cue fires at the first allowed stop.
- When a cue fires, the counter resets — no cue storms after the threshold.
- A resolution restarts the window: both
log_lesson(lesson delivered) andskip_lesson(explicit decline) reset the counters. - An unresolved cue retries sooner: if the agent neither logs a lesson (
log_lesson) nor declines explicitly (skip_lesson), the next cue comes aftermin(3, nudge_every)further stops instead of the full threshold. - The card is the final message:
log_lessonis a pure save whose result carries areply_checkself-check reminding the model that tool arguments are invisible to you. The skill calls the tool silently first and writes the lesson card as the last text of the turn.
devcoach doctor prints the live counters and explains whether the next stop would cue.
Data location
~/.devcoach/coaching.db — SQLite database
~/.devcoach/learning-state.md — coaching notebook (markdown)
~/.devcoach/courses/<id>/ — one folder per course, holding its index.html
~/.devcoach/hook.log — hook trace, only when DEVCOACH_HOOK_DEBUG=1 is set
The database is created automatically on first run. All data is local — nothing is sent to any server.
Environment variables
| Variable | Effect |
|---|---|
DEVCOACH_DIR | Relocates the whole ~/.devcoach directory (database, notebook, hook log). Meant for tests and sandboxing — e.g. DEVCOACH_DIR=$(mktemp -d) devcoach stats leaves your real data untouched |
DEVCOACH_HOOK_DEBUG=1 | Traces every hook decision (cue / silent exit and its reason) to ~/.devcoach/hook.log; the log is truncated once it passes 256 KB |
DEVCOACH_CLAUDE_DIR / CLAUDE_CONFIG_DIR | Relocate the Claude Code history that the onboarding stack scan reads (default ~/.claude) |
NO_COLOR | Disables coloured CLI output |
Database schema (reference)
-- Delivered lessons (19 columns)
lessons (
id TEXT PRIMARY KEY,
timestamp TEXT NOT NULL, -- ISO 8601 UTC, always stamped server-side
topic_id TEXT NOT NULL,
categories TEXT NOT NULL, -- JSON array
title TEXT NOT NULL,
level TEXT NOT NULL, -- junior | mid | senior
summary TEXT NOT NULL,
body TEXT, -- full lesson markdown (optional)
task_context TEXT,
project TEXT,
repository TEXT,
branch TEXT,
commit_hash TEXT,
folder TEXT,
feedback TEXT, -- know | understood | dont_know | NULL
repository_platform TEXT, -- github | gitlab | bitbucket | local
starred INTEGER NOT NULL DEFAULT 0,
imported INTEGER NOT NULL DEFAULT 0, -- 1 = shared by someone else (ignored by the rate limit)
shared_by TEXT -- the sender's name; NULL = anonymous / not imported
)
-- Knowledge map
knowledge (
topic TEXT PRIMARY KEY,
confidence INTEGER NOT NULL DEFAULT 5, -- 0-10
updated_at TEXT NOT NULL
)
-- Named groups
knowledge_group_names (group_name TEXT PRIMARY KEY)
knowledge_groups (group_name TEXT, topic TEXT, PRIMARY KEY (group_name, topic))
-- Settings
settings (key TEXT PRIMARY KEY, value TEXT NOT NULL)
-- Courses (schema v5): the index of ~/.devcoach/courses/<id>/index.html
courses (id TEXT PRIMARY KEY, lesson_id TEXT, topic_id TEXT NOT NULL, title TEXT NOT NULL,
goal TEXT, prerequisites TEXT NOT NULL DEFAULT '[]', -- JSON [{concept, known}]
status TEXT NOT NULL DEFAULT 'active', -- active | completed | abandoned
created_at TEXT NOT NULL, updated_at TEXT NOT NULL, completed_at TEXT)
course_steps (course_id TEXT NOT NULL, position INTEGER NOT NULL, title TEXT NOT NULL,
kind TEXT NOT NULL, -- concept | example | practice | check
anchor TEXT NOT NULL, -- the section id in the document
status TEXT NOT NULL DEFAULT 'todo', -- todo | done | skipped
done_at TEXT, PRIMARY KEY (course_id, position))
-- plus UNIQUE (course_id, anchor): one step per section
-- Runtime-only pacing state (never included in backups)
nudge_state (session_id TEXT PRIMARY KEY, interactions INTEGER, updated_at TEXT)
cue_state (id INTEGER PRIMARY KEY CHECK (id = 1), pending INTEGER,
last_cue_at TEXT, last_skip_reason TEXT)
Backup strategy
devcoach stores everything in a single SQLite file. Recommended backup approach:
# Daily cron / scheduled task
devcoach backup ~/Dropbox/devcoach-$(date +%Y%m%d).zip
# Before a major change
devcoach backup devcoach-before-reset.zip
The backup zip contains:
settings.json— all settingsknowledge.json— topics, confidence scores, and group assignmentslessons.json— full lesson historylearning-state.md— the coaching notebook (when present)courses.json+courses/<id>/index.html— every course's index, steps and document (when any)
All of them are restored by devcoach restore <zip>.
Reset
To start fresh while keeping your lesson history:
# Save current knowledge before clearing
devcoach backup devcoach-before-reset.zip
# Re-run the onboarding flow
devcoach setup
To reset everything including lessons, delete the database:
rm ~/.devcoach/coaching.db
devcoach setup # re-creates it