devcoach 0.8.3 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,7 +16,7 @@
16
16
 
17
17
  **Stay sharp while your AI does the work.**
18
18
 
19
- devcoach connects to Claude Code, Claude Desktop, Cursor, Windsurf, and other MCP-compatible tools. After every task you complete, it delivers a short targeted lesson calibrated to what you already know — no generic tutorials, no repeated topics, nothing to open.
19
+ devcoach connects to Claude Code, Claude Desktop, Gemini CLI *(beta)*, Codex CLI *(beta)*, Cursor, Windsurf, and other MCP-compatible tools. After every task you complete, it delivers a short targeted lesson calibrated to what you already know — no generic tutorials, no repeated topics, nothing to open.
20
20
 
21
21
  Everything runs **locally**. No data leaves your machine. One SQLite file at `~/.devcoach/coaching.db`.
22
22
 
@@ -67,7 +67,7 @@ Everything stays on your machine. No telemetry, no accounts, no calls home. Just
67
67
 
68
68
  ## Installation
69
69
 
70
- devcoach runs **locally** — a stdio MCP server that stores everything in `~/.devcoach/coaching.db` on the machine where your agent runs. It works in **Claude Code** and **Claude Desktop**, but **not** on claude.ai web (which only supports hosted/remote connectors).
70
+ devcoach runs **locally** — a stdio MCP server that stores everything in `~/.devcoach/coaching.db` on the machine where your agent runs. It works in **Claude Code**, **Claude Desktop**, **Gemini CLI** *(beta)*, and **Codex CLI** *(beta)*, but **not** on claude.ai web (which only supports hosted/remote connectors).
71
71
 
72
72
  **Requires Node.js ≥ 24** (devcoach uses the embedded `node:sqlite` module, available only from Node 24 onward).
73
73
 
@@ -191,6 +191,32 @@ after each turn whether a lesson is due, `prompt-hook` primes the model up front
191
191
 
192
192
  </details>
193
193
 
