Claude Codeã¯äœ¿ãã°äœ¿ãã»ã©è³¢ããªãããšããã®ã¯å忬åœã§ãåååã§ãã
å幎åã倧åŠçã®ããã«æ10äžã ã£ãåå ¥ãã坿¥ãæãæã¡ããªãã60äžãŸã§å¢ããäŒç€Ÿéœåã§è§£éãããŠããã®å幎ã§Claude CodeèªåŸç°å¢ãæ§ç¯ããä»ã¯æå120äžã§åã£ãŠããŸãããã®éçšã§çæããã®ããã¹ãã«ã®è æãã§ããæåã¯æã«ãªããã éå ·ãã3ã¶æåŸã«ã¯èª°ã䜿ããªãæé®ã«ãªã£ãŠããããããŠãã®æé®ã¯æ¯åã®äŒè©±ã§èªã¿èŸŒãŸãç¶ããã³ã³ããã¹ããéãã«å§è¿«ããŸããä»åã¯ããã®åé¡ã鱿¬¡ã®èªåãã¥ã¬ãŒã·ã§ã³ã§è§£æ±ºãã話ãããŸãã
ãªããã®ä»çµã¿ãå¹ãã®ã
ã䜿ãã»ã©è³¢ããªããã®è£åŽã«ããèœãšã穎
Claude Codeã«ã¯ auto-skill ãšåŒã¶ä»çµã¿ããããŸããéèªæãªã¿ã¹ã¯ã5å以äžããªãããšããåé¿çãçºèŠãããšããã¢ãããŒããä¿®æ£ããããšããAIãèªåŸçã« ~/.claude/skills/auto/<kebab-name>/SKILL.md ãžæé ãæžãåºãèšèšã§ãã
ãã®ã¡ã¢ãç©ã¿éãªãã»ã©ã次ã®äŒè©±ã§ãã®çµéšãåç §ã§ãããç°å¢ã®ãèšæ¶ããè²ã£ãŠããæèŠã¯ããããã«æ°æã¡ãããã®ã§ãã
ãããåé¡ãããã
Claude Codeã®ã³ã³ããã¹ãæ³šå ¥ã¯ãã¹ãã«ãã¡ã€ã«ãå¢ããã°å¢ããã»ã©èªã¿èŸŒã¿éãå¢ããŸããã¹ãã«ã30åã50åãšæºã蟌ãã§ãããšãäŒè©±ã®åé ã ãã§æ°åããŒã¯ã³ãã䜿ãããŠããªãã¹ãã«ã®èª¬æãã«è²»ããããŸããOpusããã«å質ã®Sonnetã§ã¯ãã³ã³ããã¹ãæ±æã¯åºåå質ã®å£åã«çŽçµãããæ¯æèª²éãããããŒã¯ã³ä»£ã¯å¢ããå¿çã®éãã¯èœã¡ãããŸãã§ãã¹ã¯ã«äœ¿ããªãæžé¡ãç©ã¿äžãç¶ãããããªãã®ã§ãã
Lilyèªèº«ã®ç°å¢ã§å®éã«ç¢ºèªããæ§é ãèšããšã~/.claude/skills/auto/ é
äžã«åã¹ãã«ããã£ã¬ã¯ããªãšããŠäžŠã³ããã®äžã® SKILL.md ã author: auto ãšããããã³ããã¿ãŒãæã€ããã® author: auto ãã£ãŒã«ãããªãæåã¹ãã«ã«ã¯ãä»åã®æŽçæ©æ§ã¯äžåè§ŠããŸããã誀çãé²ãå®å
šã¬ãŒãããèšèšã®æåã«çœ®ãããŠããç¹ãéèŠã§ãã
ãäœæ¥ãã§ã¯ãªããç°å¢ãã«æè³ããæå³
æå120äžã®ä»äºã®å€§åã¯ãClaudeã«ä»äºãæµãèšèšãäœãããšã§ããåå¥ã¿ã¹ã¯ãããªããããæ¬¡ã®100ã¿ã¹ã¯ãèªååãããä»çµã¿ãäœãã»ãã䟡å€ãé«ããããã¯ã©ã®å人éçºè ã«ãåœãŠã¯ãŸãååã ãšæããŸãã
ããããã®ãç°å¢ãèªäœãè æãããšãæŽåã³ã¹ããéã«éããªããauto-skillã®ãã¥ã¬ãŒã·ã§ã³èªååã¯ããŸãã«ãã®ãç°å¢ã®ç°å¢ãæŽåãããã¡ã¿ã¬ã€ã€ãŒã§ããèªè ã®æ¹ããClaude Codeã䜿ã蟌ãã»ã©ãåã«äœã£ãã¯ãã®ã¹ãã«ãã©ãã ã£ããããã®ã¹ãã«ããŸã 䜿ã£ãŠãïŒããšããæèŠãåºãŠããã¯ãã§ãããã®æèŠãæŸçœ®ããã«èªååããããšãã話ã§ãã
ã³ã³ããã¹ãè¥å€§åã®å ·äœçãªçµè·¯
ã¹ãã«ãå¢ãããšäœãèµ·ããããå ·äœçã«è¿œããŸãã
~/.claude/CLAUDE.md ã«ã¯ ã¹ãã«èªå·±çæïŒauto-skillsïŒ ãšããã»ã¯ã·ã§ã³ãããããåå©çšäŸ¡å€ã®ããæé ã¯é ŒãŸããªããŠãèªäœããã ãšæžããŠããŸãããã®æç€ºãçããŠããéããã¹ãã«ã¯èªç¶å¢æ®ããŸãã
åé¡ã¯ã䜿ãããªããªã£ããã¹ãã«ã®æ€ç¥ãã人éã®ç®èŠã«é Œã£ãŠããããšãæäœæ¥ã§ã¹ãã«ãã£ã¬ã¯ããªãçºããŠããã©ããçŸåœ¹ã§ã©ããéºç©ãã¯äžç®ã§ããããŸãããããšãã£ãŠå šéšæ¶ãã®ã¯æãããã®ãžã¬ã³ããè§£æ¶ããã®ãä»åã®é±æ¬¡ãã¥ã¬ãŒã¿ãŒã§ãã
èšèšã®æ žå¿ã¯3ç¹ã§ãã
-
äŒè©±ãã°ãžã®ã¹ãã«åèšåãã䜿çšã®ä»£çææšãã«ãã â çŽæ¥ã®APIåŒã³åºããã°ã§ã¯ãªãã
~/Documents/my-knowledge-base/raw/conversations/å ã®äŒè©±ãã°ãã¡ã€ã«ããã¹ãã«åãgrepããææ°ã®ãã¡ã€ã«mtimeããæçµäœ¿çšæ¥ããšã¿ãªãã -
30æ¥æªäœ¿çšã§staleã»90æ¥æªäœ¿çšã§
.archive/éé¿ â ã©ã¡ããå®åé€ã§ã¯ãªããstaleã¯ããã³ããã¿ãŒã«status: staleã远èšããã ããarchiveã¯mvã§å¥ãã£ã¬ã¯ããªãžã - å®è¡åã«å¿ ãã¹ãããã·ã§ãããåã â æäœãééããŠãã¯ã³ã³ãã³ãã§å ã«æ»ããã
å šäœã®æµã
ã¢ãŒããã¯ãã£æŠèг
[æ¯é±æ¥æ 4:15 AM]
â
com.shun.skill-curate (launchd)
â
skill-curate.sh
â
ââ â ã¹ãããã·ã§ããååŸ
â ~/.claude/skills/auto/.snapshots/
â auto-YYYYMMDD-HHMMSS.tar.gz
â
ââ â¡ auto/é
äžãå
šã¹ãã«ã¹ãã£ã³
â author: auto ã§ãªããã®ã¯ã¹ããã
â
ââ ⢠æçµäœ¿çšæ¥ã®ç®åº
â äŒè©±ãã° grep â mtime
â â created: ããã³ããã¿ãŒ
â â SKILL.md ã®ãã¡ã€ã«mtime
â
ââ â£ æ¥æ°å€å®
â > 90æ¥ â .archive/ ãž mvïŒéç Žå£ïŒ
â > 30æ¥ â status: stale ã远èš
â ããä»¥å€ â active ã«ãŠã³ã++
â
ââ †LLMçµ±åææ¡ïŒãªãã·ã§ã³ïŒ
active ⥠2 ã®ãšã Claude ãåŒã³åºã
éè€ã»äœå質åè£ã .curator-proposals.md ã«æžãåºã
å®ã¹ãã«ã¯å€æŽããªãïŒææ¡ã®ã¿ïŒ
launchdã®plistã¯ä»¥äžã®ããã«èšå®ãããŠããŸãã
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>4</integer>
<key>Minute</key>
<integer>15</integer>
<key>Weekday</key>
<integer>0</integer>
</dict>
Weekday: 0 ãæ¥æãHour: 4ã»Minute: 15 ã§æ¯é±æ¥æ 4:15 AM ã«èµ·åããŸããLowPriorityIO: trueã»Nice: 10 ã§æäœåªå
床ã®ããã¯ã°ã©ãŠã³ãå®è¡ã§ããç ã£ãŠããéã«çä»ãã人éã®ã³ã¹ãã¯ãŒãã§ãã
â ã¹ãããã·ã§ããïŒå®å šãªããŒãµãã«ã®åºç€
ã¹ã¯ãªããã®åé ã§ãŸãã¹ãããã·ã§ãããåããŸãã
AUTO="$HOME/.claude/skills/auto"
SNAP="$AUTO/.snapshots"
tar czf "$SNAP/auto-$(date +%Y%m%d-%H%M%S).tar.gz" \
-C "$HOME/.claude/skills" \
--exclude='auto/.snapshots' \
--exclude='auto/.archive' \
auto 2>/dev/null \
&& echo "[$(ts)] snapshot taken" >> "$LOG"
.snapshots/ ãš .archive/ èªèº«ã¯é€å€ããŠå§çž®ããŠããŸããããããããªããšãã¢ãŒã«ã€ãã®äžã«ã¢ãŒã«ã€ããå
¥ã蟌ãååž°åé¡ãèµ·ãããdate +%Y%m%d-%H%M%S ã§ã¿ã€ã ã¹ã¿ã³ãä»ãã®ååã«ããŠããã®ã§ãé±ã远ãããšã«ã¹ãããã·ã§ãããç©ã¿äžãããŸãã
ãªã¹ãã¢æ¹æ³ã¯åçŽã§ãtar xzf ~/.claude/skills/auto/.snapshots/auto-20260803-041500.tar.gz -C ~/.claude/skills/ ãå®è¡ããã ãã§ãã鱿¬¡ã§ã¹ãããã·ã§ãããå¢ããŠããç¹ã¯å¥é find ã§å€ããã®ãæ¶ãéçšãå¿
èŠã§ãããããã¯æ¬¡ã®èª²é¡ã§ãã
â¡ å®å šã¬ãŒãïŒauthor: auto 以å€ã¯çµ¶å¯Ÿã«è§Šããªã
if ! grep -q '^author:[[:space:]]*auto' "$md"; then
echo "[$(ts)] skip (not author:auto): $skill" >> "$LOG"
continue
fi
ãããããããšã§ãæåã§äžå¯§ã«è²ãŠãã¹ãã«ã誀ã£ãŠéé¿ãããããšã¯ãããŸãããauthor: auto ãšããããã³ãããŒã«ãŒããæ©æ¢°ãçæããæŽç察象ãã瀺ãå¯äžã®æã§ããéã«èšãã°ãæ®ãããã¹ãã«ã¯ author: ãã£ãŒã«ãã auto 以å€ã«æžãæããã ãã§ä¿è·ã§ããŸããã·ã³ãã«ã§åŒ·ãã
⢠æçµäœ¿çšæ¥ã®ç®åºïŒä»£çææšã®èšèšãšéç
ãããèšèšã®äžã§æã工倫ãèŠãéšåã§ããClaude Codeã«ã¯ãã©ã®ã¹ãã«ãåŒã°ããããšããAPIã¬ãã«ã®ãã°ãå€éšããåããŸããããã®ãããäŒè©±ãã°ã®ããã¹ãã«ã¹ãã«åãåºçŸãããã©ãã ãä»£çææšãšããŠäœ¿ã£ãŠããŸãã
lastlog=$(grep -rl -- "$skill" "$LOGS" 2>/dev/null \
| while read f; do stat -f '%m' "$f" 2>/dev/null; done \
| sort -rn | head -1)
LOGS="$HOME/Documents/my-knowledge-base/raw/conversations/" ãå
šææ€çŽ¢ããã¹ãã«åãå«ããã¡ã€ã«ã®ãã¡æãæ°ãããã®ã® mtime ãUnixã¿ã€ã ã¹ã¿ã³ãã§ååŸããŸãã
ååŸã§ããªãã£ãå Žåããã©ãŒã«ããã¯ã2段éãããŸãã
# Pythonã€ã³ã©ã€ã³ã¹ã¯ãªããããïŒskill-curate.sh 42-56è¡ç®ïŒ
ref = None
if lastlog.strip():
try: ref = float(lastlog)
except: ref = None
if ref is None and created.strip():
try: ref = time.mktime(datetime.datetime.strptime(
created.strip(), "%Y-%m-%d").timetuple())
except: ref = None
if ref is None:
ref = os.path.getmtime(md)
print(int((time.time() - ref) // 86400))
â äŒè©±ãã°ã®mtime â â¡ SKILL.md ã® created: ããã³ããã¿ãŒ â ⢠SKILL.md ãã¡ã€ã«èªäœã®mtimeããšããé ã§ããcreated: ãæžãããŠããªãå€ãã¹ãã«ã§ãããã¡ã€ã«mtimeãšããæåŸã®ç Šãããã
ãã ãããã®ä»£çææšã«ã¯æ§é çãªéçããããŸãã
ãäŒè©±ãã°ã«ã¹ãã«åãç»å Žããããšãã¹ãã«ãå®éã«åŒã³åºãããŠæ©èœãããã¯ãå³å¯ã«ã¯å¥ã®äºè±¡ã§ããã¹ãã«ã®ååãäŒè©±ã®äžã§èšåãããïŒäŸ: ããã®ã¹ãã«ã¯äžèŠããããšè°è«ããïŒå Žåã§ãã䜿çšãšã«ãŠã³ããããŸããéã«ãã¹ãã«åãã³ãã³ã圢åŒïŒ/curate-skills ãªã©ïŒãšããŠåŒã°ããŠããŠããã°ã®æ€çŽ¢ãã¿ãŒã³ãäžèŽããªãå Žåã¯æŸããŸããã
ãã®å¶çŽãç¥ã£ãäžã§ãããã§ãäŒè©±ãã°ãæè¯ã®è¿äŒŒææšããšãã倿ãåã£ãŠããŸããå®ç§ãªäœ¿çšãã°ãããéçšå¯èœãªè¿äŒŒææšãéžã¶ããããå®çšçãªèªååã®å²åŠã§ãã
⣠å€å®ãšåŠçïŒstaleãšarchiveã®äºæ®µé
STALE_DAYS=30
ARCHIVE_DAYS=90
if (( days > ARCHIVE_DAYS )); then
mv "$d" "$ARCH/" && echo "[$(ts)] ARCHIVED (${days}d unused): $skill" >> "$LOG"
elif (( days > STALE_DAYS )); then
# SKILL.md ã® status ãã£ãŒã«ãã stale ã«æžãæãã
python3 - "$md" <<'PY'
import sys, re
p = sys.argv[1]; s = open(p).read()
if re.search(r'^status:', s, re.M):
s = re.sub(r'^status:.*$', 'status: stale', s, count=1, flags=re.M)
else:
s = re.sub(r'^(author:[ \t]*auto.*)$', r'\1\nstatus: stale',
s, count=1, flags=re.M)
open(p, 'w').write(s)
PY
echo "[$(ts)] stale (${days}d unused): $skill" >> "$LOG"
((active++))
else
((active++))
fi
30æ¥æªäœ¿çšã®ã¹ãã«ã¯ status: stale ãããã³ããã¿ãŒã«æžã蟌ã¿ãŸããå®éã®åé€ã§ãéé¿ã§ããªãããã©ã°ãç«ãŠãã ãã§ãããã®ãã©ã°ãããããšã§ãã¹ãã«ã€ã³ããã¯ã¹ã status: stale ã衚瀺ããããæ¬¡ã®æŽçãã§ãŒãºã§åªå
ããŠæ€èšãããã§ããŸãã
90æ¥æªäœ¿çšã®ã¹ãã«ã¯ .archive/ ãž mv ããŸããrm ã§ã¯ãªã mv ãªã®ã§ããã¡ã€ã«ã·ã¹ãã äžã§ã¯æ¶ããŠããŸãããls ~/.claude/skills/auto/.archive/ ã§ç¢ºèªã§ããå¿
èŠãªã mv ã§æ»ããŸãããã®éç Žå£æ§ãéèŠã§ããæ¶ããåŸã«å¿
èŠã ãšããã£ãããšããã·ããªãªãå®å
šã«ã«ããŒããŸãã
staleå€å®ãããã¹ãã«ã active++ ã®ã«ãŠã³ãã«å«ãŸããç¹ã«æ³šç®ããŠãã ãããstaleã¯ãããŸã§ãèŠæ³šæãã©ã°ãã§ãããã¹ãã«èªäœã¯ãŸã auto/ é
äžã«ååšããŠããŸããæ¬¡ã®é±æ¬¡å®è¡ã§30æ¥ãããã«çµéããã°ãstaleâarchiveãžèªç¶ã«ææ ŒããŸãã
†LLMçµ±åææ¡ïŒClaudeãã¹ãã«ãèªãã§ææ¡ãæžã
if [[ "$RUN_LLM" != "nollm" ]] && (( active >= 2 )) && [[ -x "$CLAUDE" ]]; then
activeã¹ãã«ã2件以äžãããã〠nollm åŒæ°ãæž¡ãããŠããªãå Žåã«ãClaudeãåŒã³åºããŠéè€ã»äœå質ã¹ãã«ã®çµ±åææ¡ãçæããŸãã
STG=$(mktemp -d -t skill-curate-stg)
( cd "$STG" && perl -e 'alarm 600; exec @ARGV' "$CLAUDE" \
--strict-mcp-config \
--mcp-config '{"mcpServers":{}}' \
-p "${AUTO} é
äžã®èªåçæã¹ãã«ã®ãã¡ãååææ¡ãã¡ã€ã« ${PROP} ããåŸã«æŽæ°ããã
SKILL.md ã®ã¿ã Read ããéè€ã»äœå質ã»çµ±ååè£ãæŽãåºããŠãã ããã..." \
--model sonnet \
--permission-mode acceptEdits \
--allowedTools "Write Edit Read" \
--add-dir "$AUTO" \
--max-budget-usd 5.00 >> "$LOG" 2>&1 < /dev/null )
[[ -f "$STG/curator-proposals.md" ]] && cp "$STG/curator-proposals.md" "$PROP"
èšèšäžã®å·¥å€«ãããã€ããããŸãã
--mcp-config '{"mcpServers":{}}' ã§MCPãç¡å¹åããŠããŸãã 鱿¬¡ãããã®äžã§ãããã¯ãŒã¯äŸåã®MCPãµãŒããŒãçªç¶èµ·åããã®ã¯äžå®å®èŠå ã§ããã¹ãã«ã®èªã¿èŸŒã¿ãšææ¡æžãåºãã ãã«çµãã
--max-budget-usd 5.00 ã§ã³ã¹ãã«äžéãèšããŠããŸãã Claude APIã®èª²éãç¡å¶éã«èµ°ããªãããã1åã®ææ¡çæã¯5ãã«ãŸã§ãææ¡ãã¡ã€ã«ãæ¶ããŠãå°ããªãã¬ãã«ã®ã¿ã¹ã¯ã«ããã以äžã®èª²éãããå¿
èŠã¯ãããŸããã
perl -e 'alarm 600; exec @ARGV' ã§ã¿ã€ã ã¢ãŠãã600ç§ã«èšå®ããŠããŸãã åçŽãª timeout ã³ãã³ãã¯ã·ã°ãã«ã®äŒææ¹æ³ã«ãã£ãŠãClaudeããã»ã¹ãæ£åžžã«çµäºããªãå ŽåããããŸããPerl ã® alarm ã䜿ã£ã exec ã¯ããµãããã»ã¹ãå«ããŠç¢ºå®ã«çµäºãããŸãã
Claudeã«ã¯ã¹ããŒãžã³ã°ãã£ã¬ã¯ããªïŒ$STGïŒãž curator-proposals.md ãæžãããã·ã§ã«ãã³ããŒããæ§é ã«ããŠããŸãã ~/.claude/ ã¯æžã蟌ã¿ä¿è·ãããŠããã±ãŒã¹ããããããClaudeã«çŽæ¥æžããããšãšã©ãŒã«ãªãå¯èœæ§ããããŸããäžæãã£ã¬ã¯ããªãäžç¶ç¹ã«ããããšã§ãæš©éåé¡ãåé¿ããŠããŸãã
ååã®ææ¡ãã¡ã€ã«ããæ°ããSKILL.mdã ãã察象ã«ããŠããŸãã æ¯é±å
šã¹ãã«ãèªã¿çŽãã®ã¯ããŒã¯ã³ã®ç¡é§ã§ããprop_mtime ïŒååã®ææ¡ãã¡ã€ã«ã®mtimeïŒããæ°ãã SKILL.md ã ããå·®ååŠçããããšã§ã鱿¬¡å®è¡ã®ã³ã¹ããæå°åããŠããŸãã
å šäœã³ãŒãã®å€æ°ããã
å®ã³ãŒããèªãéã®åç §çšãšããŠãã¹ã¯ãªããå ã®äž»èŠå€æ°ãæŽçããŠãããŸãã
| 倿° | å€ïŒå®ã³ãŒãããïŒ | åœ¹å² |
|---|---|---|
AUTO |
~/.claude/skills/auto |
ã¹ãã«æ ŒçŽã«ãŒã |
LOGS |
~/Documents/my-knowledge-base/raw/conversations |
äŒè©±ãã°æ€çŽ¢å¯Ÿè±¡ |
SNAP |
~/.claude/skills/auto/.snapshots |
ã¹ãããã·ã§ããä¿åå |
ARCH |
~/.claude/skills/auto/.archive |
archiveéé¿å |
LOG |
~/.claude/skills/auto/.curate.log |
å®è¡ãã° |
PROP |
~/.claude/skills/auto/.curator-proposals.md |
LLMææ¡åºåå |
STALE_DAYS |
30 |
staleãã©ã°éŸå€ïŒæ¥æ°ïŒ |
ARCHIVE_DAYS |
90 |
archiveéé¿éŸå€ïŒæ¥æ°ïŒ |
RUN_LLM |
第1åŒæ°ãããã©ã«ã "llm"
|
"nollm" ã§LLMãã§ãŒãºã¹ããã |
launchdã®å®è¡ãã°ã¯ ~/.claude/logs/com.shun.skill-curate.log ã«æžã蟌ãŸããŸãïŒplistã® StandardOutPath / StandardErrorPathïŒãã¹ã¯ãªããå
ã®ã¢ããªãã°ïŒ$LOGïŒãšã¯å¥ãã¡ã€ã«ã§ãlaunchdèµ·åæã®ããã»ã¹ã¬ãã«ã®ãšã©ãŒã¯ãã¡ãã«æ®ããŸãã
ãã®äºéãã°æ§é ã¯ããã¹ã¯ãªãããèµ·åãããã©ããããšãã¹ã¯ãªãããäœããããããåããŠè¿œè·¡ã§ããç¹ã§æå¹ã§ããlaunchdã®ãã°ã«äœãæžãããŠããªããã°ã¹ã¯ãªãããèµ·åããŠããªããã¹ã¯ãªããã®ãã°ã snapshot taken ã§æ¢ãŸã£ãŠããã°ããã®å
ã§ãšã©ãŒãèµ·ããŠããŸãã
ãããŸã§ãããªããã®ä»çµã¿ãå¹ãã®ãããšãã©ãåããŠããã®ããã®å šäœåã§ããæ¬¡ã¯ããã®èšèšã®æå€§ã®åŒ±ç¹ã§ãã ãäŒè©±ãã°èšåã䜿çšãšèŠãªããä»£çææšã®æ€èšŒæ¹æ³ãšãå®éã«èžãã ã€ãŸãã ãæãäžããŸãã
å®è£ ã®è©³çް
åé 2è¡ãé»ã£ãŠå®ã£ãŠãããã®
set -u
export PATH="$HOME/.local/bin:$HOME/.nvm/versions/node/v24.13.0/bin:/usr/bin:/bin:/usr/sbin:/sbin"
set -u ã¯æªå®çŸ©å€æ°ãåç
§ããç¬éã«ã¹ã¯ãªãããæ¢ããŸããäžèŠå°å³ã§ãããããããªããš "$lastlog" ã空ã®ãŸãŸ float() ã«æž¡ããPythonãé»ã£ãŠ 0 ãè¿ããå
šã¹ãã«ããæçµäœ¿çšïŒ1970å¹Žãæ±ãã«ãªããŸããäžæ©ã§å
šã¹ãã«ãarchiveãããæèµ·ãããã¹ãã«ãæ¶ããŠããããšããäºæ
ãé²ãäžè¡ã§ãã
export PATH ã¯ãã£ãšå³ç©çãªçç±ã§ããlaunchdãèµ·åããã·ã§ã«ã¯ãããªããæ¯æ¥äœ¿ãzshãšã¯å¥ã®æå°ç°å¢ã§ãã~/.zshrc ã ~/.nvm/nvm.sh ãèªã¿èŸŒãŸããªããã€ãŸã claude ã³ãã³ãã node ããPATHã«æç€ºããªãéããååšããªããæ±ãã«ãªããŸããplistã«ãåãPATHãæžããŠããŸãïŒ<key>EnvironmentVariables</key> 以äžïŒããã¹ã¯ãªããåŽã«ãæžãã®ã¯å€éé²è¡ã§ããplistã®PATHã¯launchdãããã»ã¹ã«æž¡ãç°å¢å€æ°ã§ãããã¹ã¯ãªããå
ã§ãµãã·ã§ã«ãèµ·åããå Žåã«ã¯åŒãç¶ãããªãããšããããŸããexport PATH ãäž¡æ¹ã«æžãã®ã¯åé·ã«èŠããŠãå®éã«ã¯å¿
èŠãªèšèšã§ãã
find ã³ãã³ãïŒ4ã€ã®ãã©ã°ãå šéšèŠãçç±
find "$AUTO" -mindepth 1 -maxdepth 1 -type d ! -name '.*' -print 2>/dev/null
ãã®findã¯ãauto/ çŽäžã®ã¹ãã«ãã£ã¬ã¯ããªã ããåæãããããã®4ãã©ã°ã»ããã§ããåãã©ã°ãå€ãããšãã«äœãèµ·ããããå®éã«èãããšããªãå
šéšèŠããããããŸãã
-mindepth 1ãå€ããš $AUTO èªèº«ããããããã«ãŒãã auto/ ãã£ã¬ã¯ããªå
šäœã1ã¹ãã«ãšããŠåŠçããããšããŸããauto/SKILL.md ãæ¢ãã«è¡ãããªããã° continue ãããã ãã§ããããã°ã«ãã€ãºãæ®ããŸãã
-maxdepth 1ãå€ããš .archive/ é
äžã®éé¿æžã¿ã¹ãã«ãåã³ã¹ãã£ã³å¯Ÿè±¡ã«ãªããŸãããã£ããéé¿ããã¹ãã«ããäŒè©±ãã°ã«ãããããªãããå床archiveããšããç¡éã«ãŒãã«å
¥ããmv ããç§»åå
ã«ååãã£ã¬ã¯ããªãæ¢ã«ååšããããšã©ãŒã§æ¢ãŸããŸãã
-type dãå€ããš .curate.log ã .curator-proposals.md ã®ãã¡ã€ã«ããããããŸããbasename ã§ãã¡ã€ã«åãåããSKILL.mdã®ååšç¢ºèªã§ê±žë¬ãããã®ã§å®å®³ã¯ãŒãã§ããããã°ã«ç¡æå³ãª skip ãšã³ããªã倧éã«ç©ãŸããŸãã
! -name '.*'ãå€ããš .snapshots ãš .archive ãã¹ãã£ã³å¯Ÿè±¡ã«ãªããŸãã.snapshots ã«ã¯ SKILL.md ããªãã®ã§ continue ãããŸããã.archive ã®äžèº«ã¯æ¬ç©ã®ïŒéé¿æžã¿ïŒã¹ãã«ã§ããããã« author: auto ãããã¹ãã«ãå床stale/archiveå€å®ãåãããã§ã« .archive/ ã«ããã®ã«å床 mv "$d" "$ARCH/" ããããšãããã¹ãå€ã«ãªããŸãã
2>/dev/null ã¯macOSã®æš©éãšã©ãŒããµã€ã¬ã³ãåããããã§ãã~/.claude/ é
äžã®äžéšãã¡ã€ã«ãä»ããã»ã¹ã«ããã¯ãããŠãããš find ã Permission denied ãåããŸãããããããã°ã«æµããšæ¬æ¥ã®æŽçãã°ãåãããŸãã
Python ã€ã³ã©ã€ã³ãšããéžæã®çç±
ã¹ã¯ãªããå
ã«2ç®æãPythonã³ãŒãã <<'PY' ãã¢ããã¥ã¡ã³ãã§åã蟌ãŸããŠããŸããããªãå¥ãã¡ã€ã«ã® .py ã«ããªãã®ãããšæåã«èãããŸããã
çç±ã¯åäžãã¡ã€ã«ã§èªå·±å®çµããŠããããšã§ããskill-curate.sh ã ãã ~/.claude/scripts/ ã«çœ®ãã°åããPythonã¹ã¯ãªããã®é
眮ãã¹ãå¥é管çããå¿
èŠããªããã¹ãã«ãã¥ã¬ãŒã¿ãŒã®èšå®ãäººã«æž¡ããšããããã®ãã¡ã€ã«1æ¬ã§ããã
<<'PY' ã®ã·ã³ã°ã«ã¯ã©ãŒããéèŠã§ãã<<PY ã ãšãã¢ããã¥ã¡ã³ãå
ã® $d ã $md ãã·ã§ã«ã«å±éãããŠããŸããPythonåŽã«æ£ããæååãæž¡ããŸãããã·ã³ã°ã«ã¯ã©ãŒãã§å²ãããšã§ããã¢ããã¥ã¡ã³ãã®å
容ããªãã©ã«æååãšããŠPythonã«æž¡ããŸãã
æ¥æ°èšç®ãPythonã§æžããçç±ãæç¢ºã§ãbashã®æ¥ä»èšç®ã¯macOSãšGNU/Linuxã§æžãæ¹ãéããŸããdate -d ã¯GNUãdate -v ã¯BSDãPythonã® time.time() ãš os.path.getmtime() ã¯ã¯ãã¹ãã©ãããã©ãŒã ã§åãïŒä»åã¯macOSå°çšèšèšã§ãããå°æ¥ã®ç§»æ€ã³ã¹ããäžããïŒã
staleæžã蟌ã¿ã®2ãã¿ãŒã³æ£èŠè¡šçŸ
if re.search(r'^status:', s, re.M):
s = re.sub(r'^status:.*$', 'status: stale', s, count=1, flags=re.M)
else:
s = re.sub(r'^(author:[ \t]*auto.*)$', r'\1\nstatus: stale',
s, count=1, flags=re.M)
ãã§ã« status: ãã£ãŒã«ããããã¹ãã«ãšããªãã¹ãã«ã§åŠçãåããŠããŸãã
status: ãæ¢ã«ããå Žåã¯åçŽãªçœ®æã§ããactive ã experimental ãªã©äœãæžããŠãã£ãŠã status: stale ã«æžãæããŸããcount=1 ã§æåã®1ä»¶ã ã眮æããã®ã§ãæ¬æäžã«å¶ç¶ status: ãšããæååãåºãŠããŠãå®å
šã§ãã
status: ããªãå Žå㯠author: auto ã®çŽåŸã«æ¹è¡ã§æ¿å
¥ããŸãããªã author: auto ã®çŽåŸããYAMLããã³ããã¿ãŒã¯ --- ã§å²ãŸãããããã¯ã§ãããPythonã¯ãã®ãããã¯å¢çãæèããè§£æãããŠããŸããïŒæååãšããŠæ£èŠè¡šçŸã§åŠçïŒãããã³ããã¿ãŒã®æåŸã®è¡ïŒ---ïŒã®åã«æ¿å
¥ããã®ãçæ³ã§ããããããããã«ã¯ --- ã®äœçœ®ãæ¢ãå¿
èŠããããã³ãŒããè€éã«ãªããŸããauthor: auto ã¯å¿
ãããã³ããã¿ãŒã«ååšããããšãå®å
šã¬ãŒãã§ä¿èšŒãããŠããã®ã§ããããæ¿å
¥ç¹ã«ããã®ãæãåçŽãã€å®å
šã§ãã
LLMãã§ãŒãºã®3ã€ã®å®å šè£ 眮
ååã§ãè§ŠããŸãããã3ã€ã®å·¥å€«ãããããæ·±æãããŸãã
--strict-mcp-config --mcp-config '{"mcpServers":{}}'
ãããçç¥ããŠlaunchdããClaudeãèµ·åãããšãClaude㯠~/.claude/claude_desktop_config.json ãé¡äŒŒã®MCPèšå®ãèªã¿ãObsidian MCPãFigma MCPãªã©ã®ãµãŒããŒãèµ·åããããšããŸãããããã¯èªèšŒãèŠæ±ããUIããªãç°å¢ã§ã¯åŸ
ã¡ç¶ããããã¿ã€ã ã¢ãŠãããŠå€±æããŸããMCPã空ãªããžã§ã¯ãã§äžæžãããããšã§ãClaudeæ¬äœã ããã·ã³ãã«ã«èµ·åã§ããŸãã
perl -e 'alarm 600; exec @ARGV'
bashã® timeout 600 claude ... ãšã»ãŒåãã«èŠããŸãããããã»ã¹ã°ã«ãŒãã®æ±ããéããŸããtimeout ã¯ã¿ã€ã ã¢ãŠãæã«SIGTERMãçŽæ¥ã®åããã»ã¹ïŒããã§ã¯ claude ã³ãã³ãïŒã«éããŸãããããClaudeã¯å
éšã§Node.jsã®ã¯ãŒã«ãŒããµãããã»ã¹ãè€æ°èµ·åããããšããããSIGTERMãåããã»ã¹ã ãã«å±ããå«ããã»ã¹ãæ®çããããšããããŸããperl -e 'alarm 600; exec @ARGV' ã¯åãPIDã§Claudeã exec ãããããã·ã°ãã«ããã®ããã»ã¹ã°ã«ãŒãå
šäœã«å±ããŸãã
STGã¹ããŒãžã³ã°ãã£ã¬ã¯ããª
STG=$(mktemp -d -t skill-curate-stg)
( cd "$STG" && ... "$CLAUDE" ... -p "... ./curator-proposals.md ..." )
[[ -f "$STG/curator-proposals.md" ]] && cp "$STG/curator-proposals.md" "$PROP"
rm -rf "$STG"
Claudeã« ~/.claude/skills/auto/.curator-proposals.md ãžçŽæ¥æžããããšãlaunchdç°å¢ã§ã¯ ~/.claude/ ãæžã蟌ã¿ä¿è·ãããŠããã±ãŒã¹ã§å€±æããŸããmktemp -d ã§äœã£ãäžæãã£ã¬ã¯ããªã« cd ããŠããèµ·åããããšã§ãClaudeããèŠãã«ã¬ã³ããã£ã¬ã¯ããªã $STG ã«ãªããŸããClaudeãžã®æç€ºã«ã¯ ./curator-proposals.mdïŒçžå¯Ÿãã¹ïŒãšæžãã°ã$STG/curator-proposals.md ã«æžãããŸããæåããã cp ã§æ£èŠã®å Žæã«çœ®ããrm -rf "$STG" ã§äžæãã£ã¬ã¯ããªãçä»ããŸãã
active >= 2 ãšããéŸå€
if [[ "$RUN_LLM" != "nollm" ]] && (( active >= 2 )) && [[ -x "$CLAUDE" ]]; then
ãªã1ä»¶ã§ãLLMãåŒã°ãªãã®ãããéè€ã»äœå質ã»çµ±ååè£ãæŽãåºãããšããäœæ¥ã¯ãæ¯èŒå¯Ÿè±¡ãè€æ°ãªããšæå³ããªããŸããã1ä»¶ã®ã¹ãã«ãèªãã§ãããäœå質ã§ã¯ïŒããšå€å®ãããããšã¯æè¡çã«ã¯å¯èœã§ãããClaude APIãåŒã³åºãã³ã¹ãã«èŠåã䟡å€ããªãã鱿¬¡ã§æå€§5ãã«ã®äžéïŒ--max-budget-usd 5.00ïŒãèšããŠããŸãããããããåŒã³åºããªãã®ããã¹ãã§ãã
activeä»¶æ°ãå€ãã»ã©LLMææ¡ã®äŸ¡å€ã¯äžãããŸãã10ä»¶ã®ã¹ãã«ã«ããããšããã¯åãå 容ãªã®ã§çµ±åã§ããŸãããšèšã£ãŠãããã®ã¯æçšã§ãã
ç§ãè©°ãŸã£ã話
è©°ãŸãâ ïŒlaunchdã§åããäœãããªã
çç¶ïŒã¿ãŒããã«ã§æåå®è¡ãããšæ£åžžåäœãããlaunchdã«ç»é²ããŠç¿é±åŸ
ã£ãŠã .curate.log ã空ã®ãŸãŸã
åå ïŒclaude ã³ãã³ããèŠã€ãããªããlaunchdç°å¢ã®PATH㯠/usr/bin:/bin:/usr/sbin:/sbin ã ãã§ãã~/.local/bin/claude ã¯ãã¡ããã~/.nvm/versions/node/v24.13.0/bin/ ã® node ããªããã¹ã¯ãªããã [[ -x "$CLAUDE" ]] ã§ claude ã®ååšç¢ºèªãã㊠false ã«ãªããLLMãã§ãŒãºãã¹ãããããããæŽçãã§ãŒãºã¯ python3 ã䜿ã£ãŠããŠããã¡ããèŠã€ãããªãå Žå㯠days ã®èšç®ããŒãïŒçµäºã³ãŒãéãŒãã®ãŸãŸæé»çã«ïŒã«ãªã£ãŠããŸãããçµæãã¹ãããã·ã§ããã¯äœæãã snapshot taken ã ãæžãããŠããã§éæ¢ããŠããã
çŽãæ¹ïŒplistã® EnvironmentVariables ã«å®å
šãªPATHãæžããã¹ã¯ãªããã®åé ã§ã export PATH ãããäž¡æ¹ã«æžãã®ã¯åé·ã«èŠããŸãããlaunchdãæž¡ãç°å¢å€æ°ãšã¹ã¯ãªããå
ã§åãšã¯ã¹ããŒããã倿°ã¯å¥ã®ã¬ã€ã€ãŒã§ããçæ¹ã ãã§ã¯ç¹å®ã®ç°å¢ã§åçŸããåé¡ããã£ããããçŸåšã®ã¹ã¯ãªããã®ããã«äž¡æ¹ã«æžã圢ãå®å®ããŠããŸãã
è©°ãŸãâ¡ïŒã¹ãããã·ã§ãããæ¯é±10åã«èšããã§ãã
çç¶ïŒ.snapshots/ ãã£ã¬ã¯ããªã3é±ç®ã«æ¥ã«éããªã£ããls -lh ~/.claude/skills/auto/.snapshots/ ãèŠããšãææ°ã®tar.gzãå
é±ã®10åã®ãµã€ãºã
åå ïŒ--exclude ãæžããŠããªãã£ãããã.snapshots/ èªäœãtar.gzã®äžã«å«ãŸããŠãããã€ãŸãå
é±ã®ã¹ãããã·ã§ããïŒã¢ãŒã«ã€ãå
ã®ã¢ãŒã«ã€ãïŒãä»é±ã®tar.gzã«äžžããšå
¥ã蟌ãã§ããããããæ¯é±ååž°çã«èšããã3é±ç®ã«ã¯ãã¹ãããã·ã§ããã®ã¹ãããã·ã§ããã®ã¹ãããã·ã§ããããšããå
¥ãåæ§é ã§ãã£ã¹ã¯ãå§è¿«ããŠããŸããã
çŽãæ¹ïŒ
tar czf "$SNAP/auto-$(date +%Y%m%d-%H%M%S).tar.gz" \
-C "$HOME/.claude/skills" \
--exclude='auto/.snapshots' \
--exclude='auto/.archive' \
auto 2>/dev/null
--exclude='auto/.snapshots' ãš --exclude='auto/.archive' ã远å ããŠè§£æ±ºãtarã® --exclude ã¯tar.gzå
ã®ãã¹ã§æå®ããŸãã-C "$HOME/.claude/skills" ã§ã¹ãã«ãã£ã¬ã¯ããªã« cd ããç¶æ
ã§taråããŠãããããauto/.snapshots ãšããçžå¯Ÿãã¹ã§æ£ããé€å€ãããŸãã
å€ãã¹ãããã·ã§ããã®åé€ã¯çŸæç¹ã§èªååããŠããŸãããææ¬¡ã§ find ~/.claude/skills/auto/.snapshots -name '*.tar.gz' -mtime +60 -delete ãæåå®è¡ããéçšã§ããããã¯æ¬¡ã®æ¹å課é¡ãšããŠæ®ã£ãŠããŸãã
è©°ãŸãâ¢ïŒtimeout ã§Claudeãæ®çãç¶ãã
çç¶ïŒLLMãã§ãŒãºã600ç§ã§æ¢ãŸãããps aux | grep claude ãç¿æã®launchdèµ·åæã«ãClaudeããã»ã¹ã衚瀺ãããç¿é±ã®å®è¡ãšåé±ã®å®è¡ã䞊走ãã$PROP ã®æžã蟌ã¿ãç«¶åããŠãã¡ã€ã«ãå£ããã
åå ïŒæåã®ããŒãžã§ã³ã§ã¯ timeout 600 "$CLAUDE" ... ãšæžããŠããŸãããtimeout ã¯ã¿ã€ã ã¢ãŠãæã«SIGTERMãçŽæ¥ã®åããã»ã¹ã«éããŸãããããClaude CLIïŒããŒãžã§ã³ã«ããïŒã¯å
éšã§Node.jsã®worker_threadsæãã¯åããã»ã¹ãçæããããšããããSIGTERMã芪ããã»ã¹ã®ã¿ã«å±ããŠå«ããã»ã¹ãçãæ®ãç¶æ³ãçºçããŸããã
çŽãæ¹ïŒ
perl -e 'alarm 600; exec @ARGV' "$CLAUDE" ...
exec @ARGV ã«ãã£ãŠperlã¯Claudeã«çœ®ãæããïŒperlã®PIDãClaudeã®PIDã«ãªãïŒãalarm ã·ã°ãã«ã¯ãã®ããã»ã¹ã°ã«ãŒãå
šäœã察象ã«ããŸããå ã㊠( cd "$STG" && perl -e ... ) ã®ãµãã·ã§ã«å
šäœãããã»ã¹ã°ã«ãŒããšããŠæ±ãããšã§ãæ®çããã»ã¹ãçºçãã«ããæ§é ã«ãªããŸããããã®ä¿®æ£åŸã¯ç¿æã«æ®çããã»ã¹ã確èªãããªããªã£ãŠããŸãã
è©°ãŸãâ£ïŒã¹ãã«åãçããšäŒè©±ãã°å šäœãããããã
çç¶ïŒcodex ãšããã¹ãã«åãä»ãããã®ãäœã£ããšããããã®ã¹ãã«ãæ°žä¹
ã«ã䜿çšäžïŒactiveïŒããšå€å®ããããäŒè©±ãã°ã® grep -rl -- "codex" ãå
šãã¡ã€ã«ãè¿ããŠããŠãææ°mtimeããä»é±ã®äŒè©±ãã°ãã«ãªãç¶ããã
åå ïŒäŒè©±ãã°ã«ã¯ãCodexã«æããããCodexã§å®è£
ããããšããæ¥åžžçãªèšè¿°ãç¡æ°ã«ååšããŸããã¹ãã«å codex ã¯åèªãšããŠäžè¬çãããŠããã°æ€çŽ¢ãã¹ãã«ã䜿çšããšãåãªãèšåããåºå¥ã§ããŸããã
çŽãæ¹ïŒãšéçïŒïŒæ ¹æ¬çãªè§£æ±ºã«ã¯ãªã£ãŠããŸãããçŸæç¹ã§ã®å¯ŸåŠã¯ãã¹ãã«åãã§ããã ãåºæã§é·ãããããšã§ããcodex ã§ã¯ãªã codex-delegation-handoff ã®ãããªãã€ãã³åºåãã®è€åèªã«ãããšãgrep ãå®å
šäžèŽã«è¿ã粟床ã§ãããããŸããgrep -rl -- "codex-delegation-handoff" ã¯æ±çšçãªäŒè©±ãã°ã§ã¯ã»ãŒãããããŸããã
èšèšçã«ã¯ãäŒè©±ãã°ãžã®èšåã䜿çšã®ä»£çææšã«ãããããšèªäœãè¿äŒŒã§ããããã®ç²ŸåºŠã¯ãã®è¿äŒŒã®æ§é çãªéçã§ããå®ç§ãªäœ¿çšãã°ãAPIã¬ãã«ã§åããªã以äžãã¹ãã«åœåã®èŠçŽã§ã«ããŒããã®ãçŸæç¹ã®ãã¹ãã§ãã
è©°ãŸãâ€ïŒstaleãã©ã°ãæ¬æã«æžã蟌ãŸãã
çç¶ïŒããã¹ãã«ã® SKILL.md ãéããšãããã³ããã¿ãŒïŒ--- ã§å²ãŸããéšåïŒã§ã¯ãªãæ¬æã®äžã« status: stale ãçªç¶æžãããŠãããYAMLãšããŠã¯ç¡å¹ã§ã次åã®grepå€å®ãå£ããã
åå ïŒãã®ã¹ãã«ã®æ¬æïŒèª¬æã®äŸç€ºéšåïŒã« author: auto ã®å Žåã¯... ãšããæååãå«ãŸããŠããŸãããæ£èŠè¡šçŸ r'^(author:[ \t]*auto.*)$' ã® re.M ãã©ã°ã¯å
šè¡ã«å¯Ÿã㊠^ ãè¡é ãšããŠæ±ããŸããããã³ããã¿ãŒå
ã® author: auto ããå
ã«æ¬æå
ã® author: auto ã®å Žåã¯... ãåºãŠããå Žåãããã«ãããã㊠\nstatus: stale ãæ¿å
¥ãããŸãã
çŽãæ¹ïŒcount=1 ãããã®ã§ãæåã®1ä»¶ã ãã眮æãããšããå¶çŽã¯ãããŸããã€ãŸãæ¬æãå
ã«ããå Žåã¯æ¬æã«ãã©ã°ãå
¥ããããã³ããã¿ãŒã«ã¯å
¥ããŸãããæ£ç¢ºãªä¿®æ£ã¯ãããã³ããã¿ãŒïŒ--- ããæåã® --- ãŸã§ïŒã ãã察象ã«ããããŒãµãŒãæžããããšã§ãããã³ãŒãéãå¢ããŸãã
çŸåšã®çŸå®çãªå¯ŸåŠã¯ãã¹ãã«æ¬æã®äŸç€ºã³ãŒãã« author: auto ãšããæååãæžããªããšããèŠçŽã§ããã³ãŒããããã¯å
ã®YAMLäŸç€ºã§ããã°ããã¯ã¯ã©ãŒãã§å²ãããè¡é ã«ã¯ãªãã ^ ã«ãããããŸããããã€ã³ã©ã€ã³ã®èª¬ææã«ã¯æ³šæãå¿
èŠã§ããå®å
šãªä¿®æ£ã¯FrontmatterããŒãµãŒã®å®è£
ãšããŠç©ã¿æ®ãã«ãªã£ãŠããŸãã
èªååãããŸãåããªãçç±ã¯ãã»ãšãã©ã®å ŽåãããŒã«ã®æã蟌ã¿ãã§ããã¿ãŒããã«ã§åãããlaunchdã§ãåããSIGTERMãéãã°å¿ ãæ¢ãŸããgrepã§ååãæ¢ãã°äœ¿çšãæ€ç¥ã§ãããã©ããçŽæçã«æ£ããèŠããŠãå®éã®ç°å¢ã§ã¯å£ããŸãã
ãã®ä»çµã¿ãäœã£ãæ¬åœã®æå³ã¯ã鱿¬¡ã®èªåæŽçãããããã©ãã§å£ãããããäºåã«èãæããèšèšã®æèããã»ã¹ãèªåã®ãã®ã«ããããšã ã£ããããããŸãããç¡äººã§èµ°ããããã®ãäœããã³ã«ãåãåããæ¥ãŸããããããå€äžã®4æã«å€±æãããšããæèµ·ããèªåãäœãèŠãã°åå ããããããã
ããã«çãç¶ããããšããèªåŸç°å¢ã®å質ãäžããŠããå¯äžã®éã§ãã
ã€ãŸãããã€ã³ã
åæ®µã§5ã€ã®è©°ãŸããæ·±æãããŸããããå®éçšã§ã¯ãã以å€ã«ã现ããèœãšã穎ãç©ã¿éãªããŸããå®ã³ãŒããšå®äœéšããç¶²çŸ ããŸãã
-
launchctl loadãéæšå¥šãªã®ã«éã£ãŠããŸããmacOS Monterey以éãæ£ããç»é²ã¯launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.shun.skill-curate.plistãå€ãloadã³ãã³ãã¯ãDeprecatedããšèšããªããåãä»ããããšããããèµ·åããªãçç¶ãåçŸæ§ãªãåºãŸããç»é²ç¶æ ã®ç¢ºèªã¯launchctl list | grep skill-curateã§PIDæ¬ãèŠããå€ããŒããªããç»é²æžã¿ã ãäžåºŠãèµ·åããŠããªããã§ãã -
$LOGSãã£ã¬ã¯ããªã空ã»äžåšã ãšå šã¹ãã«ãæªäœ¿çšæ±ãã«ãªããã¹ã¯ãªãã9è¡ç®ã§LOGS="$HOME/Documents/my-knowledge-base/raw/conversations"ãšå®çŸ©ããŠããŸãããã®ãã¹ãå®åšããªãå Žåãgrep -rl -- "$skill" "$LOGS"ã¯ããããŒãã§lastlogã空æååã«ãªããŸããset -uã¯ãæªå®çŸ©å€æ°ã®åç §ããæ¢ããåœä»€ã§ãããã空æååã®å€æ°ãã«ã¯åå¿ããŸãããPythonã¯ãã©ãŒã«ããã¯ãšããŠcreated:âmtimeã䜿ããŸãããã¹ãã«ãäœã£ãæ¥ãæçµäœ¿çšæ¥ãšã¿ãªããããäœã£ãŠãã30æ¥ãçµéããŠããã°å šã¹ãã«ãäžæã«staleã«ãªããŸããæåã«ãã°æ ŒçŽãã¹ã®å®åšç¢ºèªã[[ -d "$LOGS" ]] || { echo "LOGS missing"; exit 1; }ã§å ã«ã¯ããã¹ãã§ããã -
äŒè©±ãã°ã«ãã€ããªãæ··åšãããšgrepãåœéœæ§ãåºãããã°ãã£ã¬ã¯ããªã«
.pngãæ·»ä»ãã¡ã€ã«ãçŽãããšãgrep -rl -- "skill-name"ããã€ããªã«ããããããŸããçŸè¡ã®grepã«--include='*.md'ã--include='*.txt'ã¯ä»ããŠããŸãããäŒè©±ãã°ã®ãã©ãŒãããïŒçŽããã¹ãã®ã¿ïŒãåæãšããèšèšã§ãããã€ããªãæ··å ¥ããŠãããã£ã¬ã¯ããªã$LOGSã«æå®ãããšã¹ãã«ããåžžã«æè¿äœ¿ãããŠããããšèª€å€å®ãç¶ããŸãã -
stat -f '%m'ã¯macOSïŒBSDïŒå°çšæ§æãã¹ã¯ãªãã40è¡ç®ã§äœ¿ã£ãŠããŸããGNU/Linuxã®stat --format=%Yãšã¯æžãæ¹ãéããŸããä»åã®launchdåæã§ã¯macOSåºå®ãªã®ã§å®å®³ãŒãã§ãããåãã¹ã¯ãªãããDockerã³ã³ãããLinuxãµãŒããŒã«æã¡èŸŒãéã¯æžãæããå¿ èŠã§ããPythonã®os.path.getmtime()ãã¯ãã¹ãã©ãããã©ãŒã ã§æžãããŠããã®ãšé察称ã§ãã -
Python
sys.argvã®é²è¡çã€ã³ããã¯ã¹è£å¡«ãå€ããšIndexErrorã§ã¯ã©ãã·ã¥ãå®ã³ãŒã44è¡ç®ïŒlastlog, created, md = (sys.argv + ["","",""])[1:4]+ ["","",""]ã®è£å¡«ããªããšãbashåŽã§åŒæ°ã1ã€ã§ãæ¬ ãããšãIndexErrorãåºãŠçµäºã³ãŒãéãŒãã«ãªããŸããdaysã空ã®ãŸãŸif (( days > ARCHIVE_DAYS ))ã«å ¥ããšç®è¡åŒãšã©ãŒã§ã¹ã¯ãªããå šäœãããã§æ¢ãŸããŸããPythonåŽã§ã¯ã©ãã·ã¥ããªãããã«ããŠããããšã§ãbashåŽã®é²è¡ã©ã€ã³ãèãããŠãå®å šãªæ§é ã«ããŠããŸãã -
--max-budget-usd 5.00ã§éäžæã¡åãã«ãªããš proposals.md ãäžå®å šãLLMã5ãã«ã®äžéã«éããæç¹ã§Claudeã匷å¶çµäºããã$STG/curator-proposals.mdã¯æžãåºãéäžã®Markdownã«ãªããŸããã¹ã¯ãªããã¯[[ -f "$STG/curator-proposals.md" ]]ã§ãã¡ã€ã«ã®ãååšãã ãã確èªããŠcpãããããå 容ãå£ããŠããŠãäžæžããããŸããéèŠãªææ¡ãèŠèœãšããªã¹ã¯ã¯ãããŸãããäžéãèšããªãå Žåã¯é±æ¬¡ãããã§APIã³ã¹ããé倩äºã«ãªããŸãã5ãã«ã¯ãææ¡ãã¡ã€ã«ãå£ããŠãçããªãäžéããšããŠèšå®ããŠããŸãã -
com.shun.skill-curate.logã¯ããŒããŒã·ã§ã³èšå®ãªããplistã®StandardOutPathãšStandardErrorPathã¯åããã¡ã€ã«~/.claude/logs/com.shun.skill-curate.logãæããŠããŸãïŒplistå®è£ ããïŒã鱿¬¡å®è¡ã®ãã³ã«è¿œèšãããããã1幎æŸçœ®ãããšæ°åMBã«ãªããŸããmacOSã®newsyslogèšå®ãæªå®è£ ã§ããçŸç¶ã¯tail -100 ~/.claude/logs/com.shun.skill-curate.logã§çŽè¿ã®ã¿ç¢ºèªããéçšã§ãã -
ã¹ãããã·ã§ããã®åé€ãèªååããŠããªãã®ã§ç©ã¿äžãããçŸè¡ã¹ã¯ãªããã¯ã¹ãããã·ã§ãããäœãã ãã§åé€ããŸãããææ¬¡ã§æåå®è¡ãå¿ èŠã§ãïŒ
find ~/.claude/skills/auto/.snapshots -name '*.tar.gz' -mtime +60 -deleteãã®1è¡ãææ¬¡launchdã«ä»èŸŒãïŒplistã§
WeekdayãçããŠDay: 1= æ¯æ1æ¥ïŒã®ãæ¬¡ã®æ¹åã¹ãããã§ãã -
launchdäºéèµ·åæã«
.curator-proposals.mdã®æžã蟌ã¿ãç«¶åãLLMãã§ãŒãºã600ç§ãè¶ ããŠç¿é±ã®StartCalendarIntervalãçºç«ãããšã2ã€ã³ã¹ã¿ã³ã¹ã䞊走ããŸãã.curate.log㯠append ãªã®ã§ãã¡ã€ã«ã¯å£ããŸãããã$PROPãã¡ã€ã«ã«ã¯2ããã»ã¹ãåæã«cpãèµ°ãããŸããçŸè¡å®è£ ã«flockã«ããããã¯ãã¡ã€ã«ã¯ãããŸãããäžŠèµ°ã«æ°ã¥ãæãããã¯.curate.logã«curate doneã2è¡é£ç¶ã§çŸããããšã§ãã -
author:ã®æžãæããå¿ãããšæå³ããarchiveããããæ®ãããã¹ãã«ãä¿è·ããã«ã¯author:ãã£ãŒã«ããauto以å€ã«å€ããã ãã§æžã¿ãŸãïŒäŸ:author: manualïŒãããããããšã§å€ãããããšåŸåãã«ãããšå¿ããŸãã90æ¥åŸã«éãã«.archive/ãžç§»åãããŠæ°ã¥ããªãããšããäºæ ã«ãªããŸããã¹ãã«ãäœã£ãçŽåŸã«author:ã確èªããç¿æ £ãå¿ èŠã§ãã -
ä»£çææšã®æ€èšŒãæ ããšèª€å€å®ã«æ°ã¥ããªãããäŒè©±ãã°ãžã®èšåã䜿çšãšã¿ãªããè¿äŒŒãã©ã®çšåºŠã®ç²ŸåºŠã§åããŠããããå®æç¢ºèªããã®ã¯éèŠã§ããæ€èšŒã¯1ã³ãã³ãã§ã§ããŸãïŒ
grep -rl -- "skill-name" ~/Documents/my-knowledge-base/raw/conversations/ | wc -lãããæ°ããŒããªããæ¬åœã«äœ¿ãããŠããªãããã¹ãã«åããã°ã«æžãããŠããªãããã®ã©ã¡ããã§ãããŒãã§ã
.archive/éé¿ã¯.snapshots/ãããã€ã§ãæ»ããããã粟床ãäœããŠãåãè¿ãã¯ã€ããŸãã
ãã¹ããã©ã¯ãã£ã¹
å®è£ ãšéçšããå°ãããåçŸæ§ã®ããæéã§ãã
1. ã¹ãã«åã¯åºæã»é·ããã€ãã³åºåãã«ãã
codex ãã codex-delegation-handoffãgrep -rl -- "codex-delegation-handoff" ã¯æ±çšäŒè©±ãã°ã«ã»ãŒãããããŸããã䜿çšä»£çææšã®ç²ŸåºŠã¯ã¹ãã«åœåã®èŠçŽã§ååæ±ºãŸããŸããæ°ããã¹ãã«ãäœããšããskill-name ãäžè¬çãªè±åèªãã©ãã ãå
ã«ç¢ºèªããç¿æ
£ã粟床ã®åºç€ã§ãã
2. author: auto ãã©ã°ãä¿è·æ©æ§ã®å¯äžã®æã«ãã
ãæ©æ¢°ãçæããæŽç察象ãã瀺ããã©ã°ã¯1çš®é¡ã ãã«ããŠããããã以å€ã®ã¹ãã«ã¯ author: manual ã§ã author: lily ã§ããauto ã§ãªããã°å®ã³ãŒã34ã37è¡ç®ã®å®å
šã¬ãŒãã§ç¡æ¡ä»¶ã¹ããããããŸãããã©ã°ãå¢ããããæ¡ä»¶ãè€éã«ããããããšãä¿è·ããžãã¯ãå£ããæã®åœ±é¿ç¯å²ãåºãããŸãã
3. set -u ã¯ãããã¹ã¯ãªããã®æåã®1è¡
æªå®çŸ©å€æ°ã float() ã«æž¡ããš Pythonãé»ã£ãŠ0ãè¿ããå
šã¹ãã«ãã1970幎ããæªäœ¿çšãæ±ãã«ãªããŸããset -u ãããã°æªå®çŸ©å€æ°ã®åç
§ã§ã¹ã¯ãªãããå³åæ¢ãããã°ã«è¡çªå·ãæ®ããŸããåå 調æ»ã®æéã10åãã30ç§ã«çž®ãŸããŸãã
4. PATH 㯠plist ãš ã¹ã¯ãªããã®äž¡æ¹ã«æžã
plist ã® EnvironmentVariables/PATH ã¯launchdãããã»ã¹ã«æž¡ãç°å¢å€æ°ã§ããã¹ã¯ãªããåé ã® export PATH ã¯ãµãã·ã§ã«èµ·åæã«åŒãç¶ãããã®åãšã¯ã¹ããŒãã§ããã©ã¡ããçæ¹ã ãã§ã¯ãç¹å®ã®ç°å¢ã§ãµãã·ã§ã«ã®claude/python3ãèŠã€ãããªããçç¶ãåçŸããŸããçŸè¡ã® plist ãš skill-curate.sh åé ã¯äž¡æ¹ã«åããã¹ãæžããŠããŸãã
5. perl -e 'alarm 600; exec @ARGV' ã§ã¿ã€ã ã¢ãŠããå®å
šã«æãã
bash ã® timeout ã¯çŽæ¥ã®åããã»ã¹ã«SIGTERMãéããŸããClaudeãå
éšã§worker_threadsããµãããã»ã¹ãçæããå Žåãå«ããã»ã¹ãçãæ®ããŸããperl alarm exec ã¯perlãClaudeã«çœ®ãæããïŒåãPIDã§ execïŒãããã·ã°ãã«ãããã»ã¹ã°ã«ãŒãå
šäœã«å±ããŸããç¿é±ã®launchdèµ·åæã«Claudeãæ®çããŠããããšããç¶æ³ãé²ããŸãã
6. LLMã«ã¯ã¹ããŒãžã³ã°ãã£ã¬ã¯ããªã®ã«ã¬ã³ãã§æžããã
mktemp -d ã§äžæãã£ã¬ã¯ããªãäœããããã« cd ããŠããClaudeãèµ·åããŸããClaudeãžã®æç€ºã« ./curator-proposals.mdïŒçžå¯Ÿãã¹ïŒãšæžãããšã§ã~/.claude/ ãžã®çŽæ¥æžãèŸŒã¿æš©éãäžããã«åºåãåãåããŸãã[[ -f "$STG/curator-proposals.md" ]] ã§ãã¡ã€ã«ã®ååšç¢ºèªåŸã« cpãæåŸã« rm -rf "$STG" ã§çä»ããããã®3ã¹ããããã¹ããŒãžã³ã°çµç±ã®å®ç³ã§ãã
7. --max-budget-usd 5.00 ã§LLMã³ã¹ãã«äžéãèšãã
鱿¬¡ãããã®LLMãã§ãŒãºã¯ãææ¡ãæžããã ãã§ãå®éã«ã¹ãã«ã倿ŽããŸãããä»®ã«ææ¡ãã¡ã€ã«ãäžå®å šã§ãç¿é±åå®è¡ãããŸãããã®ã¿ã¹ã¯ã«5ãã«è¶ ã®èª²éã¯äžèŠã§ããäžéå€ã¯ã¿ã¹ã¯ã®ã倱æããŠãçããªãæå€§ã³ã¹ããã§æ±ºããŸãã
8. --strict-mcp-config --mcp-config '{"mcpServers":{}}' ã§MCPãç¡å¹åãã
launchdããClaudeãèµ·åãããšãã€ã³ã¿ã©ã¯ãã£ããªMCPãµãŒããŒãèªèšŒåŸ ã¡ã«ãªããŸããUIã®ãªãç°å¢ã§ã¯æ°žé ã«åŸ ã¡ç¶ããããã¿ã€ã ã¢ãŠãããŠLLMãã§ãŒãºå šäœã倱æããŸãã空ã®MCPèšå®ãäžæžãããããšã§ãClaudeæ¬äœã ããã¯ãªãŒã³ã«èµ·åã§ããŸãã鱿¬¡ãããã§å€éšãµãŒãã¹ã«æ¥ç¶ããå¿ èŠã¯ãããŸããã
9. find ã®4ãã©ã°ã»ããã¯åŽ©ããªã
find "$AUTO" -mindepth 1 -maxdepth 1 -type d ! -name '.*' -print
-mindepth 1ïŒ$AUTO èªèº«ãé€å€ïŒã-maxdepth 1ïŒ.archive/ é
äžã®åã¹ãã£ã³ãé²ãïŒã-type dïŒãã¡ã€ã«ãã¹ãã«ãšèª€èªããªãïŒã! -name '.*'ïŒ.snapshots .archive ãã¹ãã£ã³ããªãïŒã4ã€ã®ãã¡1ã€ã§ãå€ããšç¡å®³ã«èŠããŠåŸã§æ°ã¥ãã«ãããã°ãçãŸããŸãã
10. ã¹ãããã·ã§ããã® --exclude 㯠.snapshots ãš .archive ã®äž¡æ¹
çæ¹ã ãæžããšååž°è¥å€§ããéé¿æžã¿ã¹ãã«ã®äºééé¿ãèµ·ããŸããå®ã³ãŒã24ã26è¡ç®ã®ããã«äž¡æ¹ãæç€ºããŸãïŒ
tar czf "..." --exclude='auto/.snapshots' --exclude='auto/.archive' auto
-C "$HOME/.claude/skills" ã§äœæ¥ãã£ã¬ã¯ããªãç§»åããäžã§ auto ãæå®ããŠããããã--exclude ã®ãã¹ã¯ auto/.snapshots ãšããçžå¯Ÿåœ¢åŒã§ãã
11. nollm åŒæ°ã§LLMãªããã¹ããã§ããå£ãæ®ã
RUN_LLM="${1:-llm}" ã§ç¬¬1åŒæ°ã nollm ã®ãšãLLMãã§ãŒãºãã¹ãããã§ããŸããååã»ããã¢ãããèšå®å€æŽåŸã®åäœç¢ºèªã¯ ~/.claude/scripts/skill-curate.sh nollm ã§èµ°ãããã°ãã¹ãããã·ã§ããååŸã»stale/archiveå€å®ã ããæ€èšŒã§ããŸããClaude APIãåŒã°ãªãã®ã§ã³ã¹ãã»æéã»æ®çããã»ã¹ã®ãªã¹ã¯ããŒãã§ãã
12. äºéãã°èšèšã§ãèµ·åãããããšãäœããããããåé¢ãã
launchdã®ãã°ïŒ~/.claude/logs/com.shun.skill-curate.logïŒã¯ããã»ã¹èµ·åã¬ãã«ã®ãšã©ãŒãèšé²ããŸããã¹ã¯ãªããå
ã®ã¢ããªãã°ïŒ~/.claude/skills/auto/.curate.logïŒã¯ã¹ãããã·ã§ããååŸã»staleå€å®ã»archiveæäœãèšé²ããŸããåé¡èšºæã®é åºã¯ãlaunchdãã°ã«äœããªãâã¹ã¯ãªãããèµ·åããŠããªãããlaunchdãã°ã¯ãããã¢ããªãã°ã snapshot taken ã§æ¢ãŸã£ãŠããâãã®å
ã§ãšã©ãŒããšäºæ®µéã§çµã蟌ããŸãã
13. ãªã¹ãã¢ã³ãã³ãã ~/.claude/scripts/ ã«ã¡ã¢ããŠãã
éçšäžã«ãarchiveããã¹ãã«ãæ»ããããã¯å¿ ãèµ·ããŸããã³ãã³ãããã®å Žã§èããªããŠæžãããã«ãæå ã«çšæããŠãããŸãïŒ
# çŽè¿ã¹ãããã·ã§ãããããã«åŸ©å
tar xzf ~/.claude/skills/auto/.snapshots/auto-YYYYMMDD-HHMMSS.tar.gz \
-C ~/.claude/skills/
# ç¹å®ã¹ãã«ã ã .archive/ ããæ»ã
mv ~/.claude/skills/auto/.archive/skill-name ~/.claude/skills/auto/
14. ä»£çææšã®èª€å€å®ã¯ .archive/ ã®éç Žå£æ§ã§ã«ããŒãã
ãäŒè©±ãã°ãžã®èšåã䜿çšãšã¿ãªããè¿äŒŒã®ç²ŸåºŠã¯å®ç§ã§ã¯ãããŸãããèšèšã®æ£çŽãªè©äŸ¡ãšããŠããã®è¿äŒŒã¯ãå®ç§ãªäœ¿çšãã°ããéçšå¯èœãªææšãéžã¶ããšãã倿ã§ãã誀ã£ãŠarchiveãããã¹ãã«ã¯ mv ã§1ç§ã§æ»ããŸãã粟床ããå¯éæ§ãå
ã«åºããããããèªåŸãããèšèšã®åºæ¬çãªå§¿å¢ã§ãã
ãŸãšã
skill-curate.sh ãš com.shun.skill-curate.plist ããã£ãŠããããšã¯ãçªãè©°ãããš3ã€ã§ããå®è¡åã«ã¹ãããã·ã§ãããåãã»author: auto 以å€ã«ã¯è§Šããªãã»åé€ã§ãªãç§»åã§éé¿ããããã®3ååãããããã粟床ãäœãä»£çææšã§ã鱿¬¡ã§èµ°ããç¶ããããŸãã
ä»£çææšã®éçãç¥ã£ãŠããŠããªã䜿ãã®ã¯ããå®ç§ãªèšèšããããæ¯é±åãäžå®å šãªä»çµã¿ãã®æ¹ã䟡å€ãããããã§ãã鱿¬¡ã§ã¹ãããã·ã§ãããç©ã¿äžãããstaleãã©ã°ãæŽæ°ãããLLMææ¡ãæžãåºãããããã°ãèŠãã°å é±äœãèµ·ããããããããããèªåŸç°å¢ã®ãèšæ¶ãã§ãã
Claude Codeã¯äœ¿ãã°äœ¿ãã»ã©ç¥èãæºãŸããããããã®ç¥èãæŽçããä»çµã¿ããªããã°ãæçµçã«ã¯ã³ã³ããã¹ãå§è¿«ãšãã圢ã§ãã®ç¥èãæ§èœãé£ãå§ããŸããauto-skillã®ãã¥ã¬ãŒã·ã§ã³èªååã¯ããç°å¢ã®ç°å¢ãæŽåãããã¡ã¿ã¬ã€ã€ãŒã§ããæå120äžã®ä»äºã®å€§åã¯ãåå¥ã¿ã¹ã¯ãããªãããæ¬¡ã®100ã¿ã¹ã¯ãèªååãããä»çµã¿ãäœãããšã§ãããã®é±æ¬¡ã¹ã¯ãªããã¯ãã®èãæ¹ã®ãæãå°å³ã§æãå¹ããå®è£ äŸã®ã²ãšã€ã§ãã
ä»çµã¿ã®å
šäœåã»æ120äžã®å
èš³ã»30æ¥æé ã¯æænoteã«ãŸãšããŠããŸãã
ð Claude CodeèªåŸç°å¢ã§ãå®éã©ã皌ãã â ä»çµã¿ã»å®äŸã»å§ãæ¹ã»ãµããŒã
LilyïŒ@bokuwalilyïŒâ å人éçºè ãClaude Code ã§èªåååºç€ãçµã¿ãªãããiOSã¢ããªãWebãµãŒãã¹ãéç£ããŠããŸã
- å¶äœç©ã»èšäºã¯ bokuwalily.com ã«ãŸãšããŠããŸãð¥ïž
- AIã§ãå¯ãŠãŠãåãä»çµã¿ããäœã£ãŠæ120äžã«ãã話㯠noteã®ææèšäº ã«ð°
- OSS: github.com/bokuwalily ð
- ææ°æ å ±ã»ãåãåãã㯠X @bokuwalily ãžð
çããã® â€ïž ãã·ã§ã¢ãå±ã¿ã«ãªããŸãïŒ