devcoach 0.3.10__tar.gz → 0.3.12__tar.gz

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.
Files changed (93) hide show
  1. {devcoach-0.3.10 → devcoach-0.3.12}/.github/workflows/ci.yml +145 -2
  2. {devcoach-0.3.10 → devcoach-0.3.12}/.gitignore +1 -0
  3. {devcoach-0.3.10 → devcoach-0.3.12}/CLAUDE.md +1 -1
  4. {devcoach-0.3.10 → devcoach-0.3.12}/PKG-INFO +12 -13
  5. {devcoach-0.3.10 → devcoach-0.3.12}/README.md +11 -12
  6. devcoach-0.3.12/devcoach.spec +74 -0
  7. {devcoach-0.3.10 → devcoach-0.3.12}/docs/how-it-works.md +0 -16
  8. {devcoach-0.3.10 → devcoach-0.3.12}/docs/index.md +0 -9
  9. {devcoach-0.3.10 → devcoach-0.3.12}/pyproject.toml +1 -1
  10. {devcoach-0.3.10 → devcoach-0.3.12}/sonar-project.properties +1 -1
  11. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/SKILL.md +144 -48
  12. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/cli/commands.py +5 -1
  13. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/core/coach.py +5 -1
  14. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/core/db.py +30 -62
  15. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/core/models.py +11 -9
  16. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/mcp/server.py +54 -14
  17. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/web/app.py +7 -1
  18. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/web/templates/settings.html +1 -0
  19. {devcoach-0.3.10 → devcoach-0.3.12}/tests/conftest.py +5 -3
  20. {devcoach-0.3.10 → devcoach-0.3.12}/tests/test_cli_commands.py +26 -1
  21. {devcoach-0.3.10 → devcoach-0.3.12}/tests/test_db_extra.py +10 -9
  22. {devcoach-0.3.10 → devcoach-0.3.12}/tests/test_mcp_server.py +134 -3
  23. {devcoach-0.3.10 → devcoach-0.3.12}/tests/test_web_extra.py +14 -0
  24. {devcoach-0.3.10 → devcoach-0.3.12}/uv.lock +146 -119
  25. devcoach-0.3.10/SKILL.md +0 -185
  26. {devcoach-0.3.10 → devcoach-0.3.12}/.github/dependabot.yml +0 -0
  27. {devcoach-0.3.10 → devcoach-0.3.12}/.github/scripts/export_backup.py +0 -0
  28. {devcoach-0.3.10 → devcoach-0.3.12}/.github/scripts/fixtures/devcoach-backup.zip +0 -0
  29. {devcoach-0.3.10 → devcoach-0.3.12}/.github/scripts/take_screenshots.py +0 -0
  30. {devcoach-0.3.10 → devcoach-0.3.12}/.github/workflows/ruff-autofix.yml +0 -0
  31. {devcoach-0.3.10 → devcoach-0.3.12}/.github/workflows/update-screenshots.yml +0 -0
  32. {devcoach-0.3.10 → devcoach-0.3.12}/LICENSE +0 -0
  33. {devcoach-0.3.10 → devcoach-0.3.12}/NOTICE +0 -0
  34. {devcoach-0.3.10 → devcoach-0.3.12}/docs/PLAN.md +0 -0
  35. {devcoach-0.3.10 → devcoach-0.3.12}/docs/cli.md +0 -0
  36. {devcoach-0.3.10 → devcoach-0.3.12}/docs/configuration.md +0 -0
  37. {devcoach-0.3.10 → devcoach-0.3.12}/docs/favicon.svg +0 -0
  38. {devcoach-0.3.10 → devcoach-0.3.12}/docs/getting-started.md +0 -0
  39. {devcoach-0.3.10 → devcoach-0.3.12}/docs/mcp-server.md +0 -0
  40. {devcoach-0.3.10 → devcoach-0.3.12}/docs/screenshots/knowledge-map-dark.png +0 -0
  41. {devcoach-0.3.10 → devcoach-0.3.12}/docs/screenshots/knowledge-map-light.png +0 -0
  42. {devcoach-0.3.10 → devcoach-0.3.12}/docs/screenshots/lesson-ci-cd-pipeline-stages-dark.png +0 -0
  43. {devcoach-0.3.10 → devcoach-0.3.12}/docs/screenshots/lesson-ci-cd-pipeline-stages-light.png +0 -0
  44. {devcoach-0.3.10 → devcoach-0.3.12}/docs/screenshots/lesson-docker-layer-cache-dark.png +0 -0
  45. {devcoach-0.3.10 → devcoach-0.3.12}/docs/screenshots/lesson-docker-layer-cache-light.png +0 -0
  46. {devcoach-0.3.10 → devcoach-0.3.12}/docs/screenshots/lesson-git-interactive-rebase-dark.png +0 -0
  47. {devcoach-0.3.10 → devcoach-0.3.12}/docs/screenshots/lesson-git-interactive-rebase-light.png +0 -0
  48. {devcoach-0.3.10 → devcoach-0.3.12}/docs/screenshots/lesson-postgresql-explain-analyze-dark.png +0 -0
  49. {devcoach-0.3.10 → devcoach-0.3.12}/docs/screenshots/lesson-postgresql-explain-analyze-light.png +0 -0
  50. {devcoach-0.3.10 → devcoach-0.3.12}/docs/screenshots/lesson-redis-cache-stampede-dark.png +0 -0
  51. {devcoach-0.3.10 → devcoach-0.3.12}/docs/screenshots/lesson-redis-cache-stampede-light.png +0 -0
  52. {devcoach-0.3.10 → devcoach-0.3.12}/docs/screenshots/lessons-dark.png +0 -0
  53. {devcoach-0.3.10 → devcoach-0.3.12}/docs/screenshots/lessons-light.png +0 -0
  54. {devcoach-0.3.10 → devcoach-0.3.12}/docs/screenshots/settings-dark.png +0 -0
  55. {devcoach-0.3.10 → devcoach-0.3.12}/docs/screenshots/settings-light.png +0 -0
  56. {devcoach-0.3.10 → devcoach-0.3.12}/docs/web-ui.md +0 -0
  57. {devcoach-0.3.10 → devcoach-0.3.12}/mkdocs.yml +0 -0
  58. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/__init__.py +0 -0
  59. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/cli/__init__.py +0 -0
  60. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/core/__init__.py +0 -0
  61. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/core/detect.py +0 -0
  62. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/core/git.py +0 -0
  63. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/core/prompts.py +0 -0
  64. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/mcp/__init__.py +0 -0
  65. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/web/__init__.py +0 -0
  66. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/web/static/favicon.svg +0 -0
  67. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/web/static/relative-time.js +0 -0
  68. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/web/static/style.css +0 -0
  69. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/web/static/vendor/alpinejs.min.js +0 -0
  70. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/web/static/vendor/flatpickr-dark.min.css +0 -0
  71. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/web/static/vendor/flatpickr.min.css +0 -0
  72. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/web/static/vendor/flatpickr.min.js +0 -0
  73. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/web/static/vendor/highlight.min.js +0 -0
  74. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/web/static/vendor/hljs-dark.min.css +0 -0
  75. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/web/static/vendor/hljs-light.min.css +0 -0
  76. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/web/static/vendor/htmx.min.js +0 -0
  77. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/web/static/vendor/icons/bitbucket.svg +0 -0
  78. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/web/static/vendor/icons/github.svg +0 -0
  79. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/web/static/vendor/icons/gitlab.svg +0 -0
  80. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/web/static/vendor/icons/vscode.svg +0 -0
  81. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/web/static/vendor/marked.min.js +0 -0
  82. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/web/static/vendor/tailwind.js +0 -0
  83. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/web/templates/base.html +0 -0
  84. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/web/templates/lesson_detail.html +0 -0
  85. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/web/templates/lessons.html +0 -0
  86. {devcoach-0.3.10 → devcoach-0.3.12}/src/devcoach/web/templates/profile.html +0 -0
  87. {devcoach-0.3.10 → devcoach-0.3.12}/tests/__init__.py +0 -0
  88. {devcoach-0.3.10 → devcoach-0.3.12}/tests/test_cli.py +0 -0
  89. {devcoach-0.3.10 → devcoach-0.3.12}/tests/test_coach.py +0 -0
  90. {devcoach-0.3.10 → devcoach-0.3.12}/tests/test_detect.py +0 -0
  91. {devcoach-0.3.10 → devcoach-0.3.12}/tests/test_git.py +0 -0
  92. {devcoach-0.3.10 → devcoach-0.3.12}/tests/test_prompts.py +0 -0
  93. {devcoach-0.3.10 → devcoach-0.3.12}/tests/test_web.py +0 -0
