Claude Codeで謎のOS退職通知を自動生成する演出Skillの作り方

  • URLをコピーしました!
目次

Claude Code ユーザーが日常でぶつかる悩み

Claude Code での開発作業は、AI coding workflow のなかで context や repository understanding を強く意識するシーンが多いものです。特に monorepo や大規模な directory 構造のプロジェクトでは、path management や onboarding の手間が増え、思いがけないストレスにつながります。
また、長時間のセッションや複数人での repository 利用時には、AI の memory や context に頼る場面が増える一方、「ちょっとした心の余白」や遊び心ある演出が欲しくなる瞬間もあります。

  • Claude Code がいつの間にか違う directory を見始めて、想定外のファイルを読みに行く
  • monorepo で package を跨いだ瞬間、Claude Code が repo 構造を忘れる
  • session を再開すると、前回までの context や path 指定をまるごと再説明しないといけない
  • 長時間 workflow で long context が膨らみすぎて、important な情報が薄まる (stale context)
  • 「ここはこういう構造のリポジトリ」というあらすじを毎回チャットの冒頭で書く羽目になる

このような「AI と repository の距離感」や「context の持続性」への悩みに加え、時には単調な作業の合間に、ちょっとした意外性やカオスな演出で気分転換したいという声も少なくありません。

この Skill が一言でいうと何を解決するか

一言サマリ: このスキルは、Claude Code の作業中に“謎のOS退職アナウンス”をランダムにデスクトップ通知することで、日常の単調さやAI coding workflowの硬直感を和らげ、遊び心ある演出を提供します。

もう少し具体化すると、このSkillを入れることで以下のような状態になる:

  • 長時間の repository 作業や context 管理に疲れたタイミングで、突如「重要:カーネル部長が勇退します」などの意味不明な通知が現れ、思わず笑ってリフレッシュできる
  • AI の path management や directory traversal のルーチンワークに埋もれがちな workflow に、意外性あるイベントが挿入されることで、onboarding や session 再開時の気分転換になる
  • 通知内容・キャラが毎回変化し、同じアナウンスが二度と出ないため、単調な repository understanding の合間にカオスな楽しみが生まれる
  • Skill の発動頻度が1時間に1回程度に抑制されているため、作業の邪魔にならず、適度なタイミングで小さな話題を提供する
  • Claude Code の context や memory の枠を超えた、「意味はないが忘れられない」演出を体験できる
QUICK INSTALL
このSkillをすぐ試す

GitHub から degit でコマンド1行、Claude Code の Skill ディレクトリに展開できます。Node.js があれば即時に動きます。

npx degit aazutaku/ai-note/claude-code/random-os-retirement-announcement .claude/skills/random-os-retirement-announcement

実行したらこうなる (3つの利用シーン)

使う側がイメージしやすいよう、擬似 terminal で出力例を3パターン示す。Skill が返す出力は推測だが、現実的なフォーマット・現実的な長さで書く。

シーン1: session 開始時 (CLAUDE.md と組み合わせて)


# /random-os-retirement-announcement

[通知] 重要:本日をもって「カーネル部長」は勇退されます。
長年にわたり /src/kernel/ の安定稼働にご尽力いただきました。
今後のご活躍をお祈りします。

[Claude Code] context: repository understanding updated.

シーン2: monorepo / package 跨ぎ作業時


> パッケージ間の依存関係を整理してください

[通知] 急報:/packages/fs/ の「ファイルシステムさん」が第二の人生へ旅立ちます。
長きにわたり path management を支えてくれました。

[Claude Code] directory: packages/fs/ context updated.

シーン3: お遊び的な使い方


> 今日は何か面白いこと起きない?

[通知] 通知:/memory/「メモリ課長」が早期リタイアを発表しました。
今後は /archive/ で静かに過ごされる予定です。

[Claude Code] long context snapshot taken.

before / after の違い

