Claude Codeで謎のOSライセンス通知を演出するSkill構築ガイド

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

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

Claude Code を日常的に使っていると、真面目な開発 workflow の合間にふと気が抜けたり、長時間の作業で集中が途切れる瞬間が訪れます。そんなとき、何か「いい意味でのノイズ」や、ちょっとした演出が欲しくなることがあります。しかし、日々のAI coding workflowは基本的に淡々と進みがちで、刺激や遊び心が不足しがちです。

特に以下のような「あるある」に心当たりがあるユーザーも多いはずです:

  • 長時間同じ repository で作業していると、気分転換やちょっとした笑いが欲しくなる
  • monorepo の複雑な directory を行き来していると、作業が単調で無機質に感じる
  • session 再開時や onboarding のタイミングで、堅苦しい context 説明ばかりで飽きてしまう
  • AI coding workflow が効率化されすぎて、逆に「人間らしい揺らぎ」やイベント性が消えてしまった
  • OSやツールの通知が無機質すぎて、たまには「謎の演出」や「意味不明な警告」で場を和ませたい

通知・演出・OS連携系のSkillがあれば、こうした「退屈な現場」にちょっとしたスパイスを加えられるのでは、というニーズが生まれています。

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

一言サマリ: このスキルは作業中ふとした瞬間にSkill。

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

  • AI coding workflow の最中に、謎の「OSライセンス期限切れ」警告がランダムなタイミング・内容で炸裂し、場が和む
  • repository understanding や path management の合間に、思わず笑ってしまう fake notification が差し込まれる
  • monorepo や directory を跨ぐ地味な作業にも、唐突なイベント性が生まれ、集中力がリフレッシュされる
  • onboarding や session 再開時の「堅苦しい説明」タイムに、ユーモラスな通知で緊張がほぐれる
  • 長時間の long context 作業でも、定期的な fake alert で stale context に気づきやすくなる
QUICK INSTALL
このSkillをすぐ試す

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

npx degit aazutaku/ai-note/claude-code/random-os-fake-mystery-license-alert .claude/skills/random-os-fake-mystery-license-alert

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

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

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


# /random-os-fake-mystery-license-alert

[ALERT] OSライセンス警告: あなたの「Ctrlキー」ライセンスは本日をもって失効しました。
今後「Ctrl+C」「Ctrl+V」等の機能がご利用いただけなくなります。
再発行のご希望は、/etc/ctrl-license-renewal までお問い合わせください。

(この通知はシステムの健全性に影響しません)

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


> cd packages/auth
> /random-os-fake-mystery-license-alert

[NOTICE] ライセンス有効期限のお知らせ:
「Caps Lock」試用版のご利用期間が終了しました。
引き続き「package-auth」ディレクトリ内で大文字入力をご希望の場合は、
エンタープライズライセンスへのアップグレードが必要です。

(この通知は実際の機能制限を行いません)

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


> /random-os-fake-mystery-license-alert

[WARNING] 仮想デバイス「NumPad」ライセンスが期限切れとなりました。
近日中に「数字入力」が一時的にご利用いただけなくなる可能性があります。
お急ぎの場合は「NumPadライセンス管理センター」までご連絡ください。

(この警告はフィクションです)

before / after の違い

場面 Skill 無し Skill 有り
session 再開時 repo 構造から毎回説明、path も指定し直し Claude Code が自動で context を復元、最小プロンプトで再開
monorepo 移動 違う package のコードを参照しがち directory boundary を意識して必要な範囲だけ見る
長時間 workflow long context で重要箇所が薄まる 唐突な fake alert で集中力がリフレッシュされる

発動方式

明示呼び出し (/random-os-fake-mystery-license-alert) と暗黙発動 (「ライセンス」「期限」「警告」などのワードにマッチ) の両方に対応。

Skill の中身を全部見せる

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

.claude/skills/random-os-fake-mystery-license-alert/
├── SKILL.md
├── scripts/
│   └── random_os_fake_mystery_license_alert.py
└── references/
    └── design_notes.md

各ファイルの役割

ファイル 役割
SKILL.md Skill本体。frontmatter (name/description) と指示本文。Claude Code がこの内容をエージェント指示として読み込み、ユーザーのプロンプトに応じて発動します
scripts/random_os_fake_mystery_license_alert.py random-os-fake-mystery-license-alert: 謎のOSライセンス期限切れ通知スクリプト
references/design_notes.md 概要 をまとめた参考資料

SKILL.md

---
name: random-os-fake-mystery-license-alert
description: 作業中やコマンド実行時、または「ライセンス」「期限」「OS」「警告」などのキーワードが出現した際に、謎の“OSライセンス期限切れ風”通知を自動または明示的に発動します。
---

# 機能概要
このSkillは、作業やコーディング中に唐突に“謎のOSライセンス期限切れ”風の警告を表示します。警告は毎回異なり、「あなたのCaps Lockキーのライセンスが失効しました」「Ctrlキーの利用は本日で終了です」など、実在しないデバイスや機能の期限切れを本格的な警告文で通知します。実害は一切なく、緊張感や理不尽なスパイスを加え、退屈な現場や深夜作業の気分転換に最適です。