@@ -257,11 +257,61 @@ jobs:
257
257
  path: dist/
258
258
  - uses: pypa/gh-action-pypi-publish@release/v1
259
259
 
260
+ # ── Build binaries ──────────────────────────────────────────────────────
261
+ # Builds PyInstaller single-file executables for all target platforms.
262
+ # Only runs on releases (tag push or workflow_dispatch) — not on PRs or main pushes.
263
+ build-binaries:
264
+ name: Build binary (${{ matrix.platform }})
265
+ needs: [bump, lint, test]
266
+ if: >
267
+ always()
268
+ && (needs.bump.result == 'success' || needs.bump.result == 'skipped')
269
+ && needs.lint.result == 'success'
270
+ && needs.test.result == 'success'
271
+ && (startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch')
272
+ strategy:
273
+ fail-fast: false
274
+ matrix:
275
+ include:
276
+ - platform: darwin-arm64
277
+ runs-on: macos-latest
278
+ - platform: darwin-amd64
279
+ runs-on: macos-13
280
+ - platform: linux-amd64
281
+ runs-on: ubuntu-latest
282
+ - platform: linux-arm64
283
+ runs-on: ubuntu-24.04-arm
284
+ runs-on: ${{ matrix.runs-on }}
285
+ steps:
286
+ - uses: actions/checkout@v6
287
+ with:
288
+ ref: ${{ needs.bump.outputs.tag || github.ref }}
289
+ - uses: astral-sh/setup-uv@v7
290
+ with:
291
+ python-version: "3.12"
292
+ - name: Install dependencies and PyInstaller
293
+ run: |
294
+ uv sync
295
+ uv pip install pyinstaller
296
+ - name: Build binary
297
+ run: uv run pyinstaller devcoach.spec --distpath dist
298
+ - name: Rename binary
299
+ run: mv dist/devcoach dist/devcoach-${{ matrix.platform }}
300
+ - uses: actions/upload-artifact@v7
301
+ with:
302
+ name: binary-${{ matrix.platform }}
303
+ path: dist/devcoach-${{ matrix.platform }}
304
+ retention-days: 7
305
+
260
306
  # ── GitHub Release ──────────────────────────────────────────────────────
261
307
  github-release:
262
308
  name: Create GitHub Release
263
- needs: [bump, publish]
264
- if: always() && needs.publish.result == 'success' && (needs.bump.result == 'success' || startsWith(github.ref, 'refs/tags/v'))
309
+ needs: [bump, publish, build-binaries]
310
+ if: >
311
+ always()
312
+ && needs.publish.result == 'success'
313
+ && needs.build-binaries.result == 'success'
314
+ && (needs.bump.result == 'success' || startsWith(github.ref, 'refs/tags/v'))
265
315
  runs-on: ubuntu-latest
266
316
  permissions:
267
317
  contents: write
@@ -273,9 +323,102 @@ jobs:
273
323
  with:
274
324
  name: dist
275
325
  path: dist/
326
+ - uses: actions/download-artifact@v8
327
+ with:
328
+ pattern: binary-*
329
+ merge-multiple: true
330
+ path: dist/
276
331
  - uses: softprops/action-gh-release@v3
277
332
  with:
278
333
  tag_name: ${{ needs.bump.outputs.tag || github.ref_name }}
279
334
  files: dist/*
280
335
  generate_release_notes: true
281
336
  fail_on_unmatched_files: true
337
+
338
+ # ── Bump Homebrew formula ────────────────────────────────────────────────
339
+ # After a successful release, updates Formula/devcoach.rb in homebrew-tap
340
+ # with the new version and SHA256 hashes for all platform binaries.
341
+ # Requires secret HOMEBREW_TAP_TOKEN (classic PAT, repo scope on homebrew-tap).
342
+ bump-homebrew-formula:
343
+ name: Bump Homebrew formula
344
+ needs: [bump, github-release, build-binaries]
345
+ if: >
346
+ always()
347
+ && needs.github-release.result == 'success'
348
+ && needs.build-binaries.result == 'success'
349
+ runs-on: ubuntu-latest
350
+ steps:
351
+ - uses: actions/download-artifact@v8
352
+ with:
353
+ pattern: binary-*
354
+ merge-multiple: true
355
+ path: binaries/
356
+ - name: Compute SHA256 hashes
357
+ id: sha
358
+ run: |
359
+ echo "darwin_arm64=$(sha256sum binaries/devcoach-darwin-arm64 | cut -d' ' -f1)" >> "$GITHUB_OUTPUT"
360
+ echo "darwin_amd64=$(sha256sum binaries/devcoach-darwin-amd64 | cut -d' ' -f1)" >> "$GITHUB_OUTPUT"
361
+ echo "linux_amd64=$(sha256sum binaries/devcoach-linux-amd64 | cut -d' ' -f1)" >> "$GITHUB_OUTPUT"
362
+ echo "linux_arm64=$(sha256sum binaries/devcoach-linux-arm64 | cut -d' ' -f1)" >> "$GITHUB_OUTPUT"
363
+ - name: Clone homebrew-tap
364
+ run: |
365
+ git clone "https://x-access-token:${{ secrets.HOMEBREW_TAP_TOKEN }}@github.com/UltimaPhoenix/homebrew-tap.git" tap
366
+ - name: Update formula
367
+ env:
368
+ TAG: ${{ needs.bump.outputs.tag || github.ref_name }}
369
+ DARWIN_ARM64_SHA: ${{ steps.sha.outputs.darwin_arm64 }}
370
+ DARWIN_AMD64_SHA: ${{ steps.sha.outputs.darwin_amd64 }}
371
+ LINUX_AMD64_SHA: ${{ steps.sha.outputs.linux_amd64 }}
372
+ LINUX_ARM64_SHA: ${{ steps.sha.outputs.linux_arm64 }}
373
+ run: |
374
+ VERSION="${TAG#v}"
375
+ cat > tap/Formula/devcoach.rb << FORMULA
376
+ class Devcoach < Formula
377
+ desc "Progressive technical coaching MCP server for Claude Code and Claude Desktop"
378
+ homepage "https://github.com/UltimaPhoenix/dev-coach"
379
+ version "$VERSION"
380
+ license "Apache-2.0"
381
+
382
+ on_macos do
383
+ on_arm do
384
+ url "https://github.com/UltimaPhoenix/dev-coach/releases/download/$TAG/devcoach-darwin-arm64"
385
+ sha256 "$DARWIN_ARM64_SHA"
386
+ end
387
+ on_intel do
388
+ url "https://github.com/UltimaPhoenix/dev-coach/releases/download/$TAG/devcoach-darwin-amd64"
389
+ sha256 "$DARWIN_AMD64_SHA"
390
+ end
391
+ end
392
+
393
+ on_linux do
394
+ on_arm do
395
+ url "https://github.com/UltimaPhoenix/dev-coach/releases/download/$TAG/devcoach-linux-arm64"
396
+ sha256 "$LINUX_ARM64_SHA"
397
+ end
398
+ on_intel do
399
+ url "https://github.com/UltimaPhoenix/dev-coach/releases/download/$TAG/devcoach-linux-amd64"
400
+ sha256 "$LINUX_AMD64_SHA"
401
+ end
402
+ end
403
+
404
+ def install
405
+ binary = Dir["devcoach-*"].first
406
+ chmod 0755, binary
407
+ bin.install binary => "devcoach"
408
+ end
409
+
410
+ test do
411
+ assert_match "devcoach", shell_output("#{bin}/devcoach --help 2>&1")
412
+ end
413
+ end
414
+ FORMULA
415
+ - name: Commit and push
416
+ run: |
417
+ TAG="${{ needs.bump.outputs.tag || github.ref_name }}"
418
+ VERSION="${TAG#v}"
419
+ cd tap
420
+ git config user.name "github-actions[bot]"
421
+ git config user.email "github-actions[bot]@users.noreply.github.com"
422
+ git add Formula/devcoach.rb
423
+ git diff --cached --quiet || git commit -m "devcoach $VERSION"
424
+ git push
@@ -31,6 +31,7 @@ MANIFEST
31
31
  # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
32
  *.manifest
33
33
  *.spec
34
+ !devcoach.spec
34
35
 
35
36
  # Installer logs
36
37
  pip-log.txt
@@ -182,7 +182,7 @@ The `log_lesson` tool accepts this schema:
182
182
  {
183
183
  "id": "uuid-or-random-string",
184
184
  "timestamp": "2025-01-15T20:30:00Z",
185
- "topic_id": "python_generators",
185
+ "topic_id": "python",
186
186
  "category": "python",
187
187
  "title": "Generator expressions vs list comprehensions",
188
188
  "level": "mid",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devcoach
3
- Version: 0.3.10
3
+ Version: 0.3.12
4
4
  Summary: A local MCP server that acts as a progressive technical coach for Claude Code and Claude Desktop
5
5
  Project-URL: Homepage, https://github.com/UltimaPhoenix/dev-coach
6
6
  Project-URL: Repository, https://github.com/UltimaPhoenix/dev-coach
@@ -262,15 +262,6 @@ flowchart TD
262
262
  E --> G
263
263
  G --> F([Done])
264
264
  G -.->|prompts| U(["You: ✅ ❌ ⏭"])
265
-
266
- style loop fill:none,stroke:#AAAAAA,stroke-dasharray:5 5,color:#757575
267
- classDef action fill:#D4E4D8,stroke:#8BAF96,color:#1E1E1E
268
- classDef term fill:#E8E8E4,stroke:#AAAAAA,color:#1E1E1E
269
- classDef user fill:#F5EDE3,stroke:#D4A27F,color:#1E1E1E
270
-
271
- class B,D,E,G action
272
- class A,F,Z term
273
- class U user
274
265
  ```
275
266
 
276
267
  → [Full decision flow: session startup · lesson selection · depth calibration](https://ultimaphoenix.github.io/dev-coach/how-it-works/)
@@ -289,13 +280,21 @@ Everything runs **locally**. No data leaves your machine. One SQLite file at `~/
289
280
 
290
281
  ## Installation
291
282
 
292
- ### Recommended no permanent install needed
283
+ ### Homebrew (macOS / Linux)
284
+
285
+ ```bash
286
+ brew tap UltimaPhoenix/tap && brew install devcoach
287
+ ```
288
+
289
+ Pre-built native binaries — no Python required.
290
+
291
+ ### uvx — no permanent install needed
293
292
 
294
293
  ```bash
295
294
  uvx devcoach mcp # starts the MCP server directly
296
295
  ```
297
296
 
298
- ### Permanent install
297
+ ### uv tool — permanent install
299
298
 
300
299
  ```bash
301
300
  uv tool install devcoach
@@ -309,7 +308,7 @@ devcoach install
309
308
 
310
309
  Restart Claude Code or Claude Desktop after installing.
311
310
 
312
- > **Requirements:** [uv](https://docs.astral.sh/uv/) · Python 3.12+ · Claude Code or Claude Desktop
311
+ > **Requirements (uvx/uv):** [uv](https://docs.astral.sh/uv/) · Python 3.12+ · Claude Code or Claude Desktop
313
312
 
314
313
  ---
315
314
 
@@ -31,15 +31,6 @@ flowchart TD
31
31
  E --> G
32
32
  G --> F([Done])
33
33
  G -.->|prompts| U(["You: ✅ ❌ ⏭"])
34
-
35
- style loop fill:none,stroke:#AAAAAA,stroke-dasharray:5 5,color:#757575
36
- classDef action fill:#D4E4D8,stroke:#8BAF96,color:#1E1E1E
37
- classDef term fill:#E8E8E4,stroke:#AAAAAA,color:#1E1E1E
38
- classDef user fill:#F5EDE3,stroke:#D4A27F,color:#1E1E1E
39
-
40
- class B,D,E,G action
41
- class A,F,Z term
42
- class U user
43
34
  ```
44
35
 
45
36
  → [Full decision flow: session startup · lesson selection · depth calibration](https://ultimaphoenix.github.io/dev-coach/how-it-works/)
@@ -58,13 +49,21 @@ Everything runs **locally**. No data leaves your machine. One SQLite file at `~/
58
49
 
59
50
  ## Installation
60
51
 
61
- ### Recommended no permanent install needed
52
+ ### Homebrew (macOS / Linux)
53
+
54
+ ```bash
55
+ brew tap UltimaPhoenix/tap && brew install devcoach
56
+ ```
57
+
58
+ Pre-built native binaries — no Python required.
59
+
60
+ ### uvx — no permanent install needed
62
61
 
63
62
  ```bash
64
63
  uvx devcoach mcp # starts the MCP server directly
65
64
  ```
66
65
 
67
- ### Permanent install
66
+ ### uv tool — permanent install
68
67
 
69
68
  ```bash
70
69
  uv tool install devcoach
@@ -78,7 +77,7 @@ devcoach install
78
77
 
79
78
  Restart Claude Code or Claude Desktop after installing.
80
79
 
81
- > **Requirements:** [uv](https://docs.astral.sh/uv/) · Python 3.12+ · Claude Code or Claude Desktop
80
+ > **Requirements (uvx/uv):** [uv](https://docs.astral.sh/uv/) · Python 3.12+ · Claude Code or Claude Desktop
82
81
 
83
82
  ---
84
83
 
@@ -0,0 +1,74 @@
1
+ # -*- mode: python ; coding: utf-8 -*-
2
+ import sys
3
+ from pathlib import Path
4
+
5
+ src = Path("src/devcoach")
6
+
7
+ datas = [
8
+ (str(src / "SKILL.md"), "devcoach"),
9
+ (str(src / "web" / "templates"), "devcoach/web/templates"),
10
+ (str(src / "web" / "static"), "devcoach/web/static"),
11
+ ]
12
+
13
+ hidden_imports = [
14
+ # pydantic-core is a compiled extension — ensure it's picked up
15
+ "pydantic_core",
16
+ "pydantic_core._pydantic_core",
17
+ # fastmcp / mcp internals that may be dynamically imported
18
+ "mcp",
19
+ "mcp.server",
20
+ "mcp.server.stdio",
21
+ "mcp.types",
22
+ # uvicorn needs these
23
+ "uvicorn.logging",
24
+ "uvicorn.loops",
25
+ "uvicorn.loops.auto",
26
+ "uvicorn.protocols",
27
+ "uvicorn.protocols.http",
28
+ "uvicorn.protocols.http.auto",
29
+ "uvicorn.protocols.websockets",
30
+ "uvicorn.protocols.websockets.auto",
31
+ "uvicorn.lifespan",
32
+ "uvicorn.lifespan.on",
33
+ # email / multipart used by starlette
34
+ "email.mime.multipart",
35
+ "email.mime.text",
36
+ "email.mime.base",
37
+ # sqlite3 is stdlib but needs explicit inclusion on some platforms
38
+ "sqlite3",
39
+ "_sqlite3",
40
+ ]
41
+
42
+ a = Analysis(
43
+ ["src/devcoach/mcp/server.py"],
44
+ pathex=["src"],
45
+ binaries=[],
46
+ datas=datas,
47
+ hiddenimports=hidden_imports,
48
+ hookspath=[],
49
+ hooksconfig={},
50
+ runtime_hooks=[],
51
+ excludes=["tkinter", "matplotlib", "numpy", "scipy", "PIL"],
52
+ noarchive=False,
53
+ )
54
+
55
+ pyz = PYZ(a.pure)
56
+
57
+ exe = EXE(
58
+ pyz,
59
+ a.scripts,
60
+ a.binaries,
61
+ a.datas,
62
+ [],
63
+ name="devcoach",
64
+ debug=False,
65
+ bootloader_ignore_signals=False,
66
+ strip=False,
67
+ upx=False,
68
+ console=True,
69
+ disable_windowed_traceback=False,
70
+ argv_emulation=False,
71
+ target_arch=None,
72
+ codesign_identity=None,
73
+ entitlements_file=None,
74
+ )
@@ -25,13 +25,6 @@ flowchart LR
25
25
  D
26
26
  E
27
27
  end
28
-
29
- style onboarding fill:none,stroke:#AAAAAA,stroke-dasharray:5 5,color:#757575
30
- classDef action fill:#D4E4D8,stroke:#8BAF96,color:#1E1E1E
31
- classDef term fill:#E8E8E4,stroke:#AAAAAA,color:#1E1E1E
32
-
33
- class C,D,E,F action
34
- class A,G term
35
28
  ```
36
29
 
37
30
  ---
@@ -58,15 +51,6 @@ flowchart TD
58
51
  E --> G
59
52
  G --> F([Done])
60
53
  G -.->|prompts| U(["You: ✅ ❌ ⏭"])
61
-
62
- style loop fill:none,stroke:#AAAAAA,stroke-dasharray:5 5,color:#757575
63
- classDef action fill:#D4E4D8,stroke:#8BAF96,color:#1E1E1E
64
- classDef term fill:#E8E8E4,stroke:#AAAAAA,color:#1E1E1E
65
- classDef user fill:#F5EDE3,stroke:#D4A27F,color:#1E1E1E
66
-
67
- class B,D,E,G action
68
- class A,F,Z term
69
- class U user
70
54
  ```
71
55
 
72
56
  ---
@@ -25,15 +25,6 @@ flowchart TD
25
25
  E --> G
26
26
  G --> F([Done])
27
27
  G -.->|prompts| U(["You: ✅ ❌ ⏭"])
28
-
29
- style loop fill:none,stroke:#AAAAAA,stroke-dasharray:5 5,color:#757575
30
- classDef action fill:#D4E4D8,stroke:#8BAF96,color:#1E1E1E
31
- classDef term fill:#E8E8E4,stroke:#AAAAAA,color:#1E1E1E
32
- classDef user fill:#F5EDE3,stroke:#D4A27F,color:#1E1E1E
33
-
34
- class B,D,E,G action
35
- class A,F,Z term
36
- class U user
37
28
  ```
38
29
 
39
30
  → [Full decision flow: session startup · lesson selection · depth calibration](how-it-works.md)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "devcoach"
3
- version = "0.3.10"
3
+ version = "0.3.12"
4
4
  description = "A local MCP server that acts as a progressive technical coach for Claude Code and Claude Desktop"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -2,7 +2,7 @@ sonar.projectKey=UltimaPhoenix_dev-coach
2
2
  sonar.organization=ultimaphoenix
3
3
 
4
4
  sonar.projectName=devcoach
5
- sonar.projectVersion=0.3.10
5
+ sonar.projectVersion=0.3.12
6
6
 
7
7
  sonar.sources=src
8
8
  sonar.tests=tests