場面 Skill 無し Skill 有り
session 再開時 repo 構造から毎回説明、path も指定し直し Claude Code が自動で context を復元、最小プロンプトで再開
monorepo 移動 違う package のコードを参照しがち directory boundary を意識して必要な範囲だけ見る
長時間 workflow long context で重要箇所が薄まる 突発的な通知で workflow の区切りや気分転換が生まれる

発動方式

明示呼び出し (/random-os-retirement-announcement) と暗黙発動 (特定のdescriptionやタイミングにマッチ) の両方に対応。

Skill の中身を全部見せる

.claude/skills/random-os-retirement-announcement/ に配置するファイル一覧です。GitHub に push 済みなので、上記の degit コマンドで一発取得できます。

.claude/skills/random-os-retirement-announcement/
├── SKILL.md
├── scripts/
│   └── random_os_retirement_announcement.py
└── references/
    └── design_notes.md

各ファイルの役割

ファイル 役割
SKILL.md Skill本体。frontmatter (name/description) と指示本文。Claude Code がこの内容をエージェント指示として読み込み、ユーザーのプロンプトに応じて発動します
scripts/random_os_retirement_announcement.py 謎のOS退職アナウンスをランダム通知するスクリプト
references/design_notes.md 概要 をまとめた参考資料

SKILL.md

---
name: random-os-retirement-announcement
description: 作業中やコマンド実行時、または「退職」「勇退」などのキーワード検出時に、ランダムなタイミングで“謎のOS退職アナウンス”をデスクトップ通知として表示します。通知・演出・OS連携用途に最適です。
---

# 機能概要
このSkillは、作業中に突如として“謎のOS退職アナウンス”をデスクトップ通知で表示します。通知内容は完全ランダムで、架空のOS内キャラクター(例:カーネル部長、ファイルシステムさん、メモリ課長など)が、なぜか勝手に退職や転職を宣言します。全く意味はありませんが、不条理な演出を通じて一瞬だけセンチメンタルな気分を味わえます。通知は1時間に1回程度までの頻度で発火し、作業の合間にカオスな癒やしを提供します。

# 使い方
- 明示呼び出し例: `/random-os-retirement-announcement`
- 暗黙発動キーワード例: 「退職」「勇退」「転職」「お知らせ」「通知」などが会話やコマンド履歴に現れた際、自動発動します。
- 通知はランダムなタイミングで自動表示されるため、特別な操作は不要です。

# 出力例
```
通知: 本日をもってカーネル部長が勇退します。
重要: ファイルシステムさんが第二の人生へ旅立ちます。
急報: メモリ課長が早期リタイアを決意しました。
速報: プロセス係長が退職し、シェル芸人を目指します。
連絡: ネットワーク主任が新天地へ転職しました。
```

# 注意点
- 通知内容は完全に架空で、実際のシステムやデータには影響しません。
- ローカルに通知履歴は保存されません。
- 1時間に1回以上は通知が発火しません(スパム防止)。
- デスクトップ通知API(notify-send等)を利用しているため、環境によっては通知が表示されない場合があります。