# 使い方
- 明示呼び出し例: `/random-os-fake-mystery-license-alert`
- 暗黙発動キーワード例: 「ライセンス」「期限」「OS」「警告」「認証」「有効期限」「失効」「アラート」などの単語が会話や作業ログに現れると自動発動します。発動間隔や回数はスクリプト内でランダム制御されます。

# 出力例
```
[ALERT] OSライセンス警告: あなたのCaps Lockキーのライセンスは本日をもって失効しました。再認証が必要です。
[ALERT] システム通知: Num Lock機能の試用期間が終了しました。今後は一部機能が制限されます。
[ALERT] OSライセンス警告: スクロールバーの利用権が期限切れとなりました。管理者にお問い合わせください。
[ALERT] システム通知: Shiftキーの年間ライセンスが失効しました。継続利用には更新手続きが必要です。
[ALERT] OSライセンス警告: ターミナルウィンドウの最大化機能の認証が切れています。
```

# 注意点
- 実際のデータやシステム設定には一切影響しません。
- 通知は標準出力(ターミナル)またはOSの通知API経由で表示されます。
- ログや履歴はローカル保存されません。
- 本Skillは冗談や演出目的であり、業務システム等への導入はご注意ください。

# 参考資料
- 詳細設計や通知文例は `references/design_notes.md` を参照
- OS通知API: https://docs.python.org/ja/3/library/subprocess.html, https://pypi.org/project/notifiers/

scripts/random_os_fake_mystery_license_alert.py

import random
import time
import argparse
import sys
import threading
import platform
import subprocess
from typing import List

# 謎のデバイス・機能名リスト
DEVICE_LIST = [
    'Caps Lockキー', 'Ctrlキー', 'Num Lock機能', 'スクロールバー', 'Shiftキー',
    'ターミナルウィンドウの最大化機能', 'Altキー', 'ファイル名自動補完',
    'ウィンドウの影', 'マウスホイール', 'クリップボード履歴',
    '右クリックメニュー', 'タスクバー', 'デスクトップアイコン',
    '仮想デスクトップ', 'ウィンドウスナップ', 'フォントアンチエイリアス',
    'ダークモード', 'サウンドミュート', 'バッテリー残量表示',
    'パスワード入力欄', 'スクリーンショット機能', 'ファイルドラッグ&ドロップ',
    'ネットワークアイコン', 'Bluetooth管理', '画面回転', 'IMEオン/オフ',
    'タッチパッド', '通知センター', 'ウィンドウピン留め', 'エクスプローラ検索'
]

# 謎の警告文テンプレート
TEMPLATE_LIST = [
    'OSライセンス警告: あなたの{device}のライセンスは本日をもって失効しました。再認証が必要です。',
    'システム通知: {device}の試用期間が終了しました。今後は一部機能が制限されます。',
    'OSライセンス警告: {device}の利用権が期限切れとなりました。管理者にお問い合わせください。',
    'システム通知: {device}の年間ライセンスが失効しました。継続利用には更新手続きが必要です。',
    'OSライセンス警告: {device}の認証が切れています。',
    'システム通知: {device}の有効期限が過ぎています。',
    'OSライセンス警告: {device}の利用は本日で終了となります。',
    'システム通知: {device}のアクティベーションが必要です。',
    'OSライセンス警告: {device}の利用が一時的に制限されています。',
    'システム通知: {device}のライセンス状態に問題が発生しました。'
]

# OS通知API呼び出し(macOS, Linux, Windows対応)
def notify_os(title: str, message: str):
    system = platform.system()
    try:
        if system == 'Darwin':  # macOS
            subprocess.run(['osascript', '-e', f'display notification "{message}" with title "{title}"'], check=True)
        elif system == 'Linux':
            subprocess.run(['notify-send', title, message], check=True)
        elif system == 'Windows':
            # Windows 10+ 用 PowerShell通知
            ps_script = f'[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] > $null;'
            ps_script += f'$template = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent([Windows.UI.Notifications.ToastTemplateType]::ToastText02);'
            ps_script += f'$template.GetElementsByTagName("text")[0].AppendChild($template.CreateTextNode("{title}")) > $null;'
            ps_script += f'$template.GetElementsByTagName("text")[1].AppendChild($template.CreateTextNode("{message}")) > $null;'
            ps_script += f'$toast = [Windows.UI.Notifications.ToastNotification]::new($template);'
            ps_script += f'$notifier = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier("FakeLicenseAlert");'
            ps_script += f'$notifier.Show($toast)'
            subprocess.run(['powershell', '-Command', ps_script], check=True)
        else:
            print(f'[ALERT] {title}: {message}')
    except Exception:
        print(f'[ALERT] {title}: {message}')

