@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.
- package/LICENSE +21 -0
- package/README.md +311 -0
- package/coach/README.md +99 -0
- package/coach/bin/aggregate_facets.py +274 -0
- package/coach/bin/analyze.py +678 -0
- package/coach/bin/bank.py +247 -0
- package/coach/bin/banner_themes.py +645 -0
- package/coach/bin/coach_paths.py +33 -0
- package/coach/bin/coexistence_check.py +129 -0
- package/coach/bin/configure.py +245 -0
- package/coach/bin/cron_check.py +81 -0
- package/coach/bin/default_statusline.py +135 -0
- package/coach/bin/doctor.py +663 -0
- package/coach/bin/insights-llm.sh +264 -0
- package/coach/bin/insights.sh +163 -0
- package/coach/bin/insights_window.py +111 -0
- package/coach/bin/marker_io.py +154 -0
- package/coach/bin/merge.py +671 -0
- package/coach/bin/redact.py +86 -0
- package/coach/bin/render_env.py +148 -0
- package/coach/bin/reward_hints.py +87 -0
- package/coach/bin/run-insights.sh +20 -0
- package/coach/bin/run_with_lock.py +85 -0
- package/coach/bin/scoring.py +260 -0
- package/coach/bin/skill_inventory.py +215 -0
- package/coach/bin/stats.py +459 -0
- package/coach/bin/status.py +293 -0
- package/coach/bin/statusline_self_patch.py +205 -0
- package/coach/bin/statusline_variants.py +146 -0
- package/coach/bin/statusline_wrap.py +244 -0
- package/coach/bin/statusline_wrap_action.py +460 -0
- package/coach/bin/switch_to_plugin.py +256 -0
- package/coach/bin/themes.py +256 -0
- package/coach/bin/user_config.py +176 -0
- package/coach/bin/xp_accounting.py +98 -0
- package/coach/changelog.md +4 -0
- package/coach/default-statusline-command.sh +19 -0
- package/coach/default-statusline-wrap-command.sh +15 -0
- package/coach/profile.yaml +37 -0
- package/coach/tests/conftest.py +13 -0
- package/coach/tests/test_aggregate_facets.py +379 -0
- package/coach/tests/test_analyze_aggregate.py +153 -0
- package/coach/tests/test_analyze_redaction.py +105 -0
- package/coach/tests/test_analyze_strengths.py +165 -0
- package/coach/tests/test_bank_atomic_write.py +61 -0
- package/coach/tests/test_bank_concurrency.py +126 -0
- package/coach/tests/test_banner_themes.py +981 -0
- package/coach/tests/test_celebrate_dedup.py +409 -0
- package/coach/tests/test_coach_paths.py +50 -0
- package/coach/tests/test_coexistence_check.py +128 -0
- package/coach/tests/test_configure.py +258 -0
- package/coach/tests/test_cron_check.py +118 -0
- package/coach/tests/test_cron_nudge_hook.py +134 -0
- package/coach/tests/test_detection_parity.py +105 -0
- package/coach/tests/test_doctor.py +595 -0
- package/coach/tests/test_hook_bespoke_dispatch.py +288 -0
- package/coach/tests/test_hook_module_resolution.py +116 -0
- package/coach/tests/test_hook_relevance.py +996 -0
- package/coach/tests/test_hook_render_env.py +364 -0
- package/coach/tests/test_hook_session_id_guard.py +160 -0
- package/coach/tests/test_insights_llm.py +759 -0
- package/coach/tests/test_insights_llm_venv_path.py +109 -0
- package/coach/tests/test_insights_window.py +237 -0
- package/coach/tests/test_install.py +1150 -0
- package/coach/tests/test_install_pyyaml_fallback.py +142 -0
- package/coach/tests/test_marker_consumption.py +167 -0
- package/coach/tests/test_marker_writer_locking.py +305 -0
- package/coach/tests/test_merge.py +413 -0
- package/coach/tests/test_no_broken_mktemp.py +90 -0
- package/coach/tests/test_render_env.py +137 -0
- package/coach/tests/test_render_env_glyphs.py +119 -0
- package/coach/tests/test_reward_hints.py +59 -0
- package/coach/tests/test_scoring.py +147 -0
- package/coach/tests/test_session_start_weekly_trigger.py +92 -0
- package/coach/tests/test_skill_inventory.py +368 -0
- package/coach/tests/test_stats_hybrid.py +142 -0
- package/coach/tests/test_status_accounting.py +41 -0
- package/coach/tests/test_statusline_failsafe.py +70 -0
- package/coach/tests/test_statusline_self_patch.py +261 -0
- package/coach/tests/test_statusline_variants.py +110 -0
- package/coach/tests/test_statusline_wrap.py +196 -0
- package/coach/tests/test_statusline_wrap_action.py +408 -0
- package/coach/tests/test_switch_to_plugin.py +360 -0
- package/coach/tests/test_themes.py +104 -0
- package/coach/tests/test_user_config.py +160 -0
- package/coach/tests/test_wrap_announce_hook.py +130 -0
- package/coach/tests/test_xp_accounting.py +55 -0
- package/hooks/coach-session-start.py +536 -0
- package/hooks/coach-user-prompt.py +2288 -0
- package/install-launchd.sh +102 -0
- package/install.sh +597 -0
- package/launchd/com.local.claude-coach.plist.template +34 -0
- package/launchd/run-insights.sh +20 -0
- package/npm/coach-claw.js +259 -0
- package/package.json +52 -0
- package/requirements.txt +11 -0
- package/settings-snippet.json +31 -0
- package/skills/coach/SKILL.md +107 -0
- package/skills/coach-insights/SKILL.md +78 -0
- 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
|