194
+ <details>
195
+ <summary><strong>Gemini CLI</strong> — full coaching loop (hooks + skill) — <strong>Beta</strong></summary>
196
+
197
+ One command registers the MCP server, the `AfterAgent`/`BeforeAgent` lesson hooks, and the coaching skill:
198
+
199
+ ```bash
200
+ npx -y devcoach install --gemini
201
+ ```
202
+
203
+ Or install the bundled **Gemini extension** instead: download `devcoach-gemini-extension-<version>.zip` from the [latest release](https://github.com/UltimaPhoenix/dev-coach/releases/latest), unzip, then `gemini extensions install <folder>`. Pick **one** of the two (both provide the same hooks; devcoach detects the extension and skips duplicates). Details: [docs/install/gemini-cli.md](docs/install/gemini-cli.md).
204
+
205
+ </details>
206
+
207
+ <details>
208
+ <summary><strong>Codex CLI</strong> — full coaching loop (hooks + skill) — <strong>Beta</strong></summary>
209
+
210
+ One command registers the MCP server (`codex mcp add`), the `Stop`/`UserPromptSubmit` lesson hooks (`~/.codex/hooks.json`), and the coaching skill (`~/.agents/skills/`):
211
+
212
+ ```bash
213
+ npx -y devcoach install --codex
214
+ ```
215
+
216
+ Codex asks you to **trust** the new hooks once on the next run — approve them or coaching stays inert. Details: [docs/install/codex.md](docs/install/codex.md).
217
+
218
+ </details>
219
+
194
220
  <details>
195
221
  <summary><strong>Other MCP agents</strong> (Cursor, Windsurf, Cline, Continue, Zed…)</summary>
196
222
 
@@ -215,7 +241,7 @@ Add this to your agent's MCP config file:
215
241
  | **Continue.dev** | `~/.continue/config.json` → `mcpServers` |
216
242
  | **Zed** | `.zed/settings.json` → `context_servers` |
217
243
 
218
- > Stop hooks (automatic lesson delivery after each task) are Claude Code-specific. Other agents have full access to all MCP tools and resources — coaching can be triggered manually or by prompting your agent.
244
+ > Stop hooks (automatic lesson delivery after each task) exist for Claude Code, Gemini CLI, and Codex CLI. The agents in this table have full access to all MCP tools and resources — coaching can be triggered manually or by prompting your agent.
219
245
 
220
246
  </details>
221
247
 
@@ -432,7 +458,7 @@ Run `devcoach install` to re-register the server with Claude Code or Claude Desk
432
458
 
433
459
  **"Coaching isn't firing / no lessons appear"**
434
460
 
435
- Run **`devcoach doctor`** — it checks the whole wiring (Node version, hook entries in `~/.claude/settings.json`, skill, MCP registration, database, pacing counters, rate limit) and ends with a verdict explaining exactly why the next stop would or wouldn't cue a lesson. Remember that pacing is intentionally quiet: with the defaults a lesson is cued only after `nudge_every` interactions in a session and within the rate limits — that's by design, not a bug. For a live trace, set `DEVCOACH_HOOK_DEBUG=1` and watch `~/.devcoach/hook.log`: every hook run appends one line with its decision (`paced (3/10)`, `rate limited: …`, `cue`). Hooks are Claude Code-specific; other agents (Cursor, Windsurf, Cline) don't support them — coaching is available on demand via MCP tools or manual prompting.
461
+ Run **`devcoach doctor`** — it checks the whole wiring (Node version, hook entries in `~/.claude/settings.json` — plus `~/.gemini/settings.json` and `~/.codex/hooks.json` when present — skill, MCP registration, database, pacing counters, rate limit) and ends with a verdict explaining exactly why the next stop would or wouldn't cue a lesson. Remember that pacing is intentionally quiet: with the defaults a lesson is cued only after `nudge_every` interactions in a session and within the rate limits — that's by design, not a bug. For a live trace, set `DEVCOACH_HOOK_DEBUG=1` and watch `~/.devcoach/hook.log`: every hook run appends one line with its decision (`paced (3/10)`, `rate limited: …`, `cue`). Hooks exist for Claude Code, Gemini CLI *(beta)*, and Codex CLI *(beta)*; other agents (Cursor, Windsurf, Cline) don't support them — coaching is available on demand via MCP tools or manual prompting.
436
462
 
437
463
  **"Stop hook error occurred" next to a lesson**
438
464
 
package/assets/SKILL.md CHANGED
@@ -1,13 +1,19 @@
1
1
  ---
2
2
  name: devcoach
3
3
  description: >
4
- Personal coaching engine: deliver, log, and manage progressive technical lessons.
5
- Use when a devcoach hook cue asks for a lesson; when the user asks about their
6
- learning — "what did I learn today/this week", "show my profile", "how good am I
7
- at X", "coaching log", "lessons to revisit" — or asks to set up or reconfigure
8
- devcoach ("setup devcoach", "redo onboarding", "reset my topics"); and after
9
- completing a substantial technical task (code, review, commit, debugging, config,
10
- queries, infra) to evaluate whether ONE lesson is due.
4
+ Use for the user's personal learning record and coaching data managed by
5
+ devcoach. Trigger when: (1) the user mentions devcoach in any form — setting it
6
+ up, redoing onboarding, resetting topics, or reviewing/rebuilding their profile
7
+ or notebook; (2) the user asks about their own learning or skill level — what
8
+ they learned recently, their coaching log or lesson history (by period, starred,
9
+ or marked don't-know), how good they are at a technology, lessons to revisit,
10
+ or whether new tech from their recent work should be tracked; (3) a devcoach
11
+ hook cue requests a lesson; (4) you just completed substantial technical work
12
+ (code, review, commit, debugging, config, queries, infra) — then evaluate
13
+ silently whether ONE lesson is due, even when coaching is never mentioned.
14
+ Do NOT use for ordinary development tasks on code, apps, or documents that
15
+ merely contain words like profile, lessons, or notebook — only when the subject
16
+ is the user's own coaching data.
11
17
  ---
12
18
 
13
19
  # devcoach — Progressive Coaching
@@ -17,10 +23,11 @@ by teaching one thing at a time, at the right moment, based on what they actuall
17
23
 
18
24
  The three hard rules, before anything else:
19
25
 
20
- 1. **The lesson card is printed as visible reply text BEFORE calling `log_lesson` —
21
- and only once, ever.** If you suspect the card was never printed, do NOT self-correct
22
- by re-printing: a devcoach hook verifies visibility after the turn and recovers a
23
- missing card itself. A card printed twice is an error.
26
+ 1. **The lesson card is printed as plain reply text BEFORE calling `log_lesson` —
27
+ and only once, ever.** The user sees only text you write directly in the reply:
28
+ the body passed to `log_lesson` is INVISIBLE to them, and composing it does not
29
+ count as showing the card. If, after `log_lesson` returns, your reply does not
30
+ contain the card as written text, write it then — once. Never write it twice.
24
31
  2. **The card ends the reply.** After `log_lesson` returns, output nothing else — no
25
32
  "lesson logged", no summary. The card is the last visible text of the turn.
26
33
  3. **A cue you decline is a `skip_lesson` call.** If a devcoach hook asked for a lesson
@@ -37,6 +44,14 @@ user explicitly asks to (re-)initialise their profile — read `references/onboa
37
44
  in this skill's directory and follow it. Do not deliver a lesson in the same turn as
38
45
  `complete_onboarding`; end the response after confirming setup.
39
46
 
47
+ ## Review & rebuild
48
+
49
+ When the user asks to review or rebuild their profile or notebook — "review my
50
+ profile/notebook", "rebuild/refresh my notebook", "refresh my profile from my
51
+ projects", "any new tech I should track?" — read `references/review.md` in this
52
+ skill's directory and follow it. Those flows are incremental and non-destructive;
53
+ only an explicit "redo onboarding" goes through `references/onboarding.md`.
54
+
40
55
  ## Before delivering a lesson
41
56
 
42
57
  Read the **`devcoach://briefing`** MCP resource — ONE silent read returns everything
@@ -83,6 +98,11 @@ Priority order:
83
98
  Tiebreaker: always prefer the profile topic. Never teach off-context lessons, and
84
99
  never pitch **below** the user's confidence band on that topic.
85
100
 
101
+ When the task's real stack is **not tracked** in the profile, prefer offering to
102
+ track it (Profile expansion below) over teaching it by analogy to a tracked
103
+ topic — analogy filing records the lesson under the wrong stack and can hide an
104
+ entire technology from the coaching record for months.
105
+
86
106
  **Depth per confidence** (per-topic, never an average): `0–3` junior — explain from
87
107
  scratch, analogies, no jargon · `4–6` mid — the why, alternatives, trade-offs ·
88
108
  `7–9` senior — edge cases, production trade-offs, historical context · `10` —
@@ -129,10 +149,13 @@ know / dont_know / skip) — never render a feedback question yourself. Read the
129
149
 
130
150
  - `"know"` / `"dont_know"` → confidence already adjusted server-side. Done.
131
151
  - `null` → elicitation unsupported/declined. Append the text prompt "Did that land?
132
- ✅ know · ❌ don't know · ⏭ skip", collect the reply next turn, then call
133
- `submit_feedback(id, value)` — but only when confidence is below the lesson's band
134
- for "know" (within/above band → already calibrated, skip the call). Never call
135
- `update_knowledge` on top of feedback.
152
+ ✅ know · ❌ don't know · ⏭ skip" — and this line may only ever appear DIRECTLY
153
+ BENEATH the card's closing band in your reply text. If the card is not right
154
+ above it (the body you passed to log_lesson is invisible to the user — composing
155
+ it is not printing it), write the full card first, then this line. Collect the
156
+ reply next turn, then call `submit_feedback(id, value)` — but only when
157
+ confidence is below the lesson's band for "know" (within/above band → already
158
+ calibrated, skip the call). Never call `update_knowledge` on top of feedback.
136
159
 
