ååã® autopilot èšäºã§ã¯ãlaunchd ãã Claude ãç¡äººã§èµ°ãããæ§æã玹ä»ããŸãããä»åã¯ãã®è£åŽãç¡äººãžã§ããæ¢ãŸã£ããŸãŸèª°ãæ°ã¥ããªãåé¡ãšããã®å¯ŸåŠã®è©±ã§ãã
ç¡äººèªååã§ãã¡ã°ãæãã®ã¯ã掟æãªãã°ãããµã€ã¬ã³ã倱æã§ããlaunchd ã®ãžã§ãã exit 78 ã§ã¯ã©ãã·ã¥ããŠããŠããhooks ã®ã¹ã¯ãªãããå®è¡æš©éã倱ã£ãŠããŠããç»é¢äžã¯äœãèµ·ããŠããªãããã«èŠããŸãã
å®éãç§ã®ç°å¢ã§ã¯ agentmemory ã exit 78 ã®ã¯ã©ãã·ã¥ã«ãŒãã«å ¥ã£ããŸãŸã6æ¥é誰ã«ãæ°ã¥ãããŸããã§ããã6æ¥ã§ãïŒ ãã®éãã£ãšãèšæ¶ãµãŒãã¯èœã¡ããŸãŸã§ããããã®ãšã automation-health.sh ã«æžãæ®ããã³ã¡ã³ããããã®èšäºã®åºçºç¹ã§ãã
é»ã£ãŠæ»ã¬ãã®ãå€ããã
èªåŸã«ãŒããçµããšãèŠåŒµã察象ãã©ãã©ãå¢ããŸãããšã³ãžãã¢ã§ããªãç§ã®æ§æã ãã§ããããã ããããŸããã
- launchd ãžã§ãïŒskill-harvest / skill-curate / agentmemory ãªã©ïŒ
- Stop hook / PreToolUse hook ã®å®äœã¹ã¯ãªãã
- äŒè©±ãã°ãé·æèšæ¶ã«å€ãã Stop hook
- Obsidian Vault ã®èªåæŽæ°
- 鱿¬¡ã»ææ¬¡ãããïŒenv-audit / plugin-purge / dotfiles-snapshot ãªã©ïŒ
ãããæ¯æ¥æã§ç¢ºèªããã®ã¯ç¡çã§ãããlaunchctl list ãåå¥ã«å©ããŠããå šäœãã©ããªã£ãŠãããã¯èŠããŸããã
ããã§ãå šéšãŸãšããŠç¹æ€ã㊠GREEN / WARN / FAIL ã®3段éã§æããŠããã1ã³ãã³ããäœããŸããã
ð¬ é客ã»å°ç·èšèšãšãAIå°å ¥ã»èªååã®ãçžè«ã¯ãã¡ã
å€å®ã¯ ok / wn / ng ã®3ã€ã ã
~/.claude/scripts/automation-health.sh ã®äžå¿ã¯ãæåæããããããçãã§ãã
fail=0; warn=0
ok() { printf " ${GRN}â${RST} %s\n" "$1"; }
wn() { printf " ${YEL}â ${RST} %s\n" "$1"; warn=$((warn+1)); }
ng() { printf " ${RED}â${RST} %s\n" "$1"; fail=$((fail+1)); }åãã§ãã¯ã ok / wn / ng ã®ã©ããã§è©äŸ¡ããŠãæåŸã«ãŸãšããŠå€å®ããŸãã
if [ "$fail" -gt 0 ]; then
printf " ${RED}â FAIL${RST} red=%d warn=%d\n\n" "$fail" "$warn"; exit 1
elif [ "$warn" -gt 0 ]; then
printf " ${YEL}â WARN${RST} warn=%d (èŽåœçåé¡ãªã)\n\n" "$warn"; exit 0
else
printf " ${GRN}â ALL GREEN${RST} å
šèªååãæ£åžžçšŒå\n\n"; exit 0
fiRED ã1ã€ã§ãããã° exit 1ããã以å€ã¯ exit 0 ã§ããexit code ãåããŠãããšãdaily-brief.sh ãªã©ãã || ã§åŸç¶åŠçã«ã€ãªããããŸãã
9ã€ã®ç¯ã§äœãèŠãŠããã
ã¹ã¯ãªããã¯9ç¯ã«åãããŠããŸããäž»ãªå€å®ãæãåºããŸãã
1. launchd ãžã§ãã®çæ»
for job in com.shun.skill-harvest com.shun.skill-curate; do
line=$(launchctl list 2>/dev/null | grep -E "\b${job}\b")
if [ -z "$line" ]; then
ng "$job: æªããŒã (launchctl load ãçŽããå¿
èŠ)"
else
exitc=$(echo "$line" | awk '{print $2}')
if [ "$exitc" = "0" ] || [ "$exitc" = "-" ]; then
ok "$job: ããŒãæž / last exit=$exitc"
else
ng "$job: last exit=$exitc (åå倱æ)"
fi
fi
donelaunchctl list ã®2åç®ãååã®çµäºã³ãŒãã§ãã- ã¯ãŸã èµ·åããŠããªãã ãã0 ã¯æåããã以å€ã¯å€±æãšããŠæ±ããŸãã
2. hooks ã¹ã¯ãªããã®å®åšãšå®è¡æš©é
for h in "${hooks[@]}"; do
f="$CLAUDE/hooks/$h"
if [ ! -f "$f" ]; then ng "$h: äžåš"
elif [ ! -x "$f" ]; then wn "$h: å®è¡æš©éãªã (chmod +x æšå¥š)"
else ok "$h"
fi
donesettings.json ã« hook ãæžããŠããå®äœã chmod +x ãããŠããªããã°é»ã£ãŠé£ã°ãããŸãããšã©ãŒãåºãŸãããããã WARN ã§æŸããŸãã
3. skill-harvest ã®ãã°é®®åºŠ
ãã°ãã¡ã€ã«ãããããšãšãæè¿èµ°ã£ãããšã¯å¥ã®è©±ã§ããã ãã age_h ãã«ãã§ mtime ããã®çµéæéãåºãã48æéããå€ããã° WARN ã«ããŠããŸãã
4ã6. èšæ¶ãŸãã
äŒè©±ãã°ã®ä»¶æ°ãš INDEX.md ã®é®®åºŠïŒ24æé以å ãïŒãObsidian ã® hot.md ã«èªåæŽæ°ããŒã«ãŒãããããindex.md ã®ç·ããŒãžæ°ãå®ãã¡ã€ã«æ°ãšäžèŽããããèŠãŸãã
remember èšæ¶å±€ã§ã¯ãnow.md ã«åãèŠçŽã3å以äžäžŠãã ã WARN ã«ããŸããconsolidate ãé ãããšãåãèŠçŽãäœåºŠã远èšãããããã§ãã
dup=$(grep -vE '^\s*$|^##|^#' "$nowf" | sort | uniq -c | sort -rn | head -1 | awk '{print $1}')
if [ "${dup:-0}" -ge 3 ]; then
wn "now.md ã«åäžèŠçŽã ${dup} å (consolidate é
å»¶ã®å
å)"
fi7. ãã£ã¹ã¯äœ¿çšéãšæ®éªž
~/.claude ã®å®å¹å®¹éã 2GB æªæºãªã OKã5GB æªæºãªã WARNããã以äžã¯ FAIL ã§ããæ»ãããã£ãã·ã¥ïŒ.disabled-cacheïŒã¯å®¹éããåŒããŠå€å®ããŸãã7æ¥ä»¥äžåã® security_warnings_state_*.json ã5å以äžããŸã£ãããéé¿ãä¿ã WARN ãåºããŸãã
8. 鱿¬¡ã»ææ¬¡ãããã®ãã° mtime
declare -a CRON_JOBS=(
"weekly env-audit:$CLAUDE/logs/env-audit-latest.md:192"
"monthly plugin-purge:$CLAUDE/logs/plugin-purge.log:744"
)
for entry in "${CRON_JOBS[@]}"; do
IFS=":" read -r name path budget <<< "$entry"
a=$(age_h "$path")
if [ "$a" -le "$budget" ]; then ok "$name: ${a}hå"
else wn "$name: ${a}hå (budget ${budget}h è¶
é)"; fi
done鱿¬¡ã¯ 192æéïŒ8æ¥ïŒãææ¬¡ã¯ 744æéïŒ31æ¥ïŒã蚱容æéã«ããŠãè¶ ããã WARN ã§ããå®éã®ãªã¹ãã«ã¯ dotfiles-snapshot ã plugin-usage ãªã©7æ¬ãå ¥ããŠããŸãã
6æ¥éèŠéãããåçç¶æ ã
agentmemory ã®ãã§ãã¯ã ãã¯2段æ§ãã«ããŸããã
am_line=$(launchctl list 2>/dev/null | awk '$3=="com.shun.agentmemory"{print $1" "$2}')
am_pid=${am_line%% *}; am_exit=${am_line##* }
if [ -z "$am_line" ]; then
wn "com.shun.agentmemory ã launchd ã«æªããŒã"
elif [ "$am_pid" = "-" ] && [ "$am_exit" != "0" ]; then
ng "com.shun.agentmemory åæ¢äž (last exit=$am_exit) â ã¯ã©ãã·ã¥ã«ãŒãã®å¯èœæ§"
else
am_code=$(curl -s -o /dev/null -w '%{http_code}' -m 3 \
http://localhost:3111/agentmemory/health 2>/dev/null || echo 000)
if [ "$am_code" = "200" ]; then ok "皌åäž (pid=$am_pid / health 200)"
elif [ "$am_code" = "000" ]; then ng "ããã»ã¹ã¯å±
ãã port 3111 ç¡å¿ç"
else ng "port 3111 ã¯éãã /agentmemory/health=$am_code â worker äžåšã®åçç¶æ
"; fi
fiçç±ã¯ã¹ã¯ãªããã®ã³ã¡ã³ãã«æ®ããŠãããŸãã
launchd ã® exit 78 ã¯ã©ãã·ã¥ã«ãŒãã6æ¥é誰ã«ãæ°ã¥ããããããã«ãããŒãã¯éãã worker äžåšã§å šAPI 404ãã®åçç¶æ ã¯æ»æŽ»ç£èŠã§ã¯èŠããªãã
åä»ãªã®ã¯åŸåã§ããããã»ã¹ã¯å± ããããŒããéããŠããã®ã§ãlaunchd ããèŠãã°ãèµ·åäžãã§ããã§ã API ãå©ããšå šéš 404 ãè¿ã£ãŠãããPID ãèŠãã ãã§ã¯ããã®ç¶æ ã¯çµ¶å¯Ÿã«èŠã€ãããŸããã
ãªã®ã§ curl ã§ /health ãå©ããHTTP 200 ãè¿ãããŸã§ç¢ºãããŠããŸããMCP ãµãŒãã API ãµãŒãã launchd ã§åãããŠããæ¹ã¯ã/health ãå©ã1è¡ãè¶³ããŠãããšãåãèŠéããé²ããŸãã
cron ãš launchd ã®äºéå®è¡
9çªç®ã®ç¯ã¯ãç§ãå®éã«ãããããä»¶ããçãŸããŸããã2026-06-01 ã« cron ãã launchd ãžç§»è¡ãããšããå€ã crontab ãæ¶ãå¿ããŠãããã§ãããã®çµæãåãã¹ã¯ãªãããæ¯ãµã€ã¯ã«2åãã€èµ°ã£ãŠããŸããç¬
cron_sh=$(crontab -l 2>/dev/null | grep -vE '^[[:space:]]*#' | \
grep -oE '/[^ ]+\.sh' | xargs -n1 basename | sort -u)
launchd_sh=$(grep -hoE '/[^<> ]+\.sh' \
~/Library/LaunchAgents/com.shun.*.plist | xargs -n1 basename | sort -u)
dup=$(comm -12 <(printf '%s\n' "$cron_sh") <(printf '%s\n' "$launchd_sh") | \
grep -vE '^[[:space:]]*$')
if [ -n "$dup" ]; then
ng "cron ãš launchd ã®äž¡æ¹ã«ç»é²ããäºéå®è¡ãããã¹ã¯ãªãã: $(printf '%s' "$dup" | tr '\n' ' ')"
fiäž¡æ¹ããã¹ã¯ãªããåãæãåºã㊠comm -12 ã§éãªããåãã ãã§ããéãªãã1ã€ã§ãããã° FAIL ã«ããŠããŸãã
æ¯æã® daily-brief ã«1è¡ã ãèŒãã
daily-brief.sh ã¯æ¯æ 8:00 ã« launchd ããèµ·åããŸãããã®åé ã«ããã«ã¹ãã§ãã¯ã®çµæã1è¡ã ãå ¥ããŠããŸãã
echo "## ð¥ ç°å¢ãã«ã¹"
run_to 60 ~/.claude/scripts/automation-health.sh 2>&1 | tail -3 | head -1tail -3 | head -1 ã§ãæåŸã®ãµããªè¡ïŒALL GREEN / WARN / FAILïŒã ããåãåºããŸãã
ããã« brief åŽã§ã¯ãã©ã€ãçéã®ç¢ºèªã§ RED ãåºããšãã ã ## ðš èŠå¯Ÿå¿ ã®ç¯ãçŸããŸããåé¡ããªãæ¥ã¯ããã®ç¯ãã®ãã®ããããŸãããbrief 㯠~/Desktop/Daily Brief/today-brief-YYYYMMDD.md ã«æžãåºãããã®ã§ãæãã¹ã¯ããããéããš RED ã ããç®ã«å ¥ããŸãã
exit 1 ã䜿ãã°ãåãèãæ¹ããã¡ã€ã«1ã€ã§åçŸã§ããŸãã
bash ~/.claude/scripts/automation-health.sh || touch ~/Desktop/AUTOMATION_FAILED.md
bash ~/.claude/scripts/automation-health.sh && rm -f ~/Desktop/AUTOMATION_FAILED.md倱æããŠããéã ããã¡ã€ã«ããã£ãŠãçŽã£ããæ¶ãããããã·ã¥ããŒããéããªããŠãããã¹ã¯ããããç¶æ ãæããŠãããŸãã
å®éã«èžãã èœãšã穎
- launchctl list ã®çµäºã³ãŒã 0 ãš - ã奿±ããããšãæ£åžžãªã®ã« WARN ãåºç¶ããŸããã©ã¡ããæ£åžžãšã㊠OR ã§ãŸãšããŸãã
- hooks ã®å®äœã« chmod +x ããªããŠããsettings.json ã¯äœãèšããŸãããWARN ã§æŸããŸã§ãç§ã¯ãŸã£ããæ°ã¥ããŠããŸããã§ãã
- 2026-06-11 ã« env-audit ã®åºåå ã scripts/ ãã logs/ ã«ç§»ãããšãããã«ã¹ãã§ãã¯åŽã®ãã¹ãçŽãå¿ èŠããããŸãã
- index.md ã®ããŒãžæ°ãã§ãã¯ã§ .backup ãªã©ã®é ããã£ã¬ã¯ããªãé€å€ããªããšããã£ãš WARN ãæ¶ããŸãã
ãŸãšã
- èªååã®æ»æŽ»ã¯ã1ã³ãã³ãã§ ALL GREEN / WARN / FAIL ã®3ã€ã«ãŸãšãã
- exit 1 ãåå³ã«ããŠãdaily-brief ãžã®1è¡ã FAILED ãã¡ã€ã«ã«ã€ãªãã
- åé¡ããããšãã ãçŸããç¯ããã¡ã€ã«ãäœãã°ãèŠã«è¡ããªããŠãç°åžžã«æ°ã¥ãã
- launchd ã® PID ã ãã§ã¯åçç¶æ ãèŠéãã®ã§ãHTTP ã® /health ãäžç·ã«å©ã
- ãããã®æ»æŽ»ã¯ããã°ã® mtime ã蚱容æéãšæ¯ã¹ãã ãã§æ©æ¢°çã«å€å®ã§ãã
6æ¥éã®èŠéãããäœã£ãä»çµã¿ã§ãããä»ã¯æ¯æã® brief ã«1è¡åºãã ãã«ãªããŸãããæ¬¡åã¯ããã®ãã«ã¹ãã§ãã¯ãš autopilot ã®æ¹åãã°ããŸãšããŠãé±ããšã«äœãå€ãã£ãããèªåã§ã¬ããŒãã«ããä»çµã¿ãæžãäºå®ã§ãã
ð ãã®èšäºã®å 容ããå®è£ ãŸã§å šéšãŸãšããææèšäºããããŸã æé ã»ã³ãŒãã»ãã³ãã¬ããã®ãŸãŸæž¡ããŠããŸã AIã§ãå¯ãŠãŠãåãä»çµã¿ãããŒããã30æ¥ã§çµãå šæé
ã³ã¡ã³ã
ãã°ã€ã³ ã äŒå¡ç»é² ãããšã³ã¡ã³ãã§ããŸã