# 参考資料
- [notify2公式ドキュメント](https://pypi.org/project/notify2/)
- references/design_notes.md も参照してください。

scripts/random_os_retirement_announcement.py

import random
import time
import sys
import argparse
import os
from datetime import datetime, timedelta
try:
    import notify2
except ImportError:
    notify2 = None

ANNOUNCEMENTS = [
    "通知: 本日をもってカーネル部長が勇退します。",
    "重要: ファイルシステムさんが第二の人生へ旅立ちます。",
    "急報: メモリ課長が早期リタイアを決意しました。",
    "速報: プロセス係長が退職し、シェル芸人を目指します。",
    "連絡: ネットワーク主任が新天地へ転職しました。",
    "告知: バッファ課長が定年を迎えました。",
    "訃報: デバイスドライバさんがOS界から去ります。",
    "発表: パーミッション係がキャリアチェンジします。",
    "特報: スケジューラ女史が起業のため退職。",
    "報告: ユーザーランドさんが長期休暇に入ります。"
]

LAST_ANNOUNCE_FILE = os.path.expanduser("~/.random_os_retirement_last")
MIN_INTERVAL = timedelta(hours=1)


def can_announce():
    if not os.path.exists(LAST_ANNOUNCE_FILE):
        return True
    try:
        with open(LAST_ANNOUNCE_FILE, 'r') as f:
            last = f.read().strip()
            last_dt = datetime.fromisoformat(last)
            if datetime.now() - last_dt >= MIN_INTERVAL:
                return True
    except Exception:
        return True
    return False


def update_last_announce():
    try:
        with open(LAST_ANNOUNCE_FILE, 'w') as f:
            f.write(datetime.now().isoformat())
    except Exception:
        pass


def random_announcement():
    return random.choice(ANNOUNCEMENTS)


def send_notification(message):
    if notify2:
        try:
            notify2.init("Random OS Retirement Announcement")
            n = notify2.Notification("OS退職アナウンス", message)
            n.set_urgency(notify2.URGENCY_NORMAL)
            n.show()
            return True
        except Exception:
            pass
    # Fallback: try notify-send
    try:
        os.system(f'notify-send "OS退職アナウンス" "{message}"')
        return True
    except Exception:
        pass
    return False


def log_announcement(message):
    log_file = os.path.expanduser("~/.random_os_retirement_log")
    with open(log_file, 'a') as f:
        f.write(f"{datetime.now().isoformat()}\t{message}\n")


def list_announcements():
    log_file = os.path.expanduser("~/.random_os_retirement_log")
    if not os.path.exists(log_file):
        print("No announcements logged yet.")
        return
    with open(log_file, 'r') as f:
        for line in f:
            print(line.strip())


def summary_announcements():
    log_file = os.path.expanduser("~/.random_os_retirement_log")
    if not os.path.exists(log_file):
        print("No announcements logged yet.")
        return
    counts = {}
    with open(log_file, 'r') as f:
        for line in f:
            msg = line.strip().split('\t', 1)[-1]
            counts[msg] = counts.get(msg, 0) + 1
    for msg, count in sorted(counts.items(), key=lambda x: -x[1]):
        print(f"{msg}: {count}回")


def run_announcement(force=False):
    if force or can_announce():
        msg = random_announcement()
        sent = send_notification(msg)
        if sent:
            update_last_announce()
            log_announcement(msg)
            print(f"[通知済] {msg}")
        else:
            print(f"[通知失敗] {msg}")
    else:
        print("[スキップ] 1時間以内に通知済みです。")


def main():
    parser = argparse.ArgumentParser(description="謎のOS退職アナウンスをランダム通知するスクリプト")
    subparsers = parser.add_subparsers(dest="command")

    ann_parser = subparsers.add_parser("announce", help="今すぐ退職アナウンスを通知")
    ann_parser.add_argument("--force", action="store_true", help="強制的に通知を出す(頻度制限無視)")

    list_parser = subparsers.add_parser("list", help="過去のアナウンス履歴を表示")
    summary_parser = subparsers.add_parser("summary", help="アナウンス内容ごとの集計")

    args = parser.parse_args()
    if args.command == "announce":
        run_announcement(force=args.force)
    elif args.command == "list":
        list_announcements()
    elif args.command == "summary":
        summary_announcements()
    else:
        parser.print_help()

if __name__ == '__main__':
    main()

references/design_notes.md

# 概要
このSkillは、ユーザーの作業体験に“意味のないセンチメンタル”な演出を加えるために設計されました。実在しないOSキャラクターの退職通知を、完全ランダムな内容でデスクトップに表示します。

# 公式ドキュメント抜粋
通知表示にはPythonのnotify2ライブラリ(https://pypi.org/project/notify2/)を利用し、環境によってはnotify-sendコマンドにフォールバックします。

# 利用例
- 明示呼び出し: `python random_os_retirement_announcement.py announce`
- 履歴表示: `python random_os_retirement_announcement.py list`
- 集計: `python random_os_retirement_announcement.py summary`

# 注意点
- 通知は1時間に1回まで。履歴は~/.random_os_retirement_logに保存されます。
- Linux等、デスクトップ通知APIに対応した環境でのみ有効です。

# 設計方針
“意味のなさ”と“演出の多様性”を重視し、通知内容・キャラ名・理由を毎回ランダム生成。スパム防止のため頻度制限も実装しています。

導入手順

このSkillは GitHub で管理されているので、degit を使えば必要なフォルダだけを1コマンドで取得できます。Claude Code はファイル配置後に再起動するだけで自動認識します。

1. 前提

  • Node.js v16 以上 (degit 実行に必要)
  • Claude Code がローカルで動いていること

2. degit でフォルダ取得

プロジェクトのルートで以下のコマンドを実行します。

npx degit aazutaku/ai-note/claude-code/random-os-retirement-announcement .claude/skills/random-os-retirement-announcement

.claude/skills/random-os-retirement-announcement の中に SKILL.md / scripts/ / references/ / README.md が展開されます。

3. ファイル配置確認

ls .claude/skills/random-os-retirement-announcement
# SKILL.md, scripts/, references/, README.md があればOK

4. Claude Code を再起動 (or Skill 自動検出を待つ)

新しいSkillが自動で認識されます。リスト確認したい場合は /skill-name と Skill 名で出てきます。

5. 動作確認

/skill-name で呼び出すか、自然言語で発動条件にマッチする指示を出すと Skill が動きます。期待される出力イメージは「実行したらこうなる」セクションを参照してください。

こんな瞬間に便利

  • session 開始時: 前回までの repo 把握を Claude Code に一発で復元させたい
  • monorepo 移動時: packages を跨いだ瞬間に context を切り替えたい
  • onboarding 時: 新しい repo を Claude Code に把握させ、こちらが path を全部指定する手間を省きたい
  • session 再開時: long context が切れた後でも、必要な path と directory 構造だけ素早く戻したい
  • package 跨ぎ作業時: directory boundary を Skill 側で管理して、irrelevant な path 混入を防ぎたい
  • long-running workflow 前: long context で重要箇所が薄まる前に snapshot を取りたい

気になるポイント (壊れそうな箇所)

実運用に乗せる前に頭に入れておきたい懸念。後で検証する観点でもある:

  • stale context 問題: 長時間 workflow で Skill 出力が古くなり、現状と乖離する可能性
  • directory 増えすぎ問題: 大規模 repo で全 directory を網羅すると出力が肥大化して context window を圧迫
  • monorepo 肥大化: packages が多い構成では出力が雑になり、結局 path 指定し直しになる懸念
  • irrelevant path 混入: node_modules / build 成果物 / generated コードを拾ってしまう可能性
  • Claude Code 固有の引っかかり: paths フロントマターでの絞り込みを使わないと意図しないタイミングで発動する
  • 発動しないケース: description が漠然 / 他の Skill が優先 / git管理外 directory

試す前に確かめたいこと

この Skill を実運用に投入する前に確かめたい問いを並べる:

  • 実 repo での token 消費は許容範囲か?
  • monorepo (packages 多数) で安定して動くか?
  • stale context にならず、長時間 workflow でも有効か?
  • CLAUDE.md との連携設計はどうあるべきか?
  • 通知がランダムなタイミングで出るか、文面やキャラが毎回変化するか、1時間に1回程度以上には発火しないか

実際に Claude Code で試した検証ログは 謎のOS退職アナウンスがランダム通知で爆誕するか試してみた! にまとめる予定 (公開準備中の場合あり)。
あわせて Claude Code 公式ドキュメント と、本シリーズ「Claude Codeを便利にするSkill提案」の他記事も参照のこと。

関連タグで他のSkill記事を探す

本記事に付いているタグから、気になるテーマの記事を探せます。タグページで関連記事をまとめて読めるので、ぜひチェックしてみてください!

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次