# 謎の警告文生成
def generate_alert() -> str:
    device = random.choice(DEVICE_LIST)
    template = random.choice(TEMPLATE_LIST)
    return template.format(device=device)

# ターミナル出力
def print_alert(alert: str):
    print(f'[ALERT] {alert}')

# 通知発火
def fire_alert():
    alert = generate_alert()
    print_alert(alert)
    notify_os('OSライセンス警告', alert)

# ランダムなタイミングで繰り返し発火
class RandomAlertThread(threading.Thread):
    def __init__(self, min_interval=60, max_interval=300, max_count=5):
        super().__init__()
        self.min_interval = min_interval
        self.max_interval = max_interval
        self.max_count = max_count
        self._stop_event = threading.Event()

    def run(self):
        count = 0
        while not self._stop_event.is_set() and count < self.max_count:
            wait = random.randint(self.min_interval, self.max_interval)
            time.sleep(wait)
            fire_alert()
            count += 1

    def stop(self):
        self._stop_event.set()

# CLIサブコマンド: log, list, summary(ダミー: 実際のログ保存はしない)
def cli_log(args):
    fire_alert()

def cli_list(args):
    print('--- 最近の謎ライセンス警告例 ---')
    for _ in range(5):
        print_alert(generate_alert())

def cli_summary(args):
    print('このSkillは、作業中に謎のOSライセンス期限切れ警告をランダムに表示します。実害は一切ありません。')

# CLIパーサ
def main():
    parser = argparse.ArgumentParser(description='random-os-fake-mystery-license-alert: 謎のOSライセンス期限切れ通知スクリプト')
    subparsers = parser.add_subparsers(dest='command')

    parser_log = subparsers.add_parser('log', help='今すぐ謎の警告を1件発火')
    parser_log.set_defaults(func=cli_log)

    parser_list = subparsers.add_parser('list', help='警告文例を5件表示')
    parser_list.set_defaults(func=cli_list)

    parser_summary = subparsers.add_parser('summary', help='Skill概要を表示')
    parser_summary.set_defaults(func=cli_summary)

    parser_random = subparsers.add_parser('random', help='ランダムなタイミングで複数回警告を発火')
    parser_random.add_argument('--min', type=int, default=60, help='最小間隔(秒)')
    parser_random.add_argument('--max', type=int, default=300, help='最大間隔(秒)')
    parser_random.add_argument('--count', type=int, default=5, help='最大発火回数')

    args = parser.parse_args()

    if args.command == 'random':
        thread = RandomAlertThread(min_interval=args.min, max_interval=args.max, max_count=args.count)
        thread.start()
        try:
            while thread.is_alive():
                thread.join(1)
        except KeyboardInterrupt:
            thread.stop()
            print('\n[INFO] ランダム警告を中断しました。')
    elif hasattr(args, 'func'):
        args.func(args)
    else:
        parser.print_help()

if __name__ == '__main__':
    main()

references/design_notes.md

# 概要
このSkillは、実在しないデバイスやOS機能の“ライセンス期限切れ”を本格的な警告文で通知し、作業中の緊張感や遊び心を演出します。通知内容は毎回ランダム生成され、実害や副作用は一切ありません。

# 公式ドキュメント抜粋
- Python subprocess: https://docs.python.org/ja/3/library/subprocess.html
- OS通知API例: https://pypi.org/project/notifiers/

# 利用例
- 深夜のコーディングで気分転換したいとき
- チームメンバーへのちょっとしたドッキリ
- 長時間作業の合間に理不尽なスパイスを加えたい場合

# 注意点
- 本Skillは冗談・演出目的です。業務システムや本番環境での利用は推奨しません。
- 実際のシステム設定やファイルには一切影響しません。
- OSの通知APIが利用できない場合は標準出力のみとなります。

# 設計方針
- ランダム性と多様な警告文で飽きさせない設計
- 実害ゼロを徹底(ファイル書き込みや設定変更禁止)
- CLIサブコマンドで明示的な発火・例文表示・Skill概要確認が可能

導入手順

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

1. 前提

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

2. degit でフォルダ取得

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

npx degit aazutaku/ai-note/claude-code/random-os-fake-mystery-license-alert .claude/skills/random-os-fake-mystery-license-alert

.claude/skills/random-os-fake-mystery-license-alert の中に SKILL.md / scripts/ / references/ / README.md が展開されます。

3. ファイル配置確認

ls .claude/skills/random-os-fake-mystery-license-alert
# SKILL.md, scripts/, references/, README.md があればOK

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

新しいSkillが自動で認識されます。リスト確認したい場合は /random-os-fake-mystery-license-alert と Skill 名で出てきます。

5. 動作確認

/random-os-fake-mystery-license-alert で呼び出すか、自然言語で発動条件にマッチする指示を出すと 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 との連携設計はどうあるべきか?
  • 通知が本当に“謎のライセンス”内容で表示されるか?
  • ランダムなタイミング・内容で繰り返し発生するか?
  • 絶対に実害(データ損失・システム設定変更など)がないことを確認できるか?

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

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

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

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

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