137
160
  **Starring:** after feedback, if it was `dont_know` on a mid/senior lesson, or
138
161
  `get_lessons({search: topic_id})` shows 2+ lessons on the topic, offer *"Want to save
@@ -21,20 +21,30 @@ This means a user who restores from backup has their knowledge automatically, so
21
21
  only Step 4 runs. On-demand re-setup ("redo onboarding", "reset my topics") always
22
22
  re-runs Steps 1–3 regardless of `knowledge_ready`.
23
23
 
24
- ## Step 1 — Ask how to set up (always ask; never pick for the user)
24
+ ## Step 1 — Ask how to set up (strongly recommend Automatic; never pick for the user)
25
25
 
26
- Present a single choice using the client's question UI (e.g. AskUserQuestion in
27
- Claude Code). Offer exactly three options and mark **Automatic** as recommended:
26
+ Read `devcoach://onboarding` FIRST — its `detected_stack`, `detected_projects`, and
27
+ `scanned_projects` come from a scan of the user's **full Claude Code history** (every
28
+ project Claude has worked in, ranked by recent activity), not just the current folder.
28
29
 
29
- - **Automatic (Recommended)** — detect the tech stack from this project and build a
30
- profile from it.
30
+ Then present a single choice using the client's question UI (e.g. AskUserQuestion in
31
+ Claude Code). Offer exactly three options, and make **Automatic** the first option,
32
+ **strongly recommended**, with its description citing the real evidence — name the
33
+ project count and 2–3 detected topics with where they were seen, e.g. *"I scanned 9
34
+ of your Claude Code projects and found TypeScript (dev-coach), Java (discordbot,
35
+ over-night-runner), Swift (blueprince) — I can build your profile from that."*:
36
+
37
+ - **Automatic (Strongly recommended)** — build the profile from the detected
38
+ history-wide stack; the user only confirms and adjusts confidences.
31
39
  - **Guided** — a step-by-step conversation to map knowledge, confidence levels, and
