Skip to content

Commit bd66e79

Browse files
auroracapitalclaude
andcommitted
feat(ops-mac): add /ops:ops-mac macOS diagnose-and-fix command
New skill skills/ops-mac/SKILL.md + bin/ops-mac dispatcher bundle the macos-toolkit CLI suite (machealth, netwhiz, pstop, macdog, lanchr, macbroom, macctl, macfig, updater) behind one entrypoint: - Self-installs the suite on first use (plugin marketplace + Homebrew tap + trust + tools), idempotent. - Read-only aggregate `audit` composes security, launch agents, processes, network, disk, and system-health probes. - Guarded `fix` flow (firewall, stale launchd daemons, cache cleanup) with per-action confirmation per plugin Rule 5; mobile-compact per Rule 7. - Hardened against two toolkit quirks: machealth's hang-prone composite is timeout-guarded; headless TTY-empty tables bypassed via forced --json. - macOS-only (exits cleanly elsewhere); complements cross-platform /ops:speedup. Bumps plugin 2.36.5 -> 2.38.0, skill count 59 -> 60, updates marketplace description + CHANGELOG. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 4dfe0b6 commit bd66e79

5 files changed

Lines changed: 428 additions & 4 deletions

File tree

.claude-plugin/marketplace.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
"plugins": [
1010
{
1111
"name": "ops",
12-
"description": "Business operations command center for Claude Code — 59 skills, 21 agents, smart background daemon. Manage communications (WhatsApp/Email/Slack/Telegram), projects, infrastructure (AWS), revenue (Stripe+RevenueCat), e-commerce, marketing, monitoring (Datadog/New Relic/OTEL), voice, and smart home (Homey Pro). Includes /ops:ops-ar A&R (audio analysis + demo verdict cards), /gtm go-to-market planner, /ops:projects portfolio dashboard, /ops:ops-home control surface, and YOLO autonomous mode with 4 parallel C-suite agents.",
12+
"description": "Business operations command center for Claude Code — 60 skills, 21 agents, smart background daemon. Manage communications (WhatsApp/Email/Slack/Telegram), projects, infrastructure (AWS), revenue (Stripe+RevenueCat), e-commerce, marketing, monitoring (Datadog/New Relic/OTEL), voice, and smart home (Homey Pro). Includes /ops:ops-ar A&R (audio analysis + demo verdict cards), /gtm go-to-market planner, /ops:projects portfolio dashboard, /ops:ops-mac macOS diagnose-and-fix (macos-toolkit CLI suite), /ops:ops-home control surface, and YOLO autonomous mode with 4 parallel C-suite agents.",
1313
"source": "./claude-ops",
14-
"version": "2.36.5",
14+
"version": "2.38.0",
1515
"category": "productivity",
1616
"keywords": [
1717
"ops",

claude-ops/.claude-plugin/plugin.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "ops",
3-
"version": "2.36.5",
4-
"description": "Business operations command center for Claude Code — 59 skills, 21 agents, and a smart background daemon that manage communications (WhatsApp/Email/Slack/Telegram), projects, infrastructure (all AWS services), revenue (Stripe + RevenueCat), e-commerce (Shopify), marketing (Klaviyo/Meta/GA4/GSC), monitoring (Datadog/New Relic/OTEL), and voice (Bland AI/ElevenLabs/Whisper). Includes /ops:ops-ar A&R (audio analysis + demo verdict cards), /gtm go-to-market planner, /ops:projects portfolio dashboard, YOLO mode for autonomous operation with 4 parallel C-suite agents, /ops:ops-home smart home control via Homey Pro, /ops:ops-unifi UniFi network control (Site Manager + Network + Protect APIs), and /ops:ops-feature-dev overlay for the feature-dev companion plugin.",
3+
"version": "2.38.0",
4+
"description": "Business operations command center for Claude Code — 60 skills, 21 agents, and a smart background daemon that manage communications (WhatsApp/Email/Slack/Telegram), projects, infrastructure (all AWS services), revenue (Stripe + RevenueCat), e-commerce (Shopify), marketing (Klaviyo/Meta/GA4/GSC), monitoring (Datadog/New Relic/OTEL), and voice (Bland AI/ElevenLabs/Whisper). Includes /ops:ops-ar A&R (audio analysis + demo verdict cards), /gtm go-to-market planner, /ops:projects portfolio dashboard, /ops:ops-mac macOS diagnose-and-fix (bundles the macos-toolkit CLI suite — security, launchd, network, disk, system health), YOLO mode for autonomous operation with 4 parallel C-suite agents, /ops:ops-home smart home control via Homey Pro, /ops:ops-unifi UniFi network control (Site Manager + Network + Protect APIs), and /ops:ops-feature-dev overlay for the feature-dev companion plugin.",
55
"author": {
66
"name": "Lifecycle Innovations Limited",
77
"url": "https://github.com/Lifecycle-Innovations-Limited"

claude-ops/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## [2.38.0] - 2026-06-28
4+
5+
### Added
6+
ops-mac: new `/ops:ops-mac` skill + `bin/ops-mac` dispatcher — a unified macOS diagnose-and-fix command center that bundles the [macos-toolkit](https://github.com/lu-zhengda/macos-toolkit) CLI suite (machealth, netwhiz, pstop, macdog, lanchr, macbroom, macctl, macfig, updater) behind one entrypoint. Self-installs the suite on first use (plugin marketplace + Homebrew tap), runs a read-only aggregate audit (security, launch agents, processes, network, disk, system health), and applies guarded fixes (firewall, stale daemons, cache cleanup) with per-action confirmation (Rule 5). Hardened against two toolkit quirks: machealth's hang-prone composite probe is timeout-guarded, and headless TTY-empty table rendering is bypassed via forced `--json`. macOS-only (exits cleanly elsewhere; complements cross-platform `/ops:speedup`).
7+
38
## [2.36.5] - 2026-06-28
49

510
### Changed

claude-ops/bin/ops-mac

Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
#!/usr/bin/env bash
2+
# ops-mac — Unified macOS diagnose-and-fix dispatcher for the claude-ops plugin.
3+
#
4+
# Wraps the `macos-toolkit` CLI suite (machealth, netwhiz, pstop, macdog,
5+
# lanchr, macbroom, macctl, macfig, updater) behind ONE entrypoint, plus a
6+
# self-installer so the suite is provisioned on first use. The companion
7+
# skill (skills/ops-mac/SKILL.md) drives the UX, confirmations (Rule 5), and
8+
# mobile formatting (Rule 7); this script is the single source of truth for
9+
# probes, the aggregate audit, and the install path.
10+
#
11+
# Design goals:
12+
# - macOS only. Hard-guards on non-Darwin and exits cleanly.
13+
# - Idempotent install. `ensure` is safe to call repeatedly; it only does
14+
# work for missing pieces (plugin marketplace, plugin, brew tap, tools).
15+
# - Headless-safe. The toolkit's pretty TUI tables render EMPTY when stdout
16+
# is not a TTY; this script forces `--json` for machine consumers and
17+
# normalizes output so an agent always gets data.
18+
# - Hang-guarded. `machealth check`/`diagnose` can block forever on a stuck
19+
# Time Machine / iCloud probe; every machealth call is wrapped in a hard
20+
# `timeout` so the dispatcher never wedges.
21+
# - Read-only by default. Only `clean`/`fix`/`install`/`update` mutate state;
22+
# everything else is pure diagnostics.
23+
# - No secrets. Emits only health/diagnostic data, never credentials.
24+
#
25+
# Usage:
26+
# ops-mac # banner + tool inventory
27+
# ops-mac ensure # install macos-toolkit suite if missing
28+
# ops-mac audit [--json] # aggregate read-only baseline (all probes)
29+
# ops-mac health [--json] # machealth check (timeout-guarded)
30+
# ops-mac net [wifi|--json] # netwhiz network diagnostics
31+
# ops-mac disk [--json] # macbroom cache scan (safe categories)
32+
# ops-mac procs [--json] # pstop top processes
33+
# ops-mac security [--json] # macdog security/privacy audit
34+
# ops-mac launchd [--json] # lanchr doctor (launch agent health)
35+
# ops-mac power # macctl power/display/audio status
36+
# ops-mac defaults [args] # macfig hidden-preferences passthrough
37+
# ops-mac update # updater app-update check
38+
# ops-mac run <tool> [args...] # raw passthrough to any toolkit binary
39+
40+
set -uo pipefail
41+
42+
# ─── OS guard ────────────────────────────────────────────────────────────────
43+
if [[ "$(uname -s)" != "Darwin" ]]; then
44+
echo "ops-mac: macOS only (detected $(uname -s)). For Linux/WSL use /ops:speedup." >&2
45+
exit 3
46+
fi
47+
48+
# Machealth hang ceiling (seconds). Its parallel composite can block on a
49+
# stuck Time Machine / iCloud probe — never let that wedge the dispatcher.
50+
MACHEALTH_TIMEOUT="${OPS_MAC_MACHEALTH_TIMEOUT:-25}"
51+
52+
TOOLS=(machealth netwhiz pstop macdog lanchr macbroom macctl macfig updater termail)
53+
WANT_JSON=0
54+
[[ " $* " == *" --json "* ]] && WANT_JSON=1
55+
56+
# Resolve a `timeout` implementation (coreutils gtimeout on brew, or none).
57+
_timeout() {
58+
local secs="$1"; shift
59+
if command -v timeout >/dev/null 2>&1; then timeout "$secs" "$@"
60+
elif command -v gtimeout >/dev/null 2>&1; then gtimeout "$secs" "$@"
61+
else "$@"; fi
62+
}
63+
64+
_have() { command -v "$1" >/dev/null 2>&1; }
65+
66+
# Resolve the real claude binary (the interactive shell wraps it in a
67+
# _claude_dispatch function that isn't present in non-login shells).
68+
_claude_bin() {
69+
if [[ -x "$HOME/.local/bin/claude" ]]; then echo "$HOME/.local/bin/claude"
70+
elif command -v claude >/dev/null 2>&1; then command -v claude
71+
else echo ""; fi
72+
}
73+
74+
# ─── inventory ───────────────────────────────────────────────────────────────
75+
missing_tools() {
76+
local m=()
77+
for t in machealth netwhiz pstop macdog lanchr macbroom macctl macfig updater; do
78+
_have "$t" || m+=("$t")
79+
done
80+
printf '%s\n' "${m[@]}"
81+
}
82+
83+
inventory() {
84+
if [[ "$WANT_JSON" == 1 ]]; then
85+
printf '{"installed":{'
86+
local first=1
87+
for t in "${TOOLS[@]}"; do
88+
[[ $first == 1 ]] || printf ','
89+
first=0
90+
if _have "$t"; then printf '"%s":true' "$t"; else printf '"%s":false' "$t"; fi
91+
done
92+
printf '}}\n'
93+
return
94+
fi
95+
echo "OPS ► MAC — macos-toolkit dispatcher"
96+
echo "host: $(sw_vers -productName 2>/dev/null) $(sw_vers -productVersion 2>/dev/null) ($(uname -m))"
97+
echo "tools:"
98+
for t in "${TOOLS[@]}"; do
99+
if _have "$t"; then echo "$t"; else echo "$t (not installed — run: ops-mac ensure)"; fi
100+
done
101+
}
102+
103+
# ─── self-installer ──────────────────────────────────────────────────────────
104+
ensure() {
105+
local cb; cb="$(_claude_bin)"
106+
echo "▸ ensuring macos-toolkit plugin + CLIs…"
107+
108+
# 1. Plugin marketplace + plugin (best-effort; needs the claude CLI).
109+
if [[ -n "$cb" ]]; then
110+
if ! "$cb" plugin marketplace list 2>/dev/null | grep -qi "macos-toolkit"; then
111+
echo " + adding marketplace lu-zhengda/macos-toolkit"
112+
"$cb" plugin marketplace add https://github.com/lu-zhengda/macos-toolkit 2>&1 | tail -1
113+
fi
114+
if ! "$cb" plugin list 2>/dev/null | grep -qi "macos-toolkit"; then
115+
echo " + installing plugin macos-toolkit@macos-toolkit"
116+
"$cb" plugin install macos-toolkit@macos-toolkit 2>&1 | tail -1
117+
fi
118+
else
119+
echo " ! claude CLI not found — skipping plugin registration (CLIs still installable)"
120+
fi
121+
122+
# 2. Homebrew tap + tools.
123+
if ! _have brew; then
124+
echo " ! Homebrew not found. Install from https://brew.sh then re-run: ops-mac ensure" >&2
125+
return 4
126+
fi
127+
if ! brew tap 2>/dev/null | grep -qi "lu-zhengda/tap"; then
128+
echo " + tapping lu-zhengda/tap"
129+
brew tap lu-zhengda/tap 2>&1 | tail -1
130+
fi
131+
# Casks from this tap are untrusted until explicitly trusted.
132+
brew trust lu-zhengda/tap >/dev/null 2>&1 || true
133+
134+
local need; need="$(missing_tools)"
135+
if [[ -z "$need" ]]; then
136+
echo " ✓ all CLIs already installed"
137+
else
138+
echo " + installing:" $need
139+
# shellcheck disable=SC2046
140+
brew install $(for t in $need; do echo "lu-zhengda/tap/$t"; done) 2>&1 | grep -E "successfully installed|Error|Warning" | tail -20
141+
fi
142+
echo "✔ ensure complete"
143+
}
144+
145+
require_tool() {
146+
if ! _have "$1"; then
147+
echo "ops-mac: '$1' not installed. Run: ops-mac ensure" >&2
148+
exit 5
149+
fi
150+
}
151+
152+
# ─── individual probes ───────────────────────────────────────────────────────
153+
p_health() {
154+
require_tool machealth
155+
if [[ "$WANT_JSON" == 1 ]]; then
156+
_timeout "$MACHEALTH_TIMEOUT" machealth check 2>/dev/null \
157+
|| echo '{"error":"machealth timed out (likely a stuck Time Machine/iCloud probe)","probe":"machealth check","timeout_s":'"$MACHEALTH_TIMEOUT"'}'
158+
else
159+
_timeout "$MACHEALTH_TIMEOUT" machealth check --human 2>&1 \
160+
|| echo "machealth: timed out after ${MACHEALTH_TIMEOUT}s — likely a stuck Time Machine / iCloud probe. Try the other probes (security/launchd/disk/net) which are reliable."
161+
fi
162+
}
163+
164+
p_net() {
165+
require_tool netwhiz
166+
case "${1:-info}" in
167+
wifi) netwhiz wifi 2>&1 ;;
168+
--json) netwhiz info 2>&1 ;; # netwhiz info is already structured-ish
169+
*) netwhiz info 2>&1 ;;
170+
esac
171+
}
172+
173+
p_disk() {
174+
require_tool macbroom
175+
# Human table renders empty when headless → always go through --json there.
176+
if [[ "$WANT_JSON" == 1 || ! -t 1 ]]; then
177+
macbroom scan --caches --json 2>/dev/null || echo '{"error":"macbroom scan failed"}'
178+
else
179+
macbroom scan --caches 2>&1
180+
fi
181+
}
182+
183+
p_procs() {
184+
require_tool pstop
185+
if [[ "$WANT_JSON" == 1 ]]; then pstop top --n 10 --json 2>/dev/null || pstop top --n 10 2>&1
186+
else pstop top --n 10 2>&1; fi
187+
}
188+
189+
p_security() {
190+
require_tool macdog
191+
if [[ "$WANT_JSON" == 1 ]]; then macdog audit --json 2>/dev/null || macdog audit 2>&1
192+
else macdog audit 2>&1; fi
193+
}
194+
195+
p_launchd() {
196+
require_tool lanchr
197+
if [[ "$WANT_JSON" == 1 ]]; then lanchr doctor --json 2>/dev/null || lanchr doctor 2>&1
198+
else lanchr doctor 2>&1; fi
199+
}
200+
201+
p_power() { require_tool macctl; macctl power status 2>&1; }
202+
p_defaults() { require_tool macfig; shift || true; macfig "$@" 2>&1; }
203+
p_update() { require_tool updater; updater check 2>&1; }
204+
205+
# ─── aggregate audit ─────────────────────────────────────────────────────────
206+
audit() {
207+
if [[ "$WANT_JSON" == 1 ]]; then
208+
# Compose one JSON object from the reliable probes. machealth is
209+
# timeout-guarded and may degrade to an error stub.
210+
local health sec disk
211+
health="$(WANT_JSON=1 p_health)"
212+
sec="$(macdog audit --json 2>/dev/null || echo 'null')"
213+
disk="$(macbroom scan --caches --json 2>/dev/null || echo 'null')"
214+
printf '{"generated_at":"%s","host":"%s %s","arch":"%s","health":%s,"security":%s,"disk":%s}\n' \
215+
"$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
216+
"$(sw_vers -productName 2>/dev/null)" "$(sw_vers -productVersion 2>/dev/null)" \
217+
"$(uname -m)" "${health:-null}" "${sec:-null}" "${disk:-null}"
218+
return
219+
fi
220+
221+
echo "════════════════════════════════════════════"
222+
echo " OPS ► MAC AUDIT — $(sw_vers -productVersion 2>/dev/null) ($(uname -m)) — $(date -u +%H:%MZ)"
223+
echo "════════════════════════════════════════════"
224+
echo
225+
echo "── SECURITY (macdog) ──"; p_security; echo
226+
echo "── LAUNCH AGENTS (lanchr doctor) ──"; p_launchd 2>&1 | head -30; echo
227+
echo "── TOP PROCESSES (pstop) ──"; p_procs 2>&1 | head -8; echo
228+
echo "── NETWORK (netwhiz) ──"; p_net info 2>&1 | head -15; echo
229+
echo "── DISK RECLAIMABLE (macbroom caches) ──"
230+
if _have jq; then
231+
macbroom scan --caches --json 2>/dev/null \
232+
| jq -r '.categories[]? | " \(.name): \((.size/1e9*100|round)/100) GB (\(.items) items, \(.risk))"' 2>/dev/null \
233+
|| echo " (run: ops-mac disk)"
234+
else
235+
echo " (install jq for sizes, or run: ops-mac disk)"
236+
fi
237+
echo
238+
echo "── SYSTEM HEALTH (machealth, ${MACHEALTH_TIMEOUT}s cap) ──"; p_health
239+
echo
240+
echo "Tip: this is read-only. Remediate with /ops:mac fix (firewall, stale daemons, cache clean)."
241+
}
242+
243+
# ─── dispatch ────────────────────────────────────────────────────────────────
244+
cmd="${1:-}"; [[ $# -gt 0 ]] && shift || true
245+
case "$cmd" in
246+
""|inventory|status) inventory ;;
247+
ensure|install) ensure ;;
248+
audit) audit ;;
249+
health) p_health ;;
250+
net|network) p_net "${1:-info}" ;;
251+
disk) p_disk ;;
252+
procs|processes) p_procs ;;
253+
security|sec) p_security ;;
254+
launchd|launch) p_launchd ;;
255+
power) p_power ;;
256+
defaults) p_defaults "$@" ;;
257+
update|updates) p_update ;;
258+
run) t="${1:-}"; shift || true; require_tool "$t"; "$t" "$@" ;;
259+
-h|--help|help)
260+
sed -n '2,40p' "$0" | sed 's/^# \{0,1\}//'
261+
;;
262+
*)
263+
echo "ops-mac: unknown command '$cmd'. Try: ensure | audit | health | net | disk | procs | security | launchd | power | update | run <tool>" >&2
264+
exit 2
265+
;;
266+
esac

0 commit comments

Comments
 (0)