@rm0nroe/coach-claw 1.0.6

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 (100) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +311 -0
  3. package/coach/README.md +99 -0
  4. package/coach/bin/aggregate_facets.py +274 -0
  5. package/coach/bin/analyze.py +678 -0
  6. package/coach/bin/bank.py +247 -0
  7. package/coach/bin/banner_themes.py +645 -0
  8. package/coach/bin/coach_paths.py +33 -0
  9. package/coach/bin/coexistence_check.py +129 -0
  10. package/coach/bin/configure.py +245 -0
  11. package/coach/bin/cron_check.py +81 -0
  12. package/coach/bin/default_statusline.py +135 -0
  13. package/coach/bin/doctor.py +663 -0
  14. package/coach/bin/insights-llm.sh +264 -0
  15. package/coach/bin/insights.sh +163 -0
  16. package/coach/bin/insights_window.py +111 -0
  17. package/coach/bin/marker_io.py +154 -0
  18. package/coach/bin/merge.py +671 -0
  19. package/coach/bin/redact.py +86 -0
  20. package/coach/bin/render_env.py +148 -0
  21. package/coach/bin/reward_hints.py +87 -0
  22. package/coach/bin/run-insights.sh +20 -0
  23. package/coach/bin/run_with_lock.py +85 -0
  24. package/coach/bin/scoring.py +260 -0
  25. package/coach/bin/skill_inventory.py +215 -0
  26. package/coach/bin/stats.py +459 -0
  27. package/coach/bin/status.py +293 -0
  28. package/coach/bin/statusline_self_patch.py +205 -0
  29. package/coach/bin/statusline_variants.py +146 -0
  30. package/coach/bin/statusline_wrap.py +244 -0
  31. package/coach/bin/statusline_wrap_action.py +460 -0
  32. package/coach/bin/switch_to_plugin.py +256 -0
  33. package/coach/bin/themes.py +256 -0
  34. package/coach/bin/user_config.py +176 -0
  35. package/coach/bin/xp_accounting.py +98 -0
  36. package/coach/changelog.md +4 -0
  37. package/coach/default-statusline-command.sh +19 -0
  38. package/coach/default-statusline-wrap-command.sh +15 -0
  39. package/coach/profile.yaml +37 -0
  40. package/coach/tests/conftest.py +13 -0
  41. package/coach/tests/test_aggregate_facets.py +379 -0
  42. package/coach/tests/test_analyze_aggregate.py +153 -0
  43. package/coach/tests/test_analyze_redaction.py +105 -0
  44. package/coach/tests/test_analyze_strengths.py +165 -0
  45. package/coach/tests/test_bank_atomic_write.py +61 -0
  46. package/coach/tests/test_bank_concurrency.py +126 -0
  47. package/coach/tests/test_banner_themes.py +981 -0
  48. package/coach/tests/test_celebrate_dedup.py +409 -0
  49. package/coach/tests/test_coach_paths.py +50 -0
  50. package/coach/tests/test_coexistence_check.py +128 -0
  51. package/coach/tests/test_configure.py +258 -0
  52. package/coach/tests/test_cron_check.py +118 -0
  53. package/coach/tests/test_cron_nudge_hook.py +134 -0
  54. package/coach/tests/test_detection_parity.py +105 -0
  55. package/coach/tests/test_doctor.py +595 -0
  56. package/coach/tests/test_hook_bespoke_dispatch.py +288 -0
  57. package/coach/tests/test_hook_module_resolution.py +116 -0
  58. package/coach/tests/test_hook_relevance.py +996 -0
  59. package/coach/tests/test_hook_render_env.py +364 -0
  60. package/coach/tests/test_hook_session_id_guard.py +160 -0
  61. package/coach/tests/test_insights_llm.py +759 -0
  62. package/coach/tests/test_insights_llm_venv_path.py +109 -0
  63. package/coach/tests/test_insights_window.py +237 -0
  64. package/coach/tests/test_install.py +1150 -0
  65. package/coach/tests/test_install_pyyaml_fallback.py +142 -0
  66. package/coach/tests/test_marker_consumption.py +167 -0
  67. package/coach/tests/test_marker_writer_locking.py +305 -0
  68. package/coach/tests/test_merge.py +413 -0
  69. package/coach/tests/test_no_broken_mktemp.py +90 -0
  70. package/coach/tests/test_render_env.py +137 -0
  71. package/coach/tests/test_render_env_glyphs.py +119 -0
  72. package/coach/tests/test_reward_hints.py +59 -0
  73. package/coach/tests/test_scoring.py +147 -0
  74. package/coach/tests/test_session_start_weekly_trigger.py +92 -0
  75. package/coach/tests/test_skill_inventory.py +368 -0
  76. package/coach/tests/test_stats_hybrid.py +142 -0
  77. package/coach/tests/test_status_accounting.py +41 -0
  78. package/coach/tests/test_statusline_failsafe.py +70 -0
  79. package/coach/tests/test_statusline_self_patch.py +261 -0
  80. package/coach/tests/test_statusline_variants.py +110 -0
  81. package/coach/tests/test_statusline_wrap.py +196 -0
  82. package/coach/tests/test_statusline_wrap_action.py +408 -0
  83. package/coach/tests/test_switch_to_plugin.py +360 -0
  84. package/coach/tests/test_themes.py +104 -0
  85. package/coach/tests/test_user_config.py +160 -0
  86. package/coach/tests/test_wrap_announce_hook.py +130 -0
  87. package/coach/tests/test_xp_accounting.py +55 -0
  88. package/hooks/coach-session-start.py +536 -0
  89. package/hooks/coach-user-prompt.py +2288 -0
  90. package/install-launchd.sh +102 -0
  91. package/install.sh +597 -0
  92. package/launchd/com.local.claude-coach.plist.template +34 -0
  93. package/launchd/run-insights.sh +20 -0
  94. package/npm/coach-claw.js +259 -0
  95. package/package.json +52 -0
  96. package/requirements.txt +11 -0
  97. package/settings-snippet.json +31 -0
  98. package/skills/coach/SKILL.md +107 -0
  99. package/skills/coach-insights/SKILL.md +78 -0
  100. package/skills/config/SKILL.md +149 -0
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env bash
2
+ # Optional add-on: register a macOS launchd job that runs the deterministic
3
+ # Coach insights pass daily at 04:00 local time.
4
+ #
5
+ # The scheduled runner (bin/insights.sh) does NOT go through the claude CLI
6
+ # — it invokes the structural analyzer + merge script directly, which is
7
+ # faster and more reliable than spawning `claude -p` for the LLM-driven
8
+ # `/coach-insights` skill on a cron schedule.
9
+ #
10
+ # Requires the main coach installer (./install.sh) to have been run first.
11
+ # Idempotent — re-run to refresh the plist.
12
+ #
13
+ # To remove: see commands at the bottom of this script's stdout.
14
+
15
+ set -euo pipefail
16
+
17
+ BUNDLE_DIR="$(cd "$(dirname "$0")" && pwd)"
18
+ TEMPLATE_PLIST="$BUNDLE_DIR/launchd/com.local.claude-coach.plist.template"
19
+ TEMPLATE_WRAPPER="$BUNDLE_DIR/launchd/run-insights.sh"
20
+
21
+ PLIST_DST="$HOME/Library/LaunchAgents/com.local.claude-coach.plist"
22
+ WRAPPER_DST="$HOME/.claude/coach/bin/run-insights.sh"
23
+ LABEL="com.local.claude-coach"
24
+
25
+ bold() { printf "\033[1m%s\033[0m\n" "$*"; }
26
+ ok() { printf "\033[32m OK: %s\033[0m\n" "$*"; }
27
+ die() { printf "\033[31m ERROR: %s\033[0m\n" "$*"; exit 1; }
28
+
29
+ # --- Preflight ---------------------------------------------------------------
30
+
31
+ bold "Preflight"
32
+
33
+ if [[ "$(uname -s)" != "Darwin" ]]; then
34
+ die "install-launchd.sh is macOS-only (launchd doesn't exist on Linux). On Linux, add a crontab entry that runs ~/.claude/coach/bin/insights.sh 1d — see README.md §Schedule."
35
+ fi
36
+ if ! command -v plutil >/dev/null 2>&1; then
37
+ die "plutil not found (expected on macOS). Are you on a headless VM with XCode tools missing?"
38
+ fi
39
+ if ! command -v launchctl >/dev/null 2>&1; then
40
+ die "launchctl not found — required to register the job."
41
+ fi
42
+ if [[ ! -d "$HOME/.claude/coach" ]]; then
43
+ die "$HOME/.claude/coach does not exist. Run ./install.sh first."
44
+ fi
45
+ if [[ ! -x "$HOME/.claude/coach/bin/insights.sh" ]]; then
46
+ die "$HOME/.claude/coach/bin/insights.sh missing. Re-run ./install.sh."
47
+ fi
48
+ ok "macOS + launchctl + plutil available"
49
+ ok "coach data dir present"
50
+ ok "insights.sh present"
51
+
52
+ # --- Install wrapper + plist ------------------------------------------------
53
+
54
+ bold "Installing"
55
+
56
+ mkdir -p "$HOME/.claude/coach/bin" "$HOME/Library/LaunchAgents"
57
+
58
+ cp "$TEMPLATE_WRAPPER" "$WRAPPER_DST"
59
+ chmod +x "$WRAPPER_DST"
60
+ ok "wrote $WRAPPER_DST"
61
+
62
+ sed "s|@HOME@|$HOME|g" "$TEMPLATE_PLIST" > "$PLIST_DST"
63
+ plutil -lint "$PLIST_DST" >/dev/null || die "plist failed lint"
64
+ ok "wrote $PLIST_DST (validated)"
65
+
66
+ # --- Load (or reload) -------------------------------------------------------
67
+
68
+ bold "Loading"
69
+ launchctl unload "$PLIST_DST" 2>/dev/null || true
70
+ launchctl load "$PLIST_DST"
71
+
72
+ # Buffer launchctl list into a var before grepping — otherwise `grep -q`
73
+ # can exit early, cause SIGPIPE on launchctl, and fail the pipeline under
74
+ # `set -euo pipefail` even when the job IS registered.
75
+ LAUNCHCTL_LIST="$(launchctl list || true)"
76
+ if printf "%s\n" "$LAUNCHCTL_LIST" | grep "$LABEL" >/dev/null 2>&1; then
77
+ ok "registered — running now, then daily at 04:00 local"
78
+ else
79
+ die "job did not register; check plist"
80
+ fi
81
+
82
+ # Fire once now so the user has seed data immediately instead of waiting
83
+ # until 04:00 tomorrow. kickstart is idempotent and safe to call right
84
+ # after load (the daily schedule is already registered).
85
+ launchctl kickstart "gui/$(id -u)/$LABEL" 2>/dev/null || true
86
+ ok "first run kickstarted — tail /tmp/claude-coach.log to watch progress"
87
+
88
+ cat <<EOF
89
+
90
+ Trigger a run again later (useful for testing):
91
+ launchctl kickstart gui/\$(id -u)/$LABEL
92
+
93
+ Tail the log:
94
+ tail -f /tmp/claude-coach.log
95
+
96
+ Pause the schedule:
97
+ launchctl unload $PLIST_DST
98
+
99
+ Remove entirely:
100
+ launchctl unload $PLIST_DST
101
+ rm $PLIST_DST $WRAPPER_DST
102
+ EOF