32
40
  topic groups (thorough, interactive).
33
41
  - **Import backup** — restore knowledge, lessons, and settings from an existing
34
42
  backup file.
35
43
 
36
- Do **not** default to Automatic silently — surface the choice and wait for the user's
37
- answer before proceeding.
44
+ When the scan found nothing (`scanned_projects` 0 or an empty `detected_stack`),
45
+ present Automatic without the evidence sentence — it falls back to the current
46
+ project's files. Do **not** default to Automatic silently — surface the choice and
47
+ wait for the user's answer before proceeding.
38
48
 
39
49
  **If Import backup:** ask for the file path and call `restore` (CLI) with it. Restore
40
50
  brings back knowledge entries automatically — no further DB steps needed. Re-read
@@ -44,11 +54,14 @@ Step 4. If `notebook_ready` is also true, proceed normally.
44
54
  ## Step 2 — Collect topics for the chosen mode
45
55
 
46
56
  **Automatic mode:**
47
- - Read `devcoach://onboarding` and present a merged topic list: `detected_stack`
48
- (auto-detected from project files) enriched with relevant entries from
49
- `default_topics` (the project's default knowledge map).
50
- - Show each topic with its suggested confidence. Ask the user to confirm, adjust,
51
- or remove each: *"Looks right? Or enter 1–10 to change it."*
57
+ - Present a merged topic list: `detected_stack` (history-wide, already merged with
58
+ the current project) enriched with relevant entries from `default_topics` (the
59
+ project's default knowledge map).
60
+ - Show each topic with its suggested confidence **and its provenance** from
61
+ `detected_projects` — e.g. *"java 6 — seen in discordbot, over-night-runner"*.
62
+ Weight what you emphasise by `prompt_count` and `last_activity`: a stack the user
63
+ works in daily deserves more topics than a one-off experiment. Ask the user to
64
+ confirm, adjust, or remove each: *"Looks right? Or enter 1–10 to change it."*
52
65
  - After the list, ask: *"Anything else I missed? List any tools, languages,
53
66
  frameworks, or practices you work with regularly."* — add each with a confidence.
54
67
 
@@ -105,9 +118,11 @@ as the `notebook` field of the `complete_onboarding` call in Step 3. The tool sa
105
118
  to `~/.devcoach/learning-state.md` atomically with the profile (so it is never empty
106
119
  and never created before the user finishes).
107
120
 
108
- Make it **personalized**: draw on everything you know about *this* user — not only this
109
- onboarding conversation, but how they work across **all their projects** (languages and
110
- tools they reach for, recurring habits, strengths, and gaps you have observed elsewhere).
121
+ Make it **personalized**: draw on everything you know about *this* user — this
122
+ onboarding conversation, plus the real cross-project data in `detected_projects`
123
+ (per-project stacks, activity volume and recency, and each project's auto-`memory`
124
+ excerpt — distilled facts about how the user actually works). Cite project names and
125
+ observed habits; never quote prompt text (it is not in the data, by design).
111
126
  Generic boilerplate is a failure; write specific, real notes. Use this structure:
112
127
 
113
128
  ```markdown
@@ -0,0 +1,67 @@
1
+ # devcoach — Review & rebuild flows
2
+
3
+ Read this file when the user asks to review or rebuild their coaching setup:
4
+ "review my notebook", "review my profile", "rebuild my notebook", "refresh my
5
+ profile from my projects", "any new tech I should track?". These flows are
6
+ **incremental and non-destructive** — the only destructive path is a full redo,
7
+ which lives in `references/onboarding.md`.
8
+
9
+ Route by intent:
10
+
11
+ ```
12
+ review my profile / notebook → Review (below)
13
+ rebuild / refresh my notebook → Rebuild notebook (below)
14
+ new tech to track? → New tech check (below)
15
+ redo onboarding / reset topics → references/onboarding.md, Steps 1–3 (confirm first — it wipes)
16
+ ```
17
+
18
+ ## Review
19
+
20
+ 1. Read `devcoach://briefing` — one silent read returns the profile, the taught
21
+ topics, and the notebook.
22
+ 2. Walk the user through the profile **grouped, not topic-by-topic**: show each
23
+ group with its topics and confidences, and ask what looks wrong. Apply
24
+ changes as they come: `update_knowledge` (confidence), `add_topic` /
25
+ `remove_topic` (membership).
26
+ 3. Then show the notebook section by section (Observations, Recurring patterns,
27
+ Recommended focus, Open hypotheses). Ask what is stale or wrong. Fold the
28
+ edits into a revised full markdown and save it with ONE `update_notebook`
29
+ call at the end — never one call per edit.
30
+ 4. Close with the New tech check below.
31
+
32
+ ## Rebuild notebook
33
+
34
+ Re-derive the notebook from real data; the knowledge map is untouched.
35
+
36
+ 1. Read `devcoach://onboarding` — `detected_projects` carries the history-wide
37
+ evidence: per-project stacks, activity volume and recency, and auto-memory
38
+ excerpts. Read `devcoach://briefing` for the current notebook and profile,
39
+ and `get_lessons({period: "all"})` for feedback history (`dont_know` lessons
40
+ are open gaps).
41
+ 2. Compose a fresh notebook (structure in `references/onboarding.md`, Step 4):
42
+ cite real cross-project observations — project names, stacks, what recurs,
43
+ what the memories reveal about how the user works. Preserve prior notes that
44
+ are still true; drop the stale ones. Never quote prompt text — it is not in
45
+ the data, by design.
46
+ 3. Show the draft, adjust to taste, save with `update_notebook`.
47
+
48
+ ## New tech check (keep the profile curated)
49
+
50
+ Compare `detected_stack` + `detected_projects` (from `devcoach://onboarding`)
51
+ against the current profile:
52
+
53
+ - Candidate = a detected topic **absent from the profile** that appears in **2+
54
+ scanned projects** or in the current project.
55
+ - Propose **at most 5** candidates, each with its evidence ("seen in discordbot
56
+ and over-night-runner") and a suggested starting confidence (the detected
57
+ value). Use the client's question UI; `add_topic` ONLY for the ones the user
58
+ confirms — never add silently.
59
+ - Also surface retirement candidates: profile topics at confidence ≤ 3 that
60
+ appear in **no** scanned project. Offer `remove_topic`; keeping them is fine.
61
+ - Nothing qualifies → say so in one line and stop. An overcrowded topic list
62
+ dilutes lesson choice — fewer, real topics beat completeness.
63
+ - `devcoach://onboarding` unreachable, or `detected_projects` empty → derive
64
+ candidates from lesson history instead (`get_lessons`: recurring stacks in
65
+ `task_context` that lack a matching topic), tell the user the evidence is
66
+ history-only, and defer the retirement pass — never guess retirements
67
+ without profile access.
@@ -18,7 +18,15 @@
18
18
  return rtf.format(-Math.floor(diffDays / 365), 'year');
19
19
  }
20
20
 
21
- document.querySelectorAll('[data-ts]').forEach(function (el) {
22
- el.textContent = relativeTime(el.dataset.ts);
21
+ function applyRelativeTimes(root) {
22
+ root.querySelectorAll('[data-ts]').forEach(function (el) {
23
+ el.textContent = relativeTime(el.dataset.ts);
24
+ });
25
+ }
26
+
27
+ applyRelativeTimes(document);
28
+ /* HTMX-swapped fragments (lesson rows, lesson meta) arrive with raw dates. */
29
+ document.body.addEventListener('htmx:afterSettle', function () {
30
+ applyRelativeTimes(document);
23
31
  });
24